Blaze  3.6
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>
57 #include <blaze/math/Exception.h>
78 #include <blaze/math/views/Check.h>
83 #include <blaze/util/Assert.h>
86 #include <blaze/util/MaybeUnused.h>
87 #include <blaze/util/mpl/If.h>
88 #include <blaze/util/TypeList.h>
89 #include <blaze/util/Types.h>
92 
93 
94 namespace blaze {
95 
96 //=================================================================================================
97 //
98 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR SPARSE MATRICES
99 //
100 //=================================================================================================
101 
102 //*************************************************************************************************
110 template< typename MT // Type of the sparse matrix
111  , bool SF // Symmetry flag
112  , typename... CCAs > // Compile time column arguments
113 class Columns<MT,true,false,SF,CCAs...>
114  : public View< SparseMatrix< Columns<MT,true,false,SF,CCAs...>, true > >
115  , private ColumnsData<CCAs...>
116 {
117  private:
118  //**Type definitions****************************************************************************
119  using DataType = ColumnsData<CCAs...>;
120  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
121  //**********************************************************************************************
122 
123  //**Compile time flags**************************************************************************
124  static constexpr size_t N = sizeof...( CCAs );
125  //**********************************************************************************************
126 
127  public:
128  //**Type definitions****************************************************************************
130  using This = Columns<MT,true,false,SF,CCAs...>;
131 
132  using BaseType = SparseMatrix<This,true>;
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_;
309 
310  //**********************************************************************************************
311 
312  //**Compile time checks*************************************************************************
321  //**********************************************************************************************
322 };
324 //*************************************************************************************************
325 
326 
327 
328 
329 //=================================================================================================
330 //
331 // CONSTRUCTORS
332 //
333 //=================================================================================================
334 
335 //*************************************************************************************************
348 template< typename MT // Type of the sparse matrix
349  , bool SF // Symmetry flag
350  , typename... CCAs > // Compile time column arguments
351 template< typename... RCAs > // Runtime column arguments
352 inline 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( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
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 //*************************************************************************************************
387 template< typename MT // Type of the sparse matrix
388  , bool SF // Symmetry flag
389  , typename... CCAs > // Compile time column arguments
390 inline 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 //*************************************************************************************************
413 template< typename MT // Type of the sparse matrix
414  , bool SF // Symmetry flag
415  , typename... CCAs > // Compile time column arguments
416 inline 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 //*************************************************************************************************
440 template< typename MT // Type of the sparse matrix
441  , bool SF // Symmetry flag
442  , typename... CCAs > // Compile time column arguments
443 inline 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 //*************************************************************************************************
470 template< typename MT // Type of the sparse matrix
471  , bool SF // Symmetry flag
472  , typename... CCAs > // Compile time column arguments
473 inline 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 //*************************************************************************************************
497 template< typename MT // Type of the sparse matrix
498  , bool SF // Symmetry flag
499  , typename... CCAs > // Compile time column arguments
500 inline 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 //*************************************************************************************************
520 template< typename MT // Type of the sparse matrix
521  , bool SF // Symmetry flag
522  , typename... CCAs > // Compile time column arguments
523 inline 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 //*************************************************************************************************
543 template< typename MT // Type of the sparse matrix
544  , bool SF // Symmetry flag
545  , typename... CCAs > // Compile time column arguments
546 inline 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 //*************************************************************************************************
566 template< typename MT // Type of the sparse matrix
567  , bool SF // Symmetry flag
568  , typename... CCAs > // Compile time column arguments
569 inline 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 //*************************************************************************************************
589 template< typename MT // Type of the sparse matrix
590  , bool SF // Symmetry flag
591  , typename... CCAs > // Compile time column arguments
592 inline 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 //*************************************************************************************************
612 template< typename MT // Type of the sparse matrix
613  , bool SF // Symmetry flag
614  , typename... CCAs > // Compile time column arguments
615 inline 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 //*************************************************************************************************
650 template< typename MT // Type of the sparse matrix
651  , bool SF // Symmetry flag
652  , typename... CCAs > // Compile time column arguments
653 inline 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 //*************************************************************************************************
699 template< typename MT // Type of the sparse matrix
700  , bool SF // Symmetry flag
701  , typename... CCAs > // Compile time column arguments
702 inline 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( &matrix_ ) ) {
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 //*************************************************************************************************
761 template< typename MT // Type of the sparse matrix
762  , bool SF // Symmetry flag
763  , typename... CCAs > // Compile time column arguments
764 template< typename MT2 // Type of the right-hand side matrix
765  , bool SO > // Storage order of the right-hand side matrix
766 inline 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( &matrix_ ) ) {
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 //*************************************************************************************************
823 template< typename MT // Type of the sparse matrix
824  , bool SF // Symmetry flag
825  , typename... CCAs > // Compile time column arguments
826 template< typename MT2 // Type of the right-hand side matrix
827  , bool SO > // Storage order of the right-hand side matrix
828 inline 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 //*************************************************************************************************
883 template< typename MT // Type of the sparse matrix
884  , bool SF // Symmetry flag
885  , typename... CCAs > // Compile time column arguments
886 template< typename MT2 // Type of the right-hand side matrix
887  , bool SO > // Storage order of the right-hand side matrix
888 inline 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 //*************************************************************************************************
943 template< typename MT // Type of the sparse matrix
944  , bool SF // Symmetry flag
945  , typename... CCAs > // Compile time column arguments
946 template< typename MT2 // Type of the right-hand side matrix
947  , bool SO > // Storage order of the right-hand side matrix
948 inline 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 //*************************************************************************************************
1003 template< typename MT // Type of the sparse matrix
1004  , bool SF // Symmetry flag
1005  , typename... CCAs > // Compile time column arguments
1006 inline MT& Columns<MT,true,false,SF,CCAs...>::operand() noexcept
1007 {
1008  return matrix_;
1009 }
1011 //*************************************************************************************************
1012 
1013 
1014 //*************************************************************************************************
1020 template< typename MT // Type of the sparse matrix
1021  , bool SF // Symmetry flag
1022  , typename... CCAs > // Compile time column arguments
1023 inline const MT& Columns<MT,true,false,SF,CCAs...>::operand() const noexcept
1024 {
1025  return matrix_;
1026 }
1028 //*************************************************************************************************
1029 
1030 
1031 //*************************************************************************************************
1037 template< typename MT // Type of the sparse matrix
1038  , bool SF // Symmetry flag
1039  , typename... CCAs > // Compile time column arguments
1040 inline size_t Columns<MT,true,false,SF,CCAs...>::rows() const noexcept
1041 {
1042  return matrix_.rows();
1043 }
1045 //*************************************************************************************************
1046 
1047 
1048 //*************************************************************************************************
1054 template< typename MT // Type of the sparse matrix
1055  , bool SF // Symmetry flag
1056  , typename... CCAs > // Compile time column arguments
1057 inline size_t Columns<MT,true,false,SF,CCAs...>::capacity() const noexcept
1058 {
1059  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1060 }
1062 //*************************************************************************************************
1063 
1064 
1065 //*************************************************************************************************
1074 template< typename MT // Type of the sparse matrix
1075  , bool SF // Symmetry flag
1076  , typename... CCAs > // Compile time column arguments
1077 inline 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 //*************************************************************************************************
1093 template< typename MT // Type of the sparse matrix
1094  , bool SF // Symmetry flag
1095  , typename... CCAs > // Compile time column arguments
1096 inline size_t Columns<MT,true,false,SF,CCAs...>::nonZeros() const
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 //*************************************************************************************************
1118 template< typename MT // Type of the sparse matrix
1119  , bool SF // Symmetry flag
1120  , typename... CCAs > // Compile time column arguments
1121 inline 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 //*************************************************************************************************
1137 template< 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 //*************************************************************************************************
1160 template< typename MT // Type of the sparse matrix
1161  , bool SF // Symmetry flag
1162  , typename... CCAs > // Compile time column arguments
1163 inline void Columns<MT,true,false,SF,CCAs...>::reset( size_t j )
1164 {
1165  matrix_.reset( idx(j) );
1166 }
1168 //*************************************************************************************************
1169 
1170 
1171 //*************************************************************************************************
1182 template< typename MT // Type of the sparse matrix
1183  , bool SF // Symmetry flag
1184  , typename... CCAs > // Compile time column arguments
1185 inline 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 //*************************************************************************************************
1210 template< typename MT // Type of the sparse matrix
1211  , bool SF // Symmetry flag
1212  , typename... CCAs > // Compile time column arguments
1213 void 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 //*************************************************************************************************
1231 template< typename MT // Type of the sparse matrix
1232  , bool SF // Symmetry flag
1233  , typename... CCAs > // Compile time column arguments
1234 void 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 //*************************************************************************************************
1255 template< typename MT // Type of the sparse matrix
1256  , bool SF // Symmetry flag
1257  , typename... CCAs > // Compile time column arguments
1258 void 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 //*************************************************************************************************
1278 template< typename MT // Type of the sparse matrix
1279  , bool SF // Symmetry flag
1280  , typename... CCAs > // Compile time column arguments
1281 inline 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 //*************************************************************************************************
1319 template< typename MT // Type of the sparse matrix
1320  , bool SF // Symmetry flag
1321  , typename... CCAs > // Compile time column arguments
1322 inline 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 //*************************************************************************************************
1345 template< typename MT // Type of the sparse matrix
1346  , bool SF // Symmetry flag
1347  , typename... CCAs > // Compile time column arguments
1348 inline 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 //*************************************************************************************************
1401 template< typename MT // Type of the sparse matrix
1402  , bool SF // Symmetry flag
1403  , typename... CCAs > // Compile time column arguments
1404 inline 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 //*************************************************************************************************
1427 template< typename MT // Type of the sparse matrix
1428  , bool SF // Symmetry flag
1429  , typename... CCAs > // Compile time column arguments
1430 inline 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 //*************************************************************************************************
1458 template< typename MT // Type of the sparse matrix
1459  , bool SF // Symmetry flag
1460  , typename... CCAs > // Compile time column arguments
1461 inline 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 //*************************************************************************************************
1482 template< typename MT // Type of the sparse matrix
1483  , bool SF // Symmetry flag
1484  , typename... CCAs > // Compile time column arguments
1485 inline 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 //*************************************************************************************************
1507 template< typename MT // Type of the sparse matrix
1508  , bool SF // Symmetry flag
1509  , typename... CCAs > // Compile time column arguments
1510 inline 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 //*************************************************************************************************
1544 template< typename MT // Type of the sparse matrix
1545  , bool SF // Symmetry flag
1546  , typename... CCAs > // Compile time column arguments
1547 template< typename Pred > // Type of the unary predicate
1548 inline 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 //*************************************************************************************************
1585 template< typename MT // Type of the sparse matrix
1586  , bool SF // Symmetry flag
1587  , typename... CCAs > // Compile time column arguments
1588 template< typename Pred > // Type of the unary predicate
1589 inline 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 //*************************************************************************************************
1622 template< typename MT // Type of the sparse matrix
1623  , bool SF // Symmetry flag
1624  , typename... CCAs > // Compile time column arguments
1625 inline 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 //*************************************************************************************************
1649 template< typename MT // Type of the sparse matrix
1650  , bool SF // Symmetry flag
1651  , typename... CCAs > // Compile time column arguments
1652 inline 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 //*************************************************************************************************
1675 template< typename MT // Type of the sparse matrix
1676  , bool SF // Symmetry flag
1677  , typename... CCAs > // Compile time column arguments
1678 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1679  Columns<MT,true,false,SF,CCAs...>::lowerBound( size_t i, size_t j )
1680 {
1681  return matrix_.lowerBound( i, idx(j) );
1682 }
1684 //*************************************************************************************************
1685 
1686 
1687 //*************************************************************************************************
1701 template< typename MT // Type of the sparse matrix
1702  , bool SF // Symmetry flag
1703  , typename... CCAs > // Compile time column arguments
1704 inline 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 //*************************************************************************************************
1727 template< typename MT // Type of the sparse matrix
1728  , bool SF // Symmetry flag
1729  , typename... CCAs > // Compile time column arguments
1730 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1731  Columns<MT,true,false,SF,CCAs...>::upperBound( size_t i, size_t j )
1732 {
1733  return matrix_.upperBound( i, idx(j) );
1734 }
1736 //*************************************************************************************************
1737 
1738 
1739 //*************************************************************************************************
1753 template< typename MT // Type of the sparse matrix
1754  , bool SF // Symmetry flag
1755  , typename... CCAs > // Compile time column arguments
1756 inline 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 //*************************************************************************************************
1786 template< typename MT // Type of the sparse matrix
1787  , bool SF // Symmetry flag
1788  , typename... CCAs > // Compile time column arguments
1789 inline 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 //*************************************************************************************************
1830 template< typename MT // Type of the sparse matrix
1831  , bool SF // Symmetry flag
1832  , typename... CCAs > // Compile time column arguments
1833 inline Columns<MT,true,false,SF,CCAs...>&
1834  Columns<MT,true,false,SF,CCAs...>::ctranspose()
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 //*************************************************************************************************
1874 template< typename MT // Type of the sparse matrix
1875  , bool SF // Symmetry flag
1876  , typename... CCAs > // Compile time column arguments
1877 template< typename Other > // Data type of the scalar value
1878 inline 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 //*************************************************************************************************
1914 template< typename MT // Type of the sparse matrix
1915  , bool SF // Symmetry flag
1916  , typename... CCAs > // Compile time column arguments
1917 template< typename Other > // Data type of the foreign expression
1918 inline bool Columns<MT,true,false,SF,CCAs...>::canAlias( const Other* alias ) const noexcept
1919 {
1920  return matrix_.isAliased( alias );
1921 }
1923 //*************************************************************************************************
1924 
1925 
1926 //*************************************************************************************************
1937 template< typename MT // Type of the sparse matrix
1938  , bool SF // Symmetry flag
1939  , typename... CCAs > // Compile time column arguments
1940 template< typename Other > // Data type of the foreign expression
1941 inline bool Columns<MT,true,false,SF,CCAs...>::isAliased( const Other* alias ) const noexcept
1942 {
1943  return matrix_.isAliased( alias );
1944 }
1946 //*************************************************************************************************
1947 
1948 
1949 //*************************************************************************************************
1960 template< typename MT // Type of the sparse matrix
1961  , bool SF // Symmetry flag
1962  , typename... CCAs > // Compile time column arguments
1963 inline bool Columns<MT,true,false,SF,CCAs...>::canSMPAssign() const noexcept
1964 {
1965  return false;
1966 }
1968 //*************************************************************************************************
1969 
1970 
1971 //*************************************************************************************************
1983 template< typename MT // Type of the sparse matrix
1984  , bool SF // Symmetry flag
1985  , typename... CCAs > // Compile time column arguments
1986 template< typename MT2 // Type of the right-hand side dense matrix
1987  , bool SO > // Storage order of the right-hand side dense matrix
1988 inline 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 //*************************************************************************************************
2030 template< typename MT // Type of the sparse matrix
2031  , bool SF // Symmetry flag
2032  , typename... CCAs > // Compile time column arguments
2033 template< typename MT2 > // Type of the right-hand side sparse matrix
2034 inline 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 //*************************************************************************************************
2076 template< typename MT // Type of the sparse matrix
2077  , bool SF // Symmetry flag
2078  , typename... CCAs > // Compile time column arguments
2079 template< typename MT2 > // Type of the right-hand side sparse matrix
2080 inline 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 //*************************************************************************************************
2125 template< typename MT // Type of the sparse matrix
2126  , bool SF // Symmetry flag
2127  , typename... CCAs > // Compile time column arguments
2128 template< typename MT2 // Type of the right-hand side matrix
2129  , bool SO > // Storage order of the right-hand side matrix
2130 inline 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 //*************************************************************************************************
2162 template< typename MT // Type of the sparse matrix
2163  , bool SF // Symmetry flag
2164  , typename... CCAs > // Compile time column arguments
2165 template< typename MT2 // Type of the right-hand side matrix
2166  , bool SO > // Storage order of the right-hand side matrix
2167 inline 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 //*************************************************************************************************
2199 template< typename MT // Type of the sparse matrix
2200  , bool SF // Symmetry flag
2201  , typename... CCAs > // Compile time column arguments
2202 template< typename MT2 // Type of the right-hand side matrix
2203  , bool SO > // Storage order of the right-hand side matrix
2204 inline 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 //*************************************************************************************************
2245 template< typename MT // Type of the sparse matrix
2246  , typename... CCAs > // Compile time column arguments
2247 class 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  static constexpr size_t N = sizeof...( CCAs );
2259  //**********************************************************************************************
2260 
2261  public:
2262  //**Type definitions****************************************************************************
2264  using This = Columns<MT,false,false,false,CCAs...>;
2265 
2266  using BaseType = SparseMatrix<This,true>;
2267  using ViewedType = MT;
2268  using ResultType = ColumnsTrait_t<MT,N>;
2269  using OppositeType = OppositeType_t<ResultType>;
2270  using TransposeType = TransposeType_t<ResultType>;
2271  using ElementType = ElementType_t<MT>;
2272  using ReturnType = ReturnType_t<MT>;
2273  using CompositeType = const Columns&;
2274 
2276  using ConstReference = ConstReference_t<MT>;
2277 
2279  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
2280  //**********************************************************************************************
2281 
2282  //**ColumnsElement class definition*************************************************************
2285  template< typename MatrixType // Type of the sparse matrix
2286  , typename IteratorType > // Type of the sparse matrix iterator
2287  class ColumnsElement
2288  : private SparseElement
2289  {
2290  public:
2291  //**Constructor******************************************************************************
2297  inline ColumnsElement( IteratorType pos, size_t row )
2298  : pos_( pos ) // Iterator to the current position of the sparse column element
2299  , row_( row ) // Index of the according row
2300  {}
2301  //*******************************************************************************************
2302 
2303  //**Assignment operator**********************************************************************
2309  template< typename T > inline ColumnsElement& operator=( const T& v ) {
2310  *pos_ = v;
2311  return *this;
2312  }
2313  //*******************************************************************************************
2314 
2315  //**Addition assignment operator*************************************************************
2321  template< typename T > inline ColumnsElement& operator+=( const T& v ) {
2322  *pos_ += v;
2323  return *this;
2324  }
2325  //*******************************************************************************************
2326 
2327  //**Subtraction assignment operator**********************************************************
2333  template< typename T > inline ColumnsElement& operator-=( const T& v ) {
2334  *pos_ -= v;
2335  return *this;
2336  }
2337  //*******************************************************************************************
2338 
2339  //**Multiplication assignment operator*******************************************************
2345  template< typename T > inline ColumnsElement& operator*=( const T& v ) {
2346  *pos_ *= v;
2347  return *this;
2348  }
2349  //*******************************************************************************************
2350 
2351  //**Division assignment operator*************************************************************
2357  template< typename T > inline ColumnsElement& operator/=( const T& v ) {
2358  *pos_ /= v;
2359  return *this;
2360  }
2361  //*******************************************************************************************
2362 
2363  //**Element access operator******************************************************************
2368  inline const ColumnsElement* operator->() const {
2369  return this;
2370  }
2371  //*******************************************************************************************
2372 
2373  //**Value function***************************************************************************
2378  inline decltype(auto) value() const {
2379  return pos_->value();
2380  }
2381  //*******************************************************************************************
2382 
2383  //**Index function***************************************************************************
2388  inline size_t index() const {
2389  return row_;
2390  }
2391  //*******************************************************************************************
2392 
2393  private:
2394  //**Member variables*************************************************************************
2395  IteratorType pos_;
2396  size_t row_;
2397  //*******************************************************************************************
2398  };
2399  //**********************************************************************************************
2400 
2401  //**ColumnsIterator class definition************************************************************
2404  template< typename MatrixType // Type of the sparse matrix
2405  , typename IteratorType > // Type of the sparse matrix iterator
2406  class ColumnsIterator
2407  {
2408  public:
2409  //**Type definitions*************************************************************************
2410  using IteratorCategory = std::forward_iterator_tag;
2411  using ValueType = ColumnsElement<MatrixType,IteratorType>;
2412  using PointerType = ValueType;
2413  using ReferenceType = ValueType;
2414  using DifferenceType = ptrdiff_t;
2415 
2416  // STL iterator requirements
2417  using iterator_category = IteratorCategory;
2418  using value_type = ValueType;
2419  using pointer = PointerType;
2420  using reference = ReferenceType;
2421  using difference_type = DifferenceType;
2422  //*******************************************************************************************
2423 
2424  //**Constructor******************************************************************************
2427  inline ColumnsIterator()
2428  : matrix_( nullptr ) // The sparse matrix containing the selected column
2429  , row_ ( 0UL ) // The current row index
2430  , column_( 0UL ) // The current column index
2431  , pos_ () // Iterator to the current sparse element
2432  {}
2433  //*******************************************************************************************
2434 
2435  //**Constructor******************************************************************************
2442  inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column )
2443  : matrix_( &matrix ) // The sparse matrix containing the selected column
2444  , row_ ( row ) // The current row index
2445  , column_( column ) // The current column index
2446  , pos_ () // Iterator to the current sparse element
2447  {
2448  for( ; row_<matrix_->rows(); ++row_ ) {
2449  pos_ = matrix_->find( row_, column_ );
2450  if( pos_ != matrix_->end( row_ ) ) break;
2451  }
2452  }
2453  //*******************************************************************************************
2454 
2455  //**Constructor******************************************************************************
2463  inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column, IteratorType pos )
2464  : matrix_( &matrix ) // The sparse matrix containing the selected column
2465  , row_ ( row ) // The current row index
2466  , column_( column ) // The current column index
2467  , pos_ ( pos ) // Iterator to the current sparse element
2468  {
2469  BLAZE_INTERNAL_ASSERT( matrix.find( row, column ) == pos, "Invalid initial iterator position" );
2470  }
2471  //*******************************************************************************************
2472 
2473  //**Constructor******************************************************************************
2478  template< typename MatrixType2, typename IteratorType2 >
2479  inline ColumnsIterator( const ColumnsIterator<MatrixType2,IteratorType2>& it )
2480  : matrix_( it.matrix_ ) // The sparse matrix containing the selected column
2481  , row_ ( it.row_ ) // The current row index
2482  , column_( it.column_ ) // The current column index
2483  , pos_ ( it.pos_ ) // Iterator to the current sparse element
2484  {}
2485  //*******************************************************************************************
2486 
2487  //**Prefix increment operator****************************************************************
2492  inline ColumnsIterator& operator++() {
2493  ++row_;
2494  for( ; row_<matrix_->rows(); ++row_ ) {
2495  pos_ = matrix_->find( row_, column_ );
2496  if( pos_ != matrix_->end( row_ ) ) break;
2497  }
2498 
2499  return *this;
2500  }
2501  //*******************************************************************************************
2502 
2503  //**Postfix increment operator***************************************************************
2508  inline const ColumnsIterator operator++( int ) {
2509  const ColumnsIterator tmp( *this );
2510  ++(*this);
2511  return tmp;
2512  }
2513  //*******************************************************************************************
2514 
2515  //**Element access operator******************************************************************
2520  inline ReferenceType operator*() const {
2521  return ReferenceType( pos_, row_ );
2522  }
2523  //*******************************************************************************************
2524 
2525  //**Element access operator******************************************************************
2530  inline PointerType operator->() const {
2531  return PointerType( pos_, row_ );
2532  }
2533  //*******************************************************************************************
2534 
2535  //**Equality operator************************************************************************
2541  template< typename MatrixType2, typename IteratorType2 >
2542  inline bool operator==( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2543  return row_ == rhs.row_;
2544  }
2545  //*******************************************************************************************
2546 
2547  //**Inequality operator**********************************************************************
2553  template< typename MatrixType2, typename IteratorType2 >
2554  inline bool operator!=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2555  return !( *this == rhs );
2556  }
2557  //*******************************************************************************************
2558 
2559  //**Subtraction operator*********************************************************************
2565  inline DifferenceType operator-( const ColumnsIterator& rhs ) const {
2566  size_t counter( 0UL );
2567  for( size_t i=rhs.row_; i<row_; ++i ) {
2568  if( matrix_->find( i, column_ ) != matrix_->end( i ) )
2569  ++counter;
2570  }
2571  return counter;
2572  }
2573  //*******************************************************************************************
2574 
2575  private:
2576  //**Member variables*************************************************************************
2577  MatrixType* matrix_;
2578  size_t row_;
2579  size_t column_;
2580  IteratorType pos_;
2581  //*******************************************************************************************
2582 
2583  //**Friend declarations**********************************************************************
2584  template< typename MatrixType2, typename IteratorType2 > friend class ColumnsIterator;
2585  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
2586  //*******************************************************************************************
2587  };
2588  //**********************************************************************************************
2589 
2590  //**Type definitions****************************************************************************
2592  using ConstIterator = ColumnsIterator< const MT, ConstIterator_t<MT> >;
2593 
2595  using Iterator = If_t< IsConst_v<MT>, ConstIterator, ColumnsIterator< MT, Iterator_t<MT> > >;
2596  //**********************************************************************************************
2597 
2598  //**Compilation flags***************************************************************************
2600  static constexpr bool smpAssignable = MT::smpAssignable;
2601 
2603  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2604  //**********************************************************************************************
2605 
2606  //**Constructors********************************************************************************
2609  template< typename... RCAs >
2610  explicit inline Columns( MT& matrix, RCAs... args );
2611 
2612  Columns( const Columns& ) = default;
2613  Columns( Columns&& ) = default;
2615  //**********************************************************************************************
2616 
2617  //**Destructor**********************************************************************************
2620  ~Columns() = default;
2622  //**********************************************************************************************
2623 
2624  //**Data access functions***********************************************************************
2627  inline Reference operator()( size_t i, size_t j );
2628  inline ConstReference operator()( size_t i, size_t j ) const;
2629  inline Reference at( size_t i, size_t j );
2630  inline ConstReference at( size_t i, size_t j ) const;
2631  inline Iterator begin ( size_t j );
2632  inline ConstIterator begin ( size_t j ) const;
2633  inline ConstIterator cbegin( size_t j ) const;
2634  inline Iterator end ( size_t j );
2635  inline ConstIterator end ( size_t j ) const;
2636  inline ConstIterator cend ( size_t j ) const;
2638  //**********************************************************************************************
2639 
2640  //**Assignment operators************************************************************************
2643  inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
2644  inline Columns& operator=( const Columns& rhs );
2645 
2646  template< typename MT2, bool SO > inline Columns& operator= ( const Matrix<MT2,SO>& rhs );
2647  template< typename MT2, bool SO > inline Columns& operator+=( const Matrix<MT2,SO>& rhs );
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 );
2651  //**********************************************************************************************
2652 
2653  //**Utility functions***************************************************************************
2656  using DataType::idx;
2657  using DataType::idces;
2658  using DataType::columns;
2659 
2660  inline MT& operand() noexcept;
2661  inline const MT& operand() const noexcept;
2662 
2663  inline size_t rows() const noexcept;
2664  inline size_t capacity() const noexcept;
2665  inline size_t capacity( size_t j ) const noexcept;
2666  inline size_t nonZeros() const;
2667  inline size_t nonZeros( size_t j ) const;
2668  inline void reset();
2669  inline void reset( size_t j );
2670  inline void reserve( size_t nonzeros );
2671  void reserve( size_t j, size_t nonzeros );
2672  inline void trim();
2673  inline void trim( size_t j );
2675  //**********************************************************************************************
2676 
2677  //**Insertion functions*************************************************************************
2680  inline Iterator set ( size_t i, size_t j, const ElementType& value );
2681  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
2682  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2683  inline void finalize( size_t j );
2685  //**********************************************************************************************
2686 
2687  //**Erase functions*****************************************************************************
2690  inline void erase( size_t i, size_t j );
2691  inline Iterator erase( size_t j, Iterator pos );
2692  inline Iterator erase( size_t j, Iterator first, Iterator last );
2693 
2694  template< typename Pred >
2695  inline void erase( Pred predicate );
2696 
2697  template< typename Pred >
2698  inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
2700  //**********************************************************************************************
2701 
2702  //**Lookup functions****************************************************************************
2705  inline Iterator find ( size_t i, size_t j );
2706  inline ConstIterator find ( size_t i, size_t j ) const;
2707  inline Iterator lowerBound( size_t i, size_t j );
2708  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2709  inline Iterator upperBound( size_t i, size_t j );
2710  inline ConstIterator upperBound( size_t i, size_t j ) const;
2712  //**********************************************************************************************
2713 
2714  //**Numeric functions***************************************************************************
2717  inline Columns& transpose();
2718  inline Columns& ctranspose();
2719 
2720  template< typename Other > inline Columns& scale( const Other& scalar );
2722  //**********************************************************************************************
2723 
2724  //**Expression template evaluation functions****************************************************
2727  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
2728  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
2729 
2730  inline bool canSMPAssign() const noexcept;
2731 
2732  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
2733  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
2734  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
2735  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
2736  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
2737  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
2739  //**********************************************************************************************
2740 
2741  private:
2742  //**Member variables****************************************************************************
2745  Operand matrix_;
2746 
2747  //**********************************************************************************************
2748 
2749  //**Compile time checks*************************************************************************
2759  //**********************************************************************************************
2760 };
2762 //*************************************************************************************************
2763 
2764 
2765 
2766 
2767 //=================================================================================================
2768 //
2769 // CONSTRUCTORS
2770 //
2771 //=================================================================================================
2772 
2773 //*************************************************************************************************
2786 template< typename MT // Type of the sparse matrix
2787  , typename... CCAs > // Compile time column arguments
2788 template< typename... RCAs > // Runtime column arguments
2789 inline Columns<MT,false,false,false,CCAs...>::Columns( MT& matrix, RCAs... args )
2790  : DataType( args... ) // Base class initialization
2791  , matrix_ ( matrix ) // The matrix containing the columns
2792 {
2793  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
2794  for( size_t j=0UL; j<columns(); ++j ) {
2795  if( matrix_.columns() <= idx(j) ) {
2796  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2797  }
2798  }
2799  }
2800 }
2802 //*************************************************************************************************
2803 
2804 
2805 
2806 
2807 //=================================================================================================
2808 //
2809 // DATA ACCESS FUNCTIONS
2810 //
2811 //=================================================================================================
2812 
2813 //*************************************************************************************************
2824 template< typename MT // Type of the sparse matrix
2825  , typename... CCAs > // Compile time column arguments
2826 inline typename Columns<MT,false,false,false,CCAs...>::Reference
2827  Columns<MT,false,false,false,CCAs...>::operator()( size_t i, size_t j )
2828 {
2829  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2830  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2831 
2832  return matrix_(i,idx(j));
2833 }
2835 //*************************************************************************************************
2836 
2837 
2838 //*************************************************************************************************
2849 template< typename MT // Type of the sparse matrix
2850  , typename... CCAs > // Compile time column arguments
2851 inline typename Columns<MT,false,false,false,CCAs...>::ConstReference
2852  Columns<MT,false,false,false,CCAs...>::operator()( size_t i, size_t j ) const
2853 {
2854  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2855  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2856 
2857  return const_cast<const MT&>( matrix_ )(i,idx(j));
2858 }
2860 //*************************************************************************************************
2861 
2862 
2863 //*************************************************************************************************
2875 template< typename MT // Type of the sparse matrix
2876  , typename... CCAs > // Compile time column arguments
2877 inline typename Columns<MT,false,false,false,CCAs...>::Reference
2878  Columns<MT,false,false,false,CCAs...>::at( size_t i, size_t j )
2879 {
2880  if( i >= rows() ) {
2881  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2882  }
2883  if( j >= columns() ) {
2884  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2885  }
2886  return (*this)(i,j);
2887 }
2889 //*************************************************************************************************
2890 
2891 
2892 //*************************************************************************************************
2904 template< typename MT // Type of the sparse matrix
2905  , typename... CCAs > // Compile time column arguments
2906 inline typename Columns<MT,false,false,false,CCAs...>::ConstReference
2907  Columns<MT,false,false,false,CCAs...>::at( size_t i, size_t j ) const
2908 {
2909  if( i >= rows() ) {
2910  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2911  }
2912  if( j >= columns() ) {
2913  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2914  }
2915  return (*this)(i,j);
2916 }
2918 //*************************************************************************************************
2919 
2920 
2921 //*************************************************************************************************
2930 template< typename MT // Type of the sparse matrix
2931  , typename... CCAs > // Compile time column arguments
2932 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
2934 {
2935  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2936 
2937  return Iterator( matrix_, 0UL, idx(j) );
2938 }
2940 //*************************************************************************************************
2941 
2942 
2943 //*************************************************************************************************
2952 template< typename MT // Type of the sparse matrix
2953  , typename... CCAs > // Compile time column arguments
2954 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
2956 {
2957  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2958 
2959  return ConstIterator( matrix_, 0UL, idx(j) );
2960 }
2962 //*************************************************************************************************
2963 
2964 
2965 //*************************************************************************************************
2974 template< typename MT // Type of the sparse matrix
2975  , typename... CCAs > // Compile time column arguments
2976 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
2978 {
2979  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2980 
2981  return ConstIterator( matrix_, 0UL, idx(j) );
2982 }
2984 //*************************************************************************************************
2985 
2986 
2987 //*************************************************************************************************
2996 template< typename MT // Type of the sparse matrix
2997  , typename... CCAs > // Compile time column arguments
2998 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3000 {
3001  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
3002 
3003  return Iterator( matrix_, rows(), idx(j) );
3004 }
3006 //*************************************************************************************************
3007 
3008 
3009 //*************************************************************************************************
3018 template< typename MT // Type of the sparse matrix
3019  , typename... CCAs > // Compile time column arguments
3020 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
3022 {
3023  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3024 
3025  return ConstIterator( matrix_, rows(), idx(j) );
3026 }
3028 //*************************************************************************************************
3029 
3030 
3031 //*************************************************************************************************
3040 template< typename MT // Type of the sparse matrix
3041  , typename... CCAs > // Compile time column arguments
3042 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
3044 {
3045  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3046 
3047  return ConstIterator( matrix_, rows(), idx(j) );
3048 }
3050 //*************************************************************************************************
3051 
3052 
3053 
3054 
3055 //=================================================================================================
3056 //
3057 // ASSIGNMENT OPERATORS
3058 //
3059 //=================================================================================================
3060 
3061 //*************************************************************************************************
3077 template< typename MT // Type of the sparse matrix
3078  , typename... CCAs > // Compile time column arguments
3079 inline Columns<MT,false,false,false,CCAs...>&
3080  Columns<MT,false,false,false,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
3081 {
3084 
3085  if( list.size() != rows() ) {
3086  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
3087  }
3088 
3089  const InitializerMatrix<ElementType> tmp( list, columns() );
3090 
3091  if( IsRestricted_v<MT> ) {
3092  for( size_t j=0UL; j<columns(); ++j ) {
3093  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, j ) ) {
3094  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3095  }
3096  }
3097  }
3098 
3099  decltype(auto) left( derestrict( *this ) );
3100 
3101  smpAssign( left, tmp );
3102 
3103  return *this;
3104 }
3106 //*************************************************************************************************
3107 
3108 
3109 //*************************************************************************************************
3124 template< typename MT // Type of the sparse matrix
3125  , typename... CCAs > // Compile time column arguments
3126 inline Columns<MT,false,false,false,CCAs...>&
3127  Columns<MT,false,false,false,CCAs...>::operator=( const Columns& rhs )
3128 {
3131 
3134 
3135  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
3136  return *this;
3137 
3138  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3139  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3140  }
3141 
3142  if( IsRestricted_v<MT> ) {
3143  for( size_t j=0UL; j<columns(); ++j ) {
3144  if( !tryAssign( matrix_, column( rhs, j, unchecked ), 0UL, idx(j) ) ) {
3145  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3146  }
3147  }
3148  }
3149 
3150  decltype(auto) left( derestrict( *this ) );
3151 
3152  if( rhs.canAlias( &matrix_ ) ) {
3153  const ResultType tmp( rhs );
3154  left.reset();
3155  smpAssign( left, tmp );
3156  }
3157  else {
3158  left.reset();
3159  smpAssign( left, rhs );
3160  }
3161 
3162  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3163 
3164  return *this;
3165 }
3167 //*************************************************************************************************
3168 
3169 
3170 //*************************************************************************************************
3185 template< typename MT // Type of the sparse matrix
3186  , typename... CCAs > // Compile time column arguments
3187 template< typename MT2 // Type of the right-hand side matrix
3188  , bool SO > // Storage order of the right-hand side matrix
3189 inline Columns<MT,false,false,false,CCAs...>&
3190  Columns<MT,false,false,false,CCAs...>::operator=( const Matrix<MT2,SO>& rhs )
3191 {
3194 
3195  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3196 
3197  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3198  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3199  }
3200 
3201  using Right = CompositeType_t<MT2>;
3202  Right right( ~rhs );
3203 
3204  if( IsRestricted_v<MT> ) {
3205  for( size_t j=0UL; j<columns(); ++j ) {
3206  if( !tryAssign( matrix_, column( right, j, unchecked ), 0UL, idx(j) ) ) {
3207  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3208  }
3209  }
3210  }
3211 
3212  decltype(auto) left( derestrict( *this ) );
3213 
3214  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
3215  const ResultType_t<MT2> tmp( right );
3216  if( IsSparseMatrix_v< ResultType_t<MT2> > )
3217  left.reset();
3218  smpAssign( left, tmp );
3219  }
3220  else {
3221  if( IsSparseMatrix_v<MT2> )
3222  left.reset();
3223  smpAssign( left, right );
3224  }
3225 
3226  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3227 
3228  return *this;
3229 }
3231 //*************************************************************************************************
3232 
3233 
3234 //*************************************************************************************************
3248 template< typename MT // Type of the sparse matrix
3249  , typename... CCAs > // Compile time column arguments
3250 template< typename MT2 // Type of the right-hand side matrix
3251  , bool SO > // Storage order of the right-hand side matrix
3252 inline Columns<MT,false,false,false,CCAs...>&
3253  Columns<MT,false,false,false,CCAs...>::operator+=( const Matrix<MT2,SO>& rhs )
3254 {
3257 
3260  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3261 
3262  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
3263 
3265 
3266  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3267  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3268  }
3269 
3270  const AddType tmp( *this + (~rhs) );
3271 
3272  if( IsRestricted_v<MT> ) {
3273  for( size_t j=0UL; j<columns(); ++j ) {
3274  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
3275  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3276  }
3277  }
3278  }
3279 
3280  decltype(auto) left( derestrict( *this ) );
3281 
3282  if( IsSparseMatrix_v<AddType> ) {
3283  left.reset();
3284  }
3285 
3286  smpAssign( left, tmp );
3287 
3288  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3289 
3290  return *this;
3291 }
3293 //*************************************************************************************************
3294 
3295 
3296 //*************************************************************************************************
3310 template< typename MT // Type of the sparse matrix
3311  , typename... CCAs > // Compile time column arguments
3312 template< typename MT2 // Type of the right-hand side matrix
3313  , bool SO > // Storage order of the right-hand side matrix
3314 inline Columns<MT,false,false,false,CCAs...>&
3315  Columns<MT,false,false,false,CCAs...>::operator-=( const Matrix<MT2,SO>& rhs )
3316 {
3319 
3322  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3323 
3324  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
3325 
3327 
3328  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3329  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3330  }
3331 
3332  const SubType tmp( *this - (~rhs) );
3333 
3334  if( IsRestricted_v<MT> ) {
3335  for( size_t j=0UL; j<columns(); ++j ) {
3336  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
3337  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3338  }
3339  }
3340  }
3341 
3342  decltype(auto) left( derestrict( *this ) );
3343 
3344  if( IsSparseMatrix_v<SubType> ) {
3345  left.reset();
3346  }
3347 
3348  smpAssign( left, tmp );
3349 
3350  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3351 
3352  return *this;
3353 }
3355 //*************************************************************************************************
3356 
3357 
3358 //*************************************************************************************************
3372 template< typename MT // Type of the sparse matrix
3373  , typename... CCAs > // Compile time column arguments
3374 template< typename MT2 // Type of the right-hand side matrix
3375  , bool SO > // Storage order of the right-hand side matrix
3376 inline Columns<MT,false,false,false,CCAs...>&
3377  Columns<MT,false,false,false,CCAs...>::operator%=( const Matrix<MT2,SO>& rhs )
3378 {
3381 
3384  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
3385 
3386  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
3387 
3389 
3390  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3391  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3392  }
3393 
3394  const SchurType tmp( *this % (~rhs) );
3395 
3396  if( IsRestricted_v<MT> ) {
3397  for( size_t j=0UL; j<columns(); ++j ) {
3398  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
3399  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3400  }
3401  }
3402  }
3403 
3404  decltype(auto) left( derestrict( *this ) );
3405 
3406  if( IsSparseMatrix_v<SchurType> ) {
3407  left.reset();
3408  }
3409 
3410  smpAssign( left, tmp );
3411 
3412  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3413 
3414  return *this;
3415 }
3417 //*************************************************************************************************
3418 
3419 
3420 
3421 
3422 //=================================================================================================
3423 //
3424 // UTILITY FUNCTIONS
3425 //
3426 //=================================================================================================
3427 
3428 //*************************************************************************************************
3434 template< typename MT // Type of the sparse matrix
3435  , typename... CCAs > // Compile time column arguments
3436 inline MT& Columns<MT,false,false,false,CCAs...>::operand() noexcept
3437 {
3438  return matrix_;
3439 }
3441 //*************************************************************************************************
3442 
3443 
3444 //*************************************************************************************************
3450 template< typename MT // Type of the sparse matrix
3451  , typename... CCAs > // Compile time column arguments
3452 inline const MT& Columns<MT,false,false,false,CCAs...>::operand() const noexcept
3453 {
3454  return matrix_;
3455 }
3457 //*************************************************************************************************
3458 
3459 
3460 //*************************************************************************************************
3466 template< typename MT // Type of the sparse matrix
3467  , typename... CCAs > // Compile time column arguments
3468 inline size_t Columns<MT,false,false,false,CCAs...>::rows() const noexcept
3469 {
3470  return matrix_.rows();
3471 }
3473 //*************************************************************************************************
3474 
3475 
3476 //*************************************************************************************************
3482 template< typename MT // Type of the sparse matrix
3483  , typename... CCAs > // Compile time column arguments
3484 inline size_t Columns<MT,false,false,false,CCAs...>::capacity() const noexcept
3485 {
3486  return rows() * columns();
3487 }
3489 //*************************************************************************************************
3490 
3491 
3492 //*************************************************************************************************
3501 template< typename MT // Type of the sparse matrix
3502  , typename... CCAs > // Compile time column arguments
3503 inline size_t Columns<MT,false,false,false,CCAs...>::capacity( size_t j ) const noexcept
3504 {
3505  MAYBE_UNUSED( j );
3506 
3507  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3508 
3509  return rows();
3510 }
3512 //*************************************************************************************************
3513 
3514 
3515 //*************************************************************************************************
3521 template< typename MT // Type of the sparse matrix
3522  , typename... CCAs > // Compile time column arguments
3524 {
3525  size_t nonzeros( 0UL );
3526 
3527  for( size_t i=0UL; i<rows(); ++i ) {
3528  const auto end( matrix_.end( i ) );
3529  for( size_t j=0UL; j<columns(); ++j ) {
3530  auto pos = matrix_.find( i, idx(j) );
3531  if( pos != end ) {
3532  ++nonzeros;
3533  }
3534  }
3535  }
3536 
3537  return nonzeros;
3538 }
3540 //*************************************************************************************************
3541 
3542 
3543 //*************************************************************************************************
3552 template< typename MT // Type of the sparse matrix
3553  , typename... CCAs > // Compile time column arguments
3554 inline size_t Columns<MT,false,false,false,CCAs...>::nonZeros( size_t j ) const
3555 {
3556  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3557 
3558  size_t counter( 0UL );
3559 
3560  const ConstIterator last( end(j) );
3561  for( ConstIterator element=begin(j); element!=last; ++element ) {
3562  ++counter;
3563  }
3564 
3565  return counter;
3566 }
3568 //*************************************************************************************************
3569 
3570 
3571 //*************************************************************************************************
3577 template< typename MT // Type of the sparse matrix
3578  , typename... CCAs > // Compile time column arguments
3580 {
3581  for( size_t j=0UL; j<columns(); ++j ) {
3582  reset( j );
3583  }
3584 }
3586 //*************************************************************************************************
3587 
3588 
3589 //*************************************************************************************************
3599 template< typename MT // Type of the sparse matrix
3600  , typename... CCAs > // Compile time column arguments
3601 inline void Columns<MT,false,false,false,CCAs...>::reset( size_t j )
3602 {
3603  const size_t index( idx(j) );
3604 
3605  const size_t ibegin( ( IsLower_v<MT> )
3606  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3607  ?( index+1UL )
3608  :( index ) )
3609  :( 0UL ) );
3610  const size_t iend ( ( IsUpper_v<MT> )
3611  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3612  ?( index )
3613  :( index+1UL ) )
3614  :( rows() ) );
3615 
3616  for( size_t i=ibegin; i<iend; ++i ) {
3617  matrix_.erase( i, index );
3618  }
3619 }
3621 //*************************************************************************************************
3622 
3623 
3624 //*************************************************************************************************
3635 template< typename MT // Type of the sparse matrix
3636  , typename... CCAs > // Compile time column arguments
3637 inline void Columns<MT,false,false,false,CCAs...>::reserve( size_t nonzeros )
3638 {
3639  MAYBE_UNUSED( nonzeros );
3640 
3641  return;
3642 }
3644 //*************************************************************************************************
3645 
3646 
3647 //*************************************************************************************************
3660 template< typename MT // Type of the sparse matrix
3661  , typename... CCAs > // Compile time column arguments
3662 void Columns<MT,false,false,false,CCAs...>::reserve( size_t j, size_t nonzeros )
3663 {
3664  MAYBE_UNUSED( j, nonzeros );
3665 
3666  return;
3667 }
3669 //*************************************************************************************************
3670 
3671 
3672 //*************************************************************************************************
3682 template< typename MT // Type of the sparse matrix
3683  , typename... CCAs > // Compile time column arguments
3684 void Columns<MT,false,false,false,CCAs...>::trim()
3685 {
3686  return;
3687 }
3689 //*************************************************************************************************
3690 
3691 
3692 //*************************************************************************************************
3703 template< typename MT // Type of the sparse matrix
3704  , typename... CCAs > // Compile time column arguments
3705 void Columns<MT,false,false,false,CCAs...>::trim( size_t j )
3706 {
3707  MAYBE_UNUSED( j );
3708 
3709  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3710 
3711  return;
3712 }
3714 //*************************************************************************************************
3715 
3716 
3717 
3718 
3719 //=================================================================================================
3720 //
3721 // INSERTION FUNCTIONS
3722 //
3723 //=================================================================================================
3724 
3725 //*************************************************************************************************
3738 template< typename MT // Type of the sparse matrix
3739  , typename... CCAs > // Compile time column arguments
3740 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3741  Columns<MT,false,false,false,CCAs...>::set( size_t i, size_t j, const ElementType& value )
3742 {
3743  return Iterator( matrix_, i, idx(j), matrix_.set( i, idx(j), value ) );
3744 }
3746 //*************************************************************************************************
3747 
3748 
3749 //*************************************************************************************************
3763 template< typename MT // Type of the sparse matrix
3764  , typename... CCAs > // Compile time column arguments
3765 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3766  Columns<MT,false,false,false,CCAs...>::insert( size_t i, size_t j, const ElementType& value )
3767 {
3768  return Iterator( matrix_, i, idx(j), matrix_.insert( i, idx(j), value ) );
3769 }
3771 //*************************************************************************************************
3772 
3773 
3774 //*************************************************************************************************
3818 template< typename MT // Type of the sparse matrix
3819  , typename... CCAs > // Compile time column arguments
3820 inline void Columns<MT,false,false,false,CCAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
3821 {
3822  if( !check || !isDefault<strict>( value ) )
3823  matrix_.insert( i, idx(j), value );
3824 }
3826 //*************************************************************************************************
3827 
3828 
3829 //*************************************************************************************************
3843 template< typename MT // Type of the sparse matrix
3844  , typename... CCAs > // Compile time column arguments
3845 inline void Columns<MT,false,false,false,CCAs...>::finalize( size_t j )
3846 {
3847  MAYBE_UNUSED( j );
3848 
3849  return;
3850 }
3852 //*************************************************************************************************
3853 
3854 
3855 
3856 
3857 //=================================================================================================
3858 //
3859 // ERASE FUNCTIONS
3860 //
3861 //=================================================================================================
3862 
3863 //*************************************************************************************************
3873 template< typename MT // Type of the sparse matrix
3874  , typename... CCAs > // Compile time column arguments
3875 inline void Columns<MT,false,false,false,CCAs...>::erase( size_t i, size_t j )
3876 {
3877  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3878  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3879 
3880  matrix_.erase( i, idx(j) );
3881 }
3883 //*************************************************************************************************
3884 
3885 
3886 //*************************************************************************************************
3896 template< typename MT // Type of the sparse matrix
3897  , typename... CCAs > // Compile time column arguments
3898 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3899  Columns<MT,false,false,false,CCAs...>::erase( size_t j, Iterator pos )
3900 {
3901  const size_t row( pos.row_ );
3902 
3903  if( row == rows() )
3904  return pos;
3905 
3906  matrix_.erase( row, pos.pos_ );
3907  return Iterator( matrix_, row+1UL, idx(j) );
3908 }
3910 //*************************************************************************************************
3911 
3912 
3913 //*************************************************************************************************
3924 template< typename MT // Type of the sparse matrix
3925  , typename... CCAs > // Compile time column arguments
3926 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3927  Columns<MT,false,false,false,CCAs...>::erase( size_t j, Iterator first, Iterator last )
3928 {
3929  MAYBE_UNUSED( j );
3930 
3931  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3932 
3933  for( ; first!=last; ++first ) {
3934  matrix_.erase( first.row_, first.pos_ );
3935  }
3936 
3937  return last;
3938 }
3940 //*************************************************************************************************
3941 
3942 
3943 //*************************************************************************************************
3966 template< typename MT // Type of the sparse matrix
3967  , typename... CCAs > // Compile time column arguments
3968 template< typename Pred > // Type of the unary predicate
3969 inline void Columns<MT,false,false,false,CCAs...>::erase( Pred predicate )
3970 {
3971  for( size_t j=0UL; j<columns(); ++j ) {
3972  for( Iterator element=begin(j); element!=end(j); ++element ) {
3973  if( predicate( element->value() ) )
3974  matrix_.erase( element.row_, element.pos_ );
3975  }
3976  }
3977 }
3979 //*************************************************************************************************
3980 
3981 
3982 //*************************************************************************************************
4009 template< typename MT // Type of the sparse matrix
4010  , typename... CCAs > // Compile time column arguments
4011 template< typename Pred > // Type of the unary predicate
4012 inline void Columns<MT,false,false,false,CCAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
4013 {
4014  MAYBE_UNUSED( j );
4015 
4016  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4017 
4018  for( ; first!=last; ++first ) {
4019  if( predicate( first->value() ) )
4020  matrix_.erase( first.row_, first.pos_ );
4021  }
4022 }
4024 //*************************************************************************************************
4025 
4026 
4027 
4028 
4029 //=================================================================================================
4030 //
4031 // LOOKUP FUNCTIONS
4032 //
4033 //=================================================================================================
4034 
4035 //*************************************************************************************************
4050 template< typename MT // Type of the sparse matrix
4051  , typename... CCAs > // Compile time column arguments
4052 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
4053  Columns<MT,false,false,false,CCAs...>::find( size_t i, size_t j )
4054 {
4055  const size_t index( idx(j) );
4056  const Iterator_t<MT> pos( matrix_.find( i, index ) );
4057 
4058  if( pos != matrix_.end( i ) )
4059  return Iterator( matrix_, i, index, pos );
4060  else
4061  return end( j );
4062 }
4064 //*************************************************************************************************
4065 
4066 
4067 //*************************************************************************************************
4082 template< typename MT // Type of the sparse matrix
4083  , typename... CCAs > // Compile time column arguments
4084 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
4085  Columns<MT,false,false,false,CCAs...>::find( size_t i, size_t j ) const
4086 {
4087  const size_t index( idx(j) );
4088  const ConstIterator_t<MT> pos( matrix_.find( i, index ) );
4089 
4090  if( pos != matrix_.end( i ) )
4091  return ConstIterator( matrix_, i, index, pos );
4092  else
4093  return end( j );
4094 }
4096 //*************************************************************************************************
4097 
4098 
4099 //*************************************************************************************************
4113 template< typename MT // Type of the sparse matrix
4114  , typename... CCAs > // Compile time column arguments
4115 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
4116  Columns<MT,false,false,false,CCAs...>::lowerBound( size_t i, size_t j )
4117 {
4118  const size_t index( idx(j) );
4119 
4120  for( ; i<rows(); ++i )
4121  {
4122  const Iterator_t<MT> pos( matrix_.find( i, index ) );
4123 
4124  if( pos != matrix_.end( i ) )
4125  return Iterator( matrix_, i, index, pos );
4126  }
4127 
4128  return end( j );
4129 }
4131 //*************************************************************************************************
4132 
4133 
4134 //*************************************************************************************************
4148 template< typename MT // Type of the sparse matrix
4149  , typename... CCAs > // Compile time column arguments
4150 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
4151  Columns<MT,false,false,false,CCAs...>::lowerBound( size_t i, size_t j ) const
4152 {
4153  const size_t index( idx(j) );
4154 
4155  for( ; i<rows(); ++i )
4156  {
4157  const ConstIterator_t<MT> pos( matrix_.find( i, index ) );
4158 
4159  if( pos != matrix_.end( i ) )
4160  return ConstIterator( matrix_, i, index, pos );
4161  }
4162 
4163  return end( j );
4164 }
4166 //*************************************************************************************************
4167 
4168 
4169 //*************************************************************************************************
4183 template< typename MT // Type of the sparse matrix
4184  , typename... CCAs > // Compile time column arguments
4185 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
4186  Columns<MT,false,false,false,CCAs...>::upperBound( size_t i, size_t j )
4187 {
4188  return lowerBound( i+1UL, j );
4189 }
4191 //*************************************************************************************************
4192 
4193 
4194 //*************************************************************************************************
4208 template< typename MT // Type of the sparse matrix
4209  , typename... CCAs > // Compile time column arguments
4210 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
4211  Columns<MT,false,false,false,CCAs...>::upperBound( size_t i, size_t j ) const
4212 {
4213  return lowerBound( i+1UL, j );
4214 }
4216 //*************************************************************************************************
4217 
4218 
4219 
4220 
4221 //=================================================================================================
4222 //
4223 // NUMERIC FUNCTIONS
4224 //
4225 //=================================================================================================
4226 
4227 //*************************************************************************************************
4240 template< typename MT // Type of the sparse matrix
4241  , typename... CCAs > // Compile time column arguments
4242 inline Columns<MT,false,false,false,CCAs...>&
4244 {
4247 
4248  if( rows() != columns() ) {
4249  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4250  }
4251 
4252  const ResultType tmp( trans( *this ) );
4253 
4254  if( IsRestricted_v<MT> ) {
4255  for( size_t j=0UL; j<columns(); ++j ) {
4256  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
4257  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4258  }
4259  }
4260  }
4261 
4262  decltype(auto) left( derestrict( *this ) );
4263 
4264  left.reset();
4265  smpAssign( left, tmp );
4266 
4267  return *this;
4268 }
4270 //*************************************************************************************************
4271 
4272 
4273 //*************************************************************************************************
4286 template< typename MT // Type of the sparse matrix
4287  , typename... CCAs > // Compile time column arguments
4288 inline Columns<MT,false,false,false,CCAs...>&
4289  Columns<MT,false,false,false,CCAs...>::ctranspose()
4290 {
4293 
4294  if( rows() != columns() ) {
4295  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4296  }
4297 
4298  const ResultType tmp( ctrans( *this ) );
4299 
4300  if( IsRestricted_v<MT> ) {
4301  for( size_t j=0UL; j<columns(); ++j ) {
4302  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
4303  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4304  }
4305  }
4306  }
4307 
4308  decltype(auto) left( derestrict( *this ) );
4309 
4310  left.reset();
4311  smpAssign( left, tmp );
4312 
4313  return *this;
4314 }
4316 //*************************************************************************************************
4317 
4318 
4319 //*************************************************************************************************
4332 template< typename MT // Type of the sparse matrix
4333  , typename... CCAs > // Compile time column arguments
4334 template< typename Other > // Data type of the scalar value
4335 inline Columns<MT,false,false,false,CCAs...>&
4336  Columns<MT,false,false,false,CCAs...>::scale( const Other& scalar )
4337 {
4341 
4342  for( size_t i=0UL; i<rows(); ++i ) {
4343  const auto end( matrix_.end( i ) );
4344  for( size_t j=0UL; j<columns(); ++j ) {
4345  auto pos = matrix_.find( i, idx(j) );
4346  if( pos != end ) {
4347  pos->value() *= scalar;
4348  }
4349  }
4350  }
4351 
4352  return *this;
4353 }
4355 //*************************************************************************************************
4356 
4357 
4358 
4359 
4360 //=================================================================================================
4361 //
4362 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4363 //
4364 //=================================================================================================
4365 
4366 //*************************************************************************************************
4377 template< typename MT // Type of the sparse matrix
4378  , typename... CCAs > // Compile time column arguments
4379 template< typename Other > // Data type of the foreign expression
4380 inline bool Columns<MT,false,false,false,CCAs...>::canAlias( const Other* alias ) const noexcept
4381 {
4382  return matrix_.isAliased( alias );
4383 }
4385 //*************************************************************************************************
4386 
4387 
4388 //*************************************************************************************************
4399 template< typename MT // Type of the sparse matrix
4400  , typename... CCAs > // Compile time column arguments
4401 template< typename Other > // Data type of the foreign expression
4402 inline bool Columns<MT,false,false,false,CCAs...>::isAliased( const Other* alias ) const noexcept
4403 {
4404  return matrix_.isAliased( alias );
4405 }
4407 //*************************************************************************************************
4408 
4409 
4410 //*************************************************************************************************
4421 template< typename MT // Type of the sparse matrix
4422  , typename... CCAs > // Compile time column arguments
4423 inline bool Columns<MT,false,false,false,CCAs...>::canSMPAssign() const noexcept
4424 {
4425  return false;
4426 }
4428 //*************************************************************************************************
4429 
4430 
4431 //*************************************************************************************************
4443 template< typename MT // Type of the sparse matrix
4444  , typename... CCAs > // Compile time column arguments
4445 template< typename MT2 // Type of the right-hand side dense matrix
4446  , bool SO > // Storage order of the right-hand side dense matrix
4447 inline void Columns<MT,false,false,false,CCAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
4448 {
4451 
4452  using RT = If_t< IsComputation_v<MT2>, ElementType_t<MT>, const ElementType_t<MT2>& >;
4453 
4454  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4455  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4456 
4457  for( size_t i=0UL; i<rows(); ++i ) {
4458  for( size_t j=0UL; j<columns(); ++j ) {
4459  RT value( (~rhs)(i,j) );
4460  if( !isDefault<strict>( value ) )
4461  matrix_.set( i, idx(j), std::move( value ) );
4462  else matrix_.erase( i, idx(j) );
4463  }
4464  }
4465 }
4467 //*************************************************************************************************
4468 
4469 
4470 //*************************************************************************************************
4482 template< typename MT // Type of the sparse matrix
4483  , typename... CCAs > // Compile time column arguments
4484 template< typename MT2 > // Type of the right-hand side sparse matrix
4485 inline void Columns<MT,false,false,false,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
4486 {
4489 
4491 
4492  using RT = If_t< IsComputation_v<MT2>, ElementType_t<MT>, const ElementType_t<MT2>& >;
4493 
4494  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4495  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4496  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4497 
4498  for( size_t i=0UL; i<rows(); ++i ) {
4499  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
4500  RT value( element->value() );
4501  if( !isDefault<strict>( value ) )
4502  matrix_.set( i, idx( element->index() ), std::move( value ) );
4503  else matrix_.erase( i, idx( element->index() ) );
4504  }
4505  }
4506 }
4508 //*************************************************************************************************
4509 
4510 
4511 //*************************************************************************************************
4523 template< typename MT // Type of the sparse matrix
4524  , typename... CCAs > // Compile time column arguments
4525 template< typename MT2 > // Type of the right-hand side sparse matrix
4526 inline void Columns<MT,false,false,false,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
4527 {
4530 
4531  using RT = If_t< IsComputation_v<MT2>, ElementType_t<MT>, const ElementType_t<MT2>& >;
4532 
4533  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4534  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4535  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4536 
4537  for( size_t j=0UL; j<columns(); ++j ) {
4538  const size_t index( idx(j) );
4539  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4540  RT value( element->value() );
4541  if( !isDefault<strict>( value ) )
4542  matrix_.set( element->index(), index, std::move( value ) );
4543  else matrix_.erase( element->index(), index );
4544  }
4545  }
4546 }
4548 //*************************************************************************************************
4549 
4550 
4551 //*************************************************************************************************
4563 template< typename MT // Type of the sparse matrix
4564  , typename... CCAs > // Compile time column arguments
4565 template< typename MT2 // Type of the right-hand side matrix
4566  , bool SO > // Storage order of the right-hand side matrix
4567 inline void Columns<MT,false,false,false,CCAs...>::addAssign( const Matrix<MT2,SO>& rhs )
4568 {
4571 
4572  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4573 
4575 
4576  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4577  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4578 
4579  const AddType tmp( serial( *this + (~rhs) ) );
4580  reset();
4581  assign( tmp );
4582 }
4584 //*************************************************************************************************
4585 
4586 
4587 //*************************************************************************************************
4599 template< typename MT // Type of the sparse matrix
4600  , typename... CCAs > // Compile time column arguments
4601 template< typename MT2 // Type of the right-hand side matrix
4602  , bool SO > // Storage order of the right-hand side matrix
4603 inline void Columns<MT,false,false,false,CCAs...>::subAssign( const Matrix<MT2,SO>& rhs )
4604 {
4607 
4608  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4609 
4611 
4612  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4613  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4614 
4615  const SubType tmp( serial( *this - (~rhs) ) );
4616  reset();
4617  assign( tmp );
4618 }
4620 //*************************************************************************************************
4621 
4622 
4623 //*************************************************************************************************
4635 template< typename MT // Type of the sparse matrix
4636  , typename... CCAs > // Compile time column arguments
4637 template< typename MT2 // Type of the right-hand side matrix
4638  , bool SO > // Storage order of the right-hand side matrix
4639 inline void Columns<MT,false,false,false,CCAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
4640 {
4643 
4644  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4645 
4648 
4649  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4650  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4651 
4652  const SchurType tmp( serial( *this % (~rhs) ) );
4653  reset();
4654  assign( tmp );
4655 }
4657 //*************************************************************************************************
4658 
4659 
4660 
4661 
4662 
4663 
4664 
4665 
4666 //=================================================================================================
4667 //
4668 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR SPARSE MATRICES
4669 //
4670 //=================================================================================================
4671 
4672 //*************************************************************************************************
4680 template< typename MT // Type of the sparse matrix
4681  , typename... CCAs > // Compile time column arguments
4682 class Columns<MT,false,false,true,CCAs...>
4683  : public View< SparseMatrix< Columns<MT,false,false,true,CCAs...>, true > >
4684  , private ColumnsData<CCAs...>
4685 {
4686  private:
4687  //**Type definitions****************************************************************************
4688  using DataType = ColumnsData<CCAs...>;
4689  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
4690  //**********************************************************************************************
4691 
4692  //**Compile time flags**************************************************************************
4693  static constexpr size_t N = sizeof...( CCAs );
4694  //**********************************************************************************************
4695 
4696  public:
4697  //**Type definitions****************************************************************************
4699  using This = Columns<MT,false,false,true,CCAs...>;
4700 
4701  using BaseType = SparseMatrix<This,true>;
4702  using ViewedType = MT;
4703  using ResultType = ColumnsTrait_t<MT,N>;
4704  using OppositeType = OppositeType_t<ResultType>;
4705  using TransposeType = TransposeType_t<ResultType>;
4706  using ElementType = ElementType_t<MT>;
4707  using ReturnType = ReturnType_t<MT>;
4708  using CompositeType = const Columns&;
4709 
4711  using ConstReference = ConstReference_t<MT>;
4712 
4714  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
4715 
4717  using ConstIterator = ConstIterator_t<MT>;
4718 
4720  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
4721  //**********************************************************************************************
4722 
4723  //**Compilation flags***************************************************************************
4725  static constexpr bool smpAssignable = MT::smpAssignable;
4726 
4728  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4729  //**********************************************************************************************
4730 
4731  //**Constructors********************************************************************************
4734  template< typename... RCAs >
4735  explicit inline Columns( MT& matrix, RCAs... args );
4736 
4737  Columns( const Columns& ) = default;
4738  Columns( Columns&& ) = default;
4740  //**********************************************************************************************
4741 
4742  //**Destructor**********************************************************************************
4745  ~Columns() = default;
4747  //**********************************************************************************************
4748 
4749  //**Data access functions***********************************************************************
4752  inline Reference operator()( size_t i, size_t j );
4753  inline ConstReference operator()( size_t i, size_t j ) const;
4754  inline Reference at( size_t i, size_t j );
4755  inline ConstReference at( size_t i, size_t j ) const;
4756  inline Iterator begin ( size_t j );
4757  inline ConstIterator begin ( size_t j ) const;
4758  inline ConstIterator cbegin( size_t j ) const;
4759  inline Iterator end ( size_t j );
4760  inline ConstIterator end ( size_t j ) const;
4761  inline ConstIterator cend ( size_t j ) const;
4763  //**********************************************************************************************
4764 
4765  //**Assignment operators************************************************************************
4768  Columns& operator=( const Columns& ) = delete;
4770  //**********************************************************************************************
4771 
4772  //**Utility functions***************************************************************************
4775  using DataType::idx;
4776  using DataType::idces;
4777  using DataType::columns;
4778 
4779  inline MT& operand() noexcept;
4780  inline const MT& operand() const noexcept;
4781 
4782  inline size_t rows() const noexcept;
4783  inline size_t capacity() const noexcept;
4784  inline size_t capacity( size_t j ) const noexcept;
4785  inline size_t nonZeros() const;
4786  inline size_t nonZeros( size_t j ) const;
4787  inline void reset();
4788  inline void reset( size_t j );
4789  inline void reserve( size_t nonzeros );
4790  void reserve( size_t j, size_t nonzeros );
4791  inline void trim();
4792  inline void trim( size_t j );
4794  //**********************************************************************************************
4795 
4796  //**Insertion functions*************************************************************************
4799  inline Iterator set ( size_t i, size_t j, const ElementType& value );
4800  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
4801  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
4802  inline void finalize( size_t j );
4804  //**********************************************************************************************
4805 
4806  //**Erase functions*****************************************************************************
4809  inline void erase( size_t i, size_t j );
4810  inline Iterator erase( size_t j, Iterator pos );
4811  inline Iterator erase( size_t j, Iterator first, Iterator last );
4812 
4813  template< typename Pred >
4814  inline void erase( Pred predicate );
4815 
4816  template< typename Pred >
4817  inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
4819  //**********************************************************************************************
4820 
4821  //**Lookup functions****************************************************************************
4824  inline Iterator find ( size_t i, size_t j );
4825  inline ConstIterator find ( size_t i, size_t j ) const;
4826  inline Iterator lowerBound( size_t i, size_t j );
4827  inline ConstIterator lowerBound( size_t i, size_t j ) const;
4828  inline Iterator upperBound( size_t i, size_t j );
4829  inline ConstIterator upperBound( size_t i, size_t j ) const;
4831  //**********************************************************************************************
4832 
4833  //**Expression template evaluation functions****************************************************
4836  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
4837  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
4838 
4839  inline bool canSMPAssign() const noexcept;
4841  //**********************************************************************************************
4842 
4843  private:
4844  //**Member variables****************************************************************************
4847  Operand matrix_;
4848 
4849  //**********************************************************************************************
4850 
4851  //**Compile time checks*************************************************************************
4861  //**********************************************************************************************
4862 };
4864 //*************************************************************************************************
4865 
4866 
4867 
4868 
4869 //=================================================================================================
4870 //
4871 // CONSTRUCTORS
4872 //
4873 //=================================================================================================
4874 
4875 //*************************************************************************************************
4888 template< typename MT // Type of the sparse matrix
4889  , typename... CCAs > // Compile time column arguments
4890 template< typename... RCAs > // Runtime column arguments
4891 inline Columns<MT,false,false,true,CCAs...>::Columns( MT& matrix, RCAs... args )
4892  : DataType( args... ) // Base class initialization
4893  , matrix_ ( matrix ) // The matrix containing the columns
4894 {
4895  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
4896  for( size_t j=0UL; j<columns(); ++j ) {
4897  if( matrix_.columns() <= idx(j) ) {
4898  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
4899  }
4900  }
4901  }
4902 }
4904 //*************************************************************************************************
4905 
4906 
4907 
4908 
4909 //=================================================================================================
4910 //
4911 // DATA ACCESS FUNCTIONS
4912 //
4913 //=================================================================================================
4914 
4915 //*************************************************************************************************
4926 template< typename MT // Type of the sparse matrix
4927  , typename... CCAs > // Compile time column arguments
4928 inline typename Columns<MT,false,false,true,CCAs...>::Reference
4929  Columns<MT,false,false,true,CCAs...>::operator()( size_t i, size_t j )
4930 {
4931  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4932  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4933 
4934  return matrix_(idx(j),i);
4935 }
4937 //*************************************************************************************************
4938 
4939 
4940 //*************************************************************************************************
4951 template< typename MT // Type of the sparse matrix
4952  , typename... CCAs > // Compile time column arguments
4953 inline typename Columns<MT,false,false,true,CCAs...>::ConstReference
4954  Columns<MT,false,false,true,CCAs...>::operator()( size_t i, size_t j ) const
4955 {
4956  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4957  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4958 
4959  return const_cast<const MT&>( matrix_ )(idx(j),i);
4960 }
4962 //*************************************************************************************************
4963 
4964 
4965 //*************************************************************************************************
4977 template< typename MT // Type of the sparse matrix
4978  , typename... CCAs > // Compile time column arguments
4979 inline typename Columns<MT,false,false,true,CCAs...>::Reference
4980  Columns<MT,false,false,true,CCAs...>::at( size_t i, size_t j )
4981 {
4982  if( i >= rows() ) {
4983  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4984  }
4985  if( j >= columns() ) {
4986  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4987  }
4988  return (*this)(i,j);
4989 }
4991 //*************************************************************************************************
4992 
4993 
4994 //*************************************************************************************************
5006 template< typename MT // Type of the sparse matrix
5007  , typename... CCAs > // Compile time column arguments
5008 inline typename Columns<MT,false,false,true,CCAs...>::ConstReference
5009  Columns<MT,false,false,true,CCAs...>::at( size_t i, size_t j ) const
5010 {
5011  if( i >= rows() ) {
5012  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
5013  }
5014  if( j >= columns() ) {
5015  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
5016  }
5017  return (*this)(i,j);
5018 }
5020 //*************************************************************************************************
5021 
5022 
5023 //*************************************************************************************************
5032 template< typename MT // Type of the sparse matrix
5033  , typename... CCAs > // Compile time column arguments
5034 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5036 {
5037  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5038 
5039  return matrix_.begin( idx(j) );
5040 }
5042 //*************************************************************************************************
5043 
5044 
5045 //*************************************************************************************************
5054 template< typename MT // Type of the sparse matrix
5055  , typename... CCAs > // Compile time column arguments
5056 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5058 {
5059  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5060 
5061  return matrix_.cbegin( idx(j) );
5062 }
5064 //*************************************************************************************************
5065 
5066 
5067 //*************************************************************************************************
5076 template< typename MT // Type of the sparse matrix
5077  , typename... CCAs > // Compile time column arguments
5078 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5080 {
5081  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5082 
5083  return matrix_.cbegin( idx(j) );
5084 }
5086 //*************************************************************************************************
5087 
5088 
5089 //*************************************************************************************************
5098 template< typename MT // Type of the sparse matrix
5099  , typename... CCAs > // Compile time column arguments
5100 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5102 {
5103  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5104 
5105  return matrix_.end( idx(j) );
5106 }
5108 //*************************************************************************************************
5109 
5110 
5111 //*************************************************************************************************
5120 template< typename MT // Type of the sparse matrix
5121  , typename... CCAs > // Compile time column arguments
5122 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5124 {
5125  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5126 
5127  return matrix_.cend( idx(j) );
5128 }
5130 //*************************************************************************************************
5131 
5132 
5133 //*************************************************************************************************
5142 template< typename MT // Type of the sparse matrix
5143  , typename... CCAs > // Compile time column arguments
5144 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5146 {
5147  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5148 
5149  return matrix_.cend( idx(j) );
5150 }
5152 //*************************************************************************************************
5153 
5154 
5155 
5156 
5157 //=================================================================================================
5158 //
5159 // UTILITY FUNCTIONS
5160 //
5161 //=================================================================================================
5162 
5163 //*************************************************************************************************
5169 template< typename MT // Type of the sparse matrix
5170  , typename... CCAs > // Compile time column arguments
5171 inline MT& Columns<MT,false,false,true,CCAs...>::operand() noexcept
5172 {
5173  return matrix_;
5174 }
5176 //*************************************************************************************************
5177 
5178 
5179 //*************************************************************************************************
5185 template< typename MT // Type of the sparse matrix
5186  , typename... CCAs > // Compile time column arguments
5187 inline const MT& Columns<MT,false,false,true,CCAs...>::operand() const noexcept
5188 {
5189  return matrix_;
5190 }
5192 //*************************************************************************************************
5193 
5194 
5195 //*************************************************************************************************
5201 template< typename MT // Type of the sparse matrix
5202  , typename... CCAs > // Compile time column arguments
5203 inline size_t Columns<MT,false,false,true,CCAs...>::rows() const noexcept
5204 {
5205  return matrix_.rows();
5206 }
5208 //*************************************************************************************************
5209 
5210 
5211 //*************************************************************************************************
5217 template< typename MT // Type of the sparse matrix
5218  , typename... CCAs > // Compile time column arguments
5219 inline size_t Columns<MT,false,false,true,CCAs...>::capacity() const noexcept
5220 {
5221  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
5222 }
5224 //*************************************************************************************************
5225 
5226 
5227 //*************************************************************************************************
5236 template< typename MT // Type of the sparse matrix
5237  , typename... CCAs > // Compile time column arguments
5238 inline size_t Columns<MT,false,false,true,CCAs...>::capacity( size_t j ) const noexcept
5239 {
5240  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5241 
5242  return matrix_.capacity( idx(j) );
5243 }
5245 //*************************************************************************************************
5246 
5247 
5248 //*************************************************************************************************
5254 template< typename MT // Type of the sparse matrix
5255  , typename... CCAs > // Compile time column arguments
5257 {
5258  size_t nonzeros( 0UL );
5259 
5260  for( size_t j=0UL; j<columns(); ++j )
5261  nonzeros += nonZeros( j );
5262 
5263  return nonzeros;
5264 }
5266 //*************************************************************************************************
5267 
5268 
5269 //*************************************************************************************************
5278 template< typename MT // Type of the sparse matrix
5279  , typename... CCAs > // Compile time column arguments
5280 inline size_t Columns<MT,false,false,true,CCAs...>::nonZeros( size_t j ) const
5281 {
5282  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5283 
5284  return matrix_.nonZeros( idx(j) );
5285 }
5287 //*************************************************************************************************
5288 
5289 
5290 //*************************************************************************************************
5296 template< typename MT // Type of the sparse matrix
5297  , typename... CCAs > // Compile time column arguments
5299 {
5300  for( size_t j=0UL; j<columns(); ++j ) {
5301  matrix_.reset( idx(j) );
5302  }
5303 }
5305 //*************************************************************************************************
5306 
5307 
5308 //*************************************************************************************************
5318 template< typename MT // Type of the sparse matrix
5319  , typename... CCAs > // Compile time column arguments
5320 inline void Columns<MT,false,false,true,CCAs...>::reset( size_t j )
5321 {
5322  matrix_.reset( idx(j) );
5323 }
5325 //*************************************************************************************************
5326 
5327 
5328 //*************************************************************************************************
5339 template< typename MT // Type of the sparse matrix
5340  , typename... CCAs > // Compile time column arguments
5341 inline void Columns<MT,false,false,true,CCAs...>::reserve( size_t nonzeros )
5342 {
5343  const size_t current( capacity() );
5344 
5345  if( nonzeros > current ) {
5346  matrix_.reserve( matrix_.capacity() + nonzeros - current );
5347  }
5348 }
5350 //*************************************************************************************************
5351 
5352 
5353 //*************************************************************************************************
5365 template< typename MT // Type of the sparse matrix
5366  , typename... CCAs > // Compile time column arguments
5367 void Columns<MT,false,false,true,CCAs...>::reserve( size_t j, size_t nonzeros )
5368 {
5369  matrix_.reserve( idx(j), nonzeros );
5370 }
5372 //*************************************************************************************************
5373 
5374 
5375 //*************************************************************************************************
5385 template< typename MT // Type of the sparse matrix
5386  , typename... CCAs > // Compile time column arguments
5387 void Columns<MT,false,false,true,CCAs...>::trim()
5388 {
5389  for( size_t j=0UL; j<columns(); ++j ) {
5390  trim( j );
5391  }
5392 }
5394 //*************************************************************************************************
5395 
5396 
5397 //*************************************************************************************************
5408 template< typename MT // Type of the sparse matrix
5409  , typename... CCAs > // Compile time column arguments
5410 void Columns<MT,false,false,true,CCAs...>::trim( size_t j )
5411 {
5412  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5413 
5414  matrix_.trim( idx(j) );
5415 }
5417 //*************************************************************************************************
5418 
5419 
5420 
5421 
5422 //=================================================================================================
5423 //
5424 // INSERTION FUNCTIONS
5425 //
5426 //=================================================================================================
5427 
5428 //*************************************************************************************************
5441 template< typename MT // Type of the sparse matrix
5442  , typename... CCAs > // Compile time column arguments
5443 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5444  Columns<MT,false,false,true,CCAs...>::set( size_t i, size_t j, const ElementType& value )
5445 {
5446  return matrix_.set( idx(j), i, value );
5447 }
5449 //*************************************************************************************************
5450 
5451 
5452 //*************************************************************************************************
5466 template< typename MT // Type of the sparse matrix
5467  , typename... CCAs > // Compile time column arguments
5468 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5469  Columns<MT,false,false,true,CCAs...>::insert( size_t i, size_t j, const ElementType& value )
5470 {
5471  return matrix_.insert( idx(j), i, value );
5472 }
5474 //*************************************************************************************************
5475 
5476 
5477 //*************************************************************************************************
5521 template< typename MT // Type of the sparse matrix
5522  , typename... CCAs > // Compile time column arguments
5523 inline void Columns<MT,false,false,true,CCAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
5524 {
5525  if( !check || !isDefault<strict>( value ) )
5526  matrix_.insert( idx(j), i, value );
5527 }
5529 //*************************************************************************************************
5530 
5531 
5532 //*************************************************************************************************
5546 template< typename MT // Type of the sparse matrix
5547  , typename... CCAs > // Compile time column arguments
5548 inline void Columns<MT,false,false,true,CCAs...>::finalize( size_t j )
5549 {
5550  MAYBE_UNUSED( j );
5551 
5552  return;
5553 }
5555 //*************************************************************************************************
5556 
5557 
5558 
5559 
5560 //=================================================================================================
5561 //
5562 // ERASE FUNCTIONS
5563 //
5564 //=================================================================================================
5565 
5566 //*************************************************************************************************
5576 template< typename MT // Type of the sparse matrix
5577  , typename... CCAs > // Compile time column arguments
5578 inline void Columns<MT,false,false,true,CCAs...>::erase( size_t i, size_t j )
5579 {
5580  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5581  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5582 
5583  matrix_.erase( idx(j), i );
5584 }
5586 //*************************************************************************************************
5587 
5588 
5589 //*************************************************************************************************
5599 template< typename MT // Type of the sparse matrix
5600  , typename... CCAs > // Compile time column arguments
5601 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5602  Columns<MT,false,false,true,CCAs...>::erase( size_t j, Iterator pos )
5603 {
5604  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5605 
5606  return matrix_.erase( idx(j), pos );
5607 }
5609 //*************************************************************************************************
5610 
5611 
5612 //*************************************************************************************************
5623 template< typename MT // Type of the sparse matrix
5624  , typename... CCAs > // Compile time column arguments
5625 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5626  Columns<MT,false,false,true,CCAs...>::erase( size_t j, Iterator first, Iterator last )
5627 {
5628  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5629 
5630  return matrix_.erase( idx(j), first, last );
5631 }
5633 //*************************************************************************************************
5634 
5635 
5636 //*************************************************************************************************
5659 template< typename MT // Type of the sparse matrix
5660  , typename... CCAs > // Compile time column arguments
5661 template< typename Pred > // Type of the unary predicate
5662 inline void Columns<MT,false,false,true,CCAs...>::erase( Pred predicate )
5663 {
5664  for( size_t j=0UL; j<columns(); ++j ) {
5665  matrix_.erase( idx(j), begin(j), end(j), predicate );
5666  }
5667 }
5669 //*************************************************************************************************
5670 
5671 
5672 //*************************************************************************************************
5699 template< typename MT // Type of the sparse matrix
5700  , typename... CCAs > // Compile time column arguments
5701 template< typename Pred > // Type of the unary predicate
5702 inline void Columns<MT,false,false,true,CCAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
5703 {
5704  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5705 
5706  matrix_.erase( idx(j), first, last, predicate );
5707 }
5709 //*************************************************************************************************
5710 
5711 
5712 
5713 
5714 //=================================================================================================
5715 //
5716 // LOOKUP FUNCTIONS
5717 //
5718 //=================================================================================================
5719 
5720 //*************************************************************************************************
5735 template< typename MT // Type of the sparse matrix
5736  , typename... CCAs > // Compile time column arguments
5737 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5738  Columns<MT,false,false,true,CCAs...>::find( size_t i, size_t j )
5739 {
5740  return matrix_.find( idx(j), i );
5741 }
5743 //*************************************************************************************************
5744 
5745 
5746 //*************************************************************************************************
5761 template< typename MT // Type of the sparse matrix
5762  , typename... CCAs > // Compile time column arguments
5763 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5764  Columns<MT,false,false,true,CCAs...>::find( size_t i, size_t j ) const
5765 {
5766  return matrix_.find( idx(j), i );
5767 }
5769 //*************************************************************************************************
5770 
5771 
5772 //*************************************************************************************************
5786 template< typename MT // Type of the sparse matrix
5787  , typename... CCAs > // Compile time column arguments
5788 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5789  Columns<MT,false,false,true,CCAs...>::lowerBound( size_t i, size_t j )
5790 {
5791  return matrix_.lowerBound( idx(j), i );
5792 }
5794 //*************************************************************************************************
5795 
5796 
5797 //*************************************************************************************************
5811 template< typename MT // Type of the sparse matrix
5812  , typename... CCAs > // Compile time column arguments
5813 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5814  Columns<MT,false,false,true,CCAs...>::lowerBound( size_t i, size_t j ) const
5815 {
5816  return matrix_.lowerBound( idx(j), i );
5817 }
5819 //*************************************************************************************************
5820 
5821 
5822 //*************************************************************************************************
5836 template< typename MT // Type of the sparse matrix
5837  , typename... CCAs > // Compile time column arguments
5838 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5839  Columns<MT,false,false,true,CCAs...>::upperBound( size_t i, size_t j )
5840 {
5841  return matrix_.upperBound( idx(j), i );
5842 }
5844 //*************************************************************************************************
5845 
5846 
5847 //*************************************************************************************************
5861 template< typename MT // Type of the sparse matrix
5862  , typename... CCAs > // Compile time column arguments
5863 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5864  Columns<MT,false,false,true,CCAs...>::upperBound( size_t i, size_t j ) const
5865 {
5866  return matrix_.upperBound( idx(j), i );
5867 }
5869 //*************************************************************************************************
5870 
5871 
5872 
5873 
5874 //=================================================================================================
5875 //
5876 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5877 //
5878 //=================================================================================================
5879 
5880 //*************************************************************************************************
5891 template< typename MT // Type of the sparse matrix
5892  , typename... CCAs > // Compile time column arguments
5893 template< typename Other > // Data type of the foreign expression
5894 inline bool Columns<MT,false,false,true,CCAs...>::canAlias( const Other* alias ) const noexcept
5895 {
5896  return matrix_.isAliased( alias );
5897 }
5899 //*************************************************************************************************
5900 
5901 
5902 //*************************************************************************************************
5913 template< typename MT // Type of the sparse matrix
5914  , typename... CCAs > // Compile time column arguments
5915 template< typename Other > // Data type of the foreign expression
5916 inline bool Columns<MT,false,false,true,CCAs...>::isAliased( const Other* alias ) const noexcept
5917 {
5918  return matrix_.isAliased( alias );
5919 }
5921 //*************************************************************************************************
5922 
5923 
5924 //*************************************************************************************************
5935 template< typename MT // Type of the sparse matrix
5936  , typename... CCAs > // Compile time column arguments
5937 inline bool Columns<MT,false,false,true,CCAs...>::canSMPAssign() const noexcept
5938 {
5939  return false;
5940 }
5942 //*************************************************************************************************
5943 
5944 } // namespace blaze
5945 
5946 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:133
Headerfile for the generic min algorithm.
Header file for the blaze::checked and blaze::unchecked instances.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
Header file for the implementation of the Columns base template.
Header file for the Schur product trait.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
Header file for the IsUniUpper type trait.
Header file for the subtraction trait.
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr 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:750
Header file for the View base class.
Header file for the IsSparseMatrix type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i....
Definition: Computation.h:81
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e....
Definition: Submatrix.h:81
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
Header file for the MAYBE_UNUSED function template.
constexpr bool IsReference_v
Auxiliary variable template for the IsReference type trait.The IsReference_v variable template provid...
Definition: IsReference.h:95
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a symmetric matrix type,...
Definition: Symmetric.h:60
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i....
Definition: TransExpr.h:81
Header file for the extended initializer_list functionality.
Header file for the IsUniLower type trait.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
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:482
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:416
Constraint on the data type.
Constraint on the data type.
Header file for the SparseMatrix base class.
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
Headerfile for the generic max algorithm.
Header file for the IsStrictlyUpper type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1361
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
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:9091
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
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:1162
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
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 Contains_v
Auxiliary variable template for the Contains type trait.The Contains_v variable template provides a c...
Definition: Contains.h:138
Header file for the IsLower type trait.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
Header file for the SparseElement base class.
Constraint on the data type.
Header file for the exception macros of the math module.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1198
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COLUMNS_TYPE(T)
Constraint on the data type.In case the given data type T is a column selection type (i....
Definition: Columns.h:81
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
Constraint on the data type.
Header file for the IsStrictlyLower type trait.
Constraint on the data type.
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:558
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type,...
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the IsConst type trait.
Header file for run time assertion macros.
Header file for the relaxation flag types.
Header file for the addition trait.
Header file for the Unique class template.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance,...
Definition: Check.h:96
Header file for the columns trait.
Constraint on the data type.
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type,...
Definition: Reference.h:79
Header file for the isDefault shim.
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
Constraint on the data type.
Constraint on the data type.
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:808
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
Header file for the implementation of the ColumnsData class template.
Header file for the IsComputation type trait class.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
auto operator *=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:494
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type,...
Definition: Hermitian.h:79
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
Header file for the IsUpper type trait.
Header file for the IsRestricted type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type,...
Definition: SparseMatrix.h:61
constexpr bool IsSparseMatrix_v
Auxiliary variable template for the IsSparseMatrix type trait.The IsSparseMatrix_v variable template ...
Definition: IsSparseMatrix.h:138
Header file for the IsExpression type trait class.
Constraint on the data type.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825