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>
79 #include <blaze/math/views/Check.h>
84 #include <blaze/util/Assert.h>
88 #include <blaze/util/mpl/If.h>
89 #include <blaze/util/TypeList.h>
90 #include <blaze/util/Types.h>
93 #include <blaze/util/Unused.h>
94 
95 
96 namespace blaze {
97 
98 //=================================================================================================
99 //
100 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR SPARSE MATRICES
101 //
102 //=================================================================================================
103 
104 //*************************************************************************************************
112 template< typename MT // Type of the sparse matrix
113  , bool SF // Symmetry flag
114  , size_t... CCAs > // Compile time column arguments
115 class Columns<MT,true,false,SF,CCAs...>
116  : public View< SparseMatrix< Columns<MT,true,false,SF,CCAs...>, true > >
117  , private ColumnsData<CCAs...>
118 {
119  private:
120  //**Type definitions****************************************************************************
121  using DataType = ColumnsData<CCAs...>;
122  using Operand = If_< IsExpression<MT>, MT, MT& >;
123  //**********************************************************************************************
124 
125  public:
126  //**Type definitions****************************************************************************
128  using This = Columns<MT,true,false,SF,CCAs...>;
129 
130  using BaseType = SparseMatrix<This,true>;
131  using ViewedType = MT;
132  using ResultType = ColumnsTrait_<MT,CCAs...>;
133  using OppositeType = OppositeType_<ResultType>;
134  using TransposeType = TransposeType_<ResultType>;
135  using ElementType = ElementType_<MT>;
136  using ReturnType = ReturnType_<MT>;
137  using CompositeType = const Columns&;
138 
140  using ConstReference = ConstReference_<MT>;
141 
143  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
144 
146  using ConstIterator = ConstIterator_<MT>;
147 
149  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
150  //**********************************************************************************************
151 
152  //**Compilation flags***************************************************************************
154  enum : bool { smpAssignable = MT::smpAssignable };
155  //**********************************************************************************************
156 
157  //**Constructors********************************************************************************
160  template< typename... RCAs >
161  explicit inline Columns( MT& matrix, RCAs... args );
162 
163  inline Columns( const Columns& ) = default;
164  inline Columns( Columns&& ) = default;
166  //**********************************************************************************************
167 
168  //**Destructor**********************************************************************************
169  // No explicitly declared destructor.
170  //**********************************************************************************************
171 
172  //**Data access functions***********************************************************************
175  inline Reference operator()( size_t i, size_t j );
176  inline ConstReference operator()( size_t i, size_t j ) const;
177  inline Reference at( size_t i, size_t j );
178  inline ConstReference at( size_t i, size_t j ) const;
179  inline Iterator begin ( size_t j );
180  inline ConstIterator begin ( size_t j ) const;
181  inline ConstIterator cbegin( size_t j ) const;
182  inline Iterator end ( size_t j );
183  inline ConstIterator end ( size_t j ) const;
184  inline ConstIterator cend ( size_t j ) const;
186  //**********************************************************************************************
187 
188  //**Assignment operators************************************************************************
191  inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
192  inline Columns& operator=( const Columns& rhs );
193 
194  template< typename MT2, bool SO > inline Columns& operator= ( const Matrix<MT2,SO>& rhs );
195  template< typename MT2, bool SO > inline Columns& operator+=( const Matrix<MT2,SO>& rhs );
196  template< typename MT2, bool SO > inline Columns& operator-=( const Matrix<MT2,SO>& rhs );
197  template< typename MT2, bool SO > inline Columns& operator%=( const Matrix<MT2,SO>& rhs );
199  //**********************************************************************************************
200 
201  //**Utility functions***************************************************************************
204  using DataType::idx;
205  using DataType::idces;
206  using DataType::columns;
207 
208  inline MT& operand() noexcept;
209  inline const MT& operand() const noexcept;
210 
211  inline size_t rows() const noexcept;
212  inline size_t capacity() const noexcept;
213  inline size_t capacity( size_t j ) const noexcept;
214  inline size_t nonZeros() const;
215  inline size_t nonZeros( size_t j ) const;
216  inline void reset();
217  inline void reset( size_t j );
218  inline void reserve( size_t nonzeros );
219  void reserve( size_t j, size_t nonzeros );
220  inline void trim();
221  inline void trim( size_t j );
223  //**********************************************************************************************
224 
225  //**Insertion functions*************************************************************************
228  inline Iterator set ( size_t i, size_t j, const ElementType& value );
229  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
230  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
231  inline void finalize( size_t j );
233  //**********************************************************************************************
234 
235  //**Erase functions*****************************************************************************
238  inline void erase( size_t i, size_t j );
239  inline Iterator erase( size_t j, Iterator pos );
240  inline Iterator erase( size_t j, Iterator first, Iterator last );
241 
242  template< typename Pred >
243  inline void erase( Pred predicate );
244 
245  template< typename Pred >
246  inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
248  //**********************************************************************************************
249 
250  //**Lookup functions****************************************************************************
253  inline Iterator find ( size_t i, size_t j );
254  inline ConstIterator find ( size_t i, size_t j ) const;
255  inline Iterator lowerBound( size_t i, size_t j );
256  inline ConstIterator lowerBound( size_t i, size_t j ) const;
257  inline Iterator upperBound( size_t i, size_t j );
258  inline ConstIterator upperBound( size_t i, size_t j ) const;
260  //**********************************************************************************************
261 
262  //**Numeric functions***************************************************************************
265  inline Columns& transpose();
266  inline Columns& ctranspose();
267 
268  template< typename Other > inline Columns& scale( const Other& scalar );
270  //**********************************************************************************************
271 
272  //**Expression template evaluation functions****************************************************
275  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
276  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
277 
278  inline bool canSMPAssign() const noexcept;
279 
280  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
281  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
282  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
283  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
284  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
285  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
287  //**********************************************************************************************
288 
289  private:
290  //**Utility functions***************************************************************************
293  inline size_t extendCapacity( size_t j ) const noexcept;
295  //**********************************************************************************************
296 
297  //**Member variables****************************************************************************
300  Operand matrix_;
301 
302  //**********************************************************************************************
303 
304  //**Compile time checks*************************************************************************
313  //**********************************************************************************************
314 };
316 //*************************************************************************************************
317 
318 
319 
320 
321 //=================================================================================================
322 //
323 // CONSTRUCTORS
324 //
325 //=================================================================================================
326 
327 //*************************************************************************************************
340 template< typename MT // Type of the sparse matrix
341  , bool SF // Symmetry flag
342  , size_t... CCAs > // Compile time column arguments
343 template< typename... RCAs > // Runtime column arguments
344 inline Columns<MT,true,false,SF,CCAs...>::Columns( MT& matrix, RCAs... args )
345  : DataType( args... ) // Base class initialization
346  , matrix_ ( matrix ) // The matrix containing the columns
347 {
348  if( !Contains< TypeList<RCAs...>, Unchecked >::value ) {
349  for( size_t j=0UL; j<columns(); ++j ) {
350  if( matrix_.columns() <= idx(j) ) {
351  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
352  }
353  }
354  }
355 }
357 //*************************************************************************************************
358 
359 
360 
361 
362 //=================================================================================================
363 //
364 // DATA ACCESS FUNCTIONS
365 //
366 //=================================================================================================
367 
368 //*************************************************************************************************
379 template< typename MT // Type of the sparse matrix
380  , bool SF // Symmetry flag
381  , size_t... CCAs > // Compile time column arguments
382 inline typename Columns<MT,true,false,SF,CCAs...>::Reference
383  Columns<MT,true,false,SF,CCAs...>::operator()( size_t i, size_t j )
384 {
385  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
386  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
387 
388  return matrix_(i,idx(j));
389 }
391 //*************************************************************************************************
392 
393 
394 //*************************************************************************************************
405 template< typename MT // Type of the sparse matrix
406  , bool SF // Symmetry flag
407  , size_t... CCAs > // Compile time column arguments
408 inline typename Columns<MT,true,false,SF,CCAs...>::ConstReference
409  Columns<MT,true,false,SF,CCAs...>::operator()( size_t i, size_t j ) const
410 {
411  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
412  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
413 
414  return const_cast<const MT&>( matrix_ )(i,idx(j));
415 }
417 //*************************************************************************************************
418 
419 
420 //*************************************************************************************************
432 template< typename MT // Type of the sparse matrix
433  , bool SF // Symmetry flag
434  , size_t... CCAs > // Compile time column arguments
435 inline typename Columns<MT,true,false,SF,CCAs...>::Reference
436  Columns<MT,true,false,SF,CCAs...>::at( size_t i, size_t j )
437 {
438  if( i >= rows() ) {
439  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
440  }
441  if( j >= columns() ) {
442  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
443  }
444  return (*this)(i,j);
445 }
447 //*************************************************************************************************
448 
449 
450 //*************************************************************************************************
462 template< typename MT // Type of the sparse matrix
463  , bool SF // Symmetry flag
464  , size_t... CCAs > // Compile time column arguments
465 inline typename Columns<MT,true,false,SF,CCAs...>::ConstReference
466  Columns<MT,true,false,SF,CCAs...>::at( size_t i, size_t j ) const
467 {
468  if( i >= rows() ) {
469  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
470  }
471  if( j >= columns() ) {
472  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
473  }
474  return (*this)(i,j);
475 }
477 //*************************************************************************************************
478 
479 
480 //*************************************************************************************************
489 template< typename MT // Type of the sparse matrix
490  , bool SF // Symmetry flag
491  , size_t... CCAs > // Compile time column arguments
492 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
494 {
495  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
496 
497  return matrix_.begin( idx(j) );
498 }
500 //*************************************************************************************************
501 
502 
503 //*************************************************************************************************
512 template< typename MT // Type of the sparse matrix
513  , bool SF // Symmetry flag
514  , size_t... CCAs > // Compile time column arguments
515 inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
517 {
518  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
519 
520  return matrix_.cbegin( idx(j) );
521 }
523 //*************************************************************************************************
524 
525 
526 //*************************************************************************************************
535 template< typename MT // Type of the sparse matrix
536  , bool SF // Symmetry flag
537  , size_t... CCAs > // Compile time column arguments
538 inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
540 {
541  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
542 
543  return matrix_.cbegin( idx(j) );
544 }
546 //*************************************************************************************************
547 
548 
549 //*************************************************************************************************
558 template< typename MT // Type of the sparse matrix
559  , bool SF // Symmetry flag
560  , size_t... CCAs > // Compile time column arguments
561 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
563 {
564  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
565 
566  return matrix_.end( idx(j) );
567 }
569 //*************************************************************************************************
570 
571 
572 //*************************************************************************************************
581 template< typename MT // Type of the sparse matrix
582  , bool SF // Symmetry flag
583  , size_t... CCAs > // Compile time column arguments
584 inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
586 {
587  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
588 
589  return matrix_.cend( idx(j) );
590 }
592 //*************************************************************************************************
593 
594 
595 //*************************************************************************************************
604 template< typename MT // Type of the sparse matrix
605  , bool SF // Symmetry flag
606  , size_t... CCAs > // Compile time column arguments
607 inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
609 {
610  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
611 
612  return matrix_.cend( idx(j) );
613 }
615 //*************************************************************************************************
616 
617 
618 
619 
620 //=================================================================================================
621 //
622 // ASSIGNMENT OPERATORS
623 //
624 //=================================================================================================
625 
626 //*************************************************************************************************
642 template< typename MT // Type of the sparse matrix
643  , bool SF // Symmetry flag
644  , size_t... CCAs > // Compile time column arguments
645 inline Columns<MT,true,false,SF,CCAs...>&
646  Columns<MT,true,false,SF,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
647 {
650 
651  if( list.size() != rows() ) {
652  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
653  }
654 
655  const InitializerMatrix<ElementType> tmp( list, columns() );
656 
657  if( IsRestricted<MT>::value ) {
658  for( size_t j=0UL; j<columns(); ++j ) {
659  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, j ) ) {
660  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
661  }
662  }
663  }
664 
665  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
666 
667  left.reset();
668  smpAssign( left, tmp );
669 
670  return *this;
671 }
673 //*************************************************************************************************
674 
675 
676 //*************************************************************************************************
691 template< typename MT // Type of the sparse matrix
692  , bool SF // Symmetry flag
693  , size_t... CCAs > // Compile time column arguments
694 inline Columns<MT,true,false,SF,CCAs...>&
695  Columns<MT,true,false,SF,CCAs...>::operator=( const Columns& rhs )
696 {
699 
702 
703  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && idces() == rhs.idces() ) )
704  return *this;
705 
706  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
707  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
708  }
709 
710  if( IsRestricted<MT>::value ) {
711  for( size_t j=0UL; j<columns(); ++j ) {
712  if( !tryAssign( matrix_, column( rhs, j, unchecked ), 0UL, idx(j) ) ) {
713  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
714  }
715  }
716  }
717 
718  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
719 
720  if( rhs.canAlias( &matrix_ ) ) {
721  const ResultType tmp( rhs );
722  left.reset();
723  smpAssign( left, tmp );
724  }
725  else {
726  left.reset();
727  smpAssign( left, rhs );
728  }
729 
730  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
731 
732  return *this;
733 }
735 //*************************************************************************************************
736 
737 
738 //*************************************************************************************************
753 template< typename MT // Type of the sparse matrix
754  , bool SF // Symmetry flag
755  , size_t... CCAs > // Compile time column arguments
756 template< typename MT2 // Type of the right-hand side matrix
757  , bool SO > // Storage order of the right-hand side matrix
758 inline Columns<MT,true,false,SF,CCAs...>&
759  Columns<MT,true,false,SF,CCAs...>::operator=( const Matrix<MT2,SO>& rhs )
760 {
763 
765 
766  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
767  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
768  }
769 
770  using Right = CompositeType_<MT2>;
771  Right right( ~rhs );
772 
773  if( IsRestricted<MT>::value ) {
774  for( size_t j=0UL; j<columns(); ++j ) {
775  if( !tryAssign( matrix_, column( right, j, unchecked ), 0UL, idx(j) ) ) {
776  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
777  }
778  }
779  }
780 
781  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
782 
783  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
784  const ResultType_<MT2> tmp( right );
785  left.reset();
786  smpAssign( left, tmp );
787  }
788  else {
789  left.reset();
790  smpAssign( left, right );
791  }
792 
793  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
794 
795  return *this;
796 }
798 //*************************************************************************************************
799 
800 
801 //*************************************************************************************************
815 template< typename MT // Type of the sparse matrix
816  , bool SF // Symmetry flag
817  , size_t... CCAs > // Compile time column arguments
818 template< typename MT2 // Type of the right-hand side matrix
819  , bool SO > // Storage order of the right-hand side matrix
820 inline Columns<MT,true,false,SF,CCAs...>&
821  Columns<MT,true,false,SF,CCAs...>::operator+=( const Matrix<MT2,SO>& rhs )
822 {
825 
829 
830  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
831 
833 
834  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
835  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
836  }
837 
838  const AddType tmp( *this + (~rhs) );
839 
840  if( IsRestricted<MT>::value ) {
841  for( size_t j=0UL; j<columns(); ++j ) {
842  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
843  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
844  }
845  }
846  }
847 
848  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
849 
850  left.reset();
851  smpAssign( left, tmp );
852 
853  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
854 
855  return *this;
856 }
858 //*************************************************************************************************
859 
860 
861 //*************************************************************************************************
875 template< typename MT // Type of the sparse matrix
876  , bool SF // Symmetry flag
877  , size_t... CCAs > // Compile time column arguments
878 template< typename MT2 // Type of the right-hand side matrix
879  , bool SO > // Storage order of the right-hand side matrix
880 inline Columns<MT,true,false,SF,CCAs...>&
881  Columns<MT,true,false,SF,CCAs...>::operator-=( const Matrix<MT2,SO>& rhs )
882 {
885 
889 
890  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
891 
893 
894  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
895  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
896  }
897 
898  const SubType tmp( *this - (~rhs) );
899 
900  if( IsRestricted<MT>::value ) {
901  for( size_t j=0UL; j<columns(); ++j ) {
902  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
903  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
904  }
905  }
906  }
907 
908  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
909 
910  left.reset();
911  smpAssign( left, tmp );
912 
913  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
914 
915  return *this;
916 }
918 //*************************************************************************************************
919 
920 
921 //*************************************************************************************************
935 template< typename MT // Type of the sparse matrix
936  , bool SF // Symmetry flag
937  , size_t... CCAs > // Compile time column arguments
938 template< typename MT2 // Type of the right-hand side matrix
939  , bool SO > // Storage order of the right-hand side matrix
940 inline Columns<MT,true,false,SF,CCAs...>&
941  Columns<MT,true,false,SF,CCAs...>::operator%=( const Matrix<MT2,SO>& rhs )
942 {
945 
949 
950  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
951 
953 
954  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
955  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
956  }
957 
958  const SchurType tmp( *this % (~rhs) );
959 
960  if( IsRestricted<MT>::value ) {
961  for( size_t j=0UL; j<columns(); ++j ) {
962  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
963  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
964  }
965  }
966  }
967 
968  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
969 
970  left.reset();
971  smpAssign( left, tmp );
972 
973  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
974 
975  return *this;
976 }
978 //*************************************************************************************************
979 
980 
981 
982 
983 //=================================================================================================
984 //
985 // UTILITY FUNCTIONS
986 //
987 //=================================================================================================
988 
989 //*************************************************************************************************
995 template< typename MT // Type of the sparse matrix
996  , bool SF // Symmetry flag
997  , size_t... CCAs > // Compile time column arguments
998 inline MT& Columns<MT,true,false,SF,CCAs...>::operand() noexcept
999 {
1000  return matrix_;
1001 }
1003 //*************************************************************************************************
1004 
1005 
1006 //*************************************************************************************************
1012 template< typename MT // Type of the sparse matrix
1013  , bool SF // Symmetry flag
1014  , size_t... CCAs > // Compile time column arguments
1015 inline const MT& Columns<MT,true,false,SF,CCAs...>::operand() const noexcept
1016 {
1017  return matrix_;
1018 }
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1029 template< typename MT // Type of the sparse matrix
1030  , bool SF // Symmetry flag
1031  , size_t... CCAs > // Compile time column arguments
1032 inline size_t Columns<MT,true,false,SF,CCAs...>::rows() const noexcept
1033 {
1034  return matrix_.rows();
1035 }
1037 //*************************************************************************************************
1038 
1039 
1040 //*************************************************************************************************
1046 template< typename MT // Type of the sparse matrix
1047  , bool SF // Symmetry flag
1048  , size_t... CCAs > // Compile time column arguments
1049 inline size_t Columns<MT,true,false,SF,CCAs...>::capacity() const noexcept
1050 {
1051  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
1052 }
1054 //*************************************************************************************************
1055 
1056 
1057 //*************************************************************************************************
1066 template< typename MT // Type of the sparse matrix
1067  , bool SF // Symmetry flag
1068  , size_t... CCAs > // Compile time column arguments
1069 inline size_t Columns<MT,true,false,SF,CCAs...>::capacity( size_t j ) const noexcept
1070 {
1071  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1072 
1073  return matrix_.capacity( idx(j) );
1074 }
1076 //*************************************************************************************************
1077 
1078 
1079 //*************************************************************************************************
1085 template< typename MT // Type of the sparse matrix
1086  , bool SF // Symmetry flag
1087  , size_t... CCAs > // Compile time column arguments
1088 inline size_t Columns<MT,true,false,SF,CCAs...>::nonZeros() const
1089 {
1090  size_t nonzeros( 0UL );
1091 
1092  for( size_t j=0UL; j<columns(); ++j )
1093  nonzeros += nonZeros( j );
1094 
1095  return nonzeros;
1096 }
1098 //*************************************************************************************************
1099 
1100 
1101 //*************************************************************************************************
1110 template< typename MT // Type of the sparse matrix
1111  , bool SF // Symmetry flag
1112  , size_t... CCAs > // Compile time column arguments
1113 inline size_t Columns<MT,true,false,SF,CCAs...>::nonZeros( size_t j ) const
1114 {
1115  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1116 
1117  return matrix_.nonZeros( idx(j) );
1118 }
1120 //*************************************************************************************************
1121 
1122 
1123 //*************************************************************************************************
1129 template< typename MT // Type of the sparse matrix
1130  , bool SF // Symmetry flag
1131  , size_t... CCAs > // Compile time column arguments
1133 {
1134  for( size_t j=0UL; j<columns(); ++j ) {
1135  matrix_.reset( idx(j) );
1136  }
1137 }
1139 //*************************************************************************************************
1140 
1141 
1142 //*************************************************************************************************
1152 template< typename MT // Type of the sparse matrix
1153  , bool SF // Symmetry flag
1154  , size_t... CCAs > // Compile time column arguments
1155 inline void Columns<MT,true,false,SF,CCAs...>::reset( size_t j )
1156 {
1157  matrix_.reset( idx(j) );
1158 }
1160 //*************************************************************************************************
1161 
1162 
1163 //*************************************************************************************************
1174 template< typename MT // Type of the sparse matrix
1175  , bool SF // Symmetry flag
1176  , size_t... CCAs > // Compile time column arguments
1177 inline void Columns<MT,true,false,SF,CCAs...>::reserve( size_t nonzeros )
1178 {
1179  const size_t current( capacity() );
1180 
1181  if( nonzeros > current ) {
1182  matrix_.reserve( matrix_.capacity() + nonzeros - current );
1183  }
1184 }
1186 //*************************************************************************************************
1187 
1188 
1189 //*************************************************************************************************
1202 template< typename MT // Type of the sparse matrix
1203  , bool SF // Symmetry flag
1204  , size_t... CCAs > // Compile time column arguments
1205 void Columns<MT,true,false,SF,CCAs...>::reserve( size_t j, size_t nonzeros )
1206 {
1207  matrix_.reserve( idx(j), nonzeros );
1208 }
1210 //*************************************************************************************************
1211 
1212 
1213 //*************************************************************************************************
1223 template< typename MT // Type of the sparse matrix
1224  , bool SF // Symmetry flag
1225  , size_t... CCAs > // Compile time column arguments
1226 void Columns<MT,true,false,SF,CCAs...>::trim()
1227 {
1228  for( size_t j=0UL; j<columns(); ++j ) {
1229  trim( j );
1230  }
1231 }
1233 //*************************************************************************************************
1234 
1235 
1236 //*************************************************************************************************
1247 template< typename MT // Type of the sparse matrix
1248  , bool SF // Symmetry flag
1249  , size_t... CCAs > // Compile time column arguments
1250 void Columns<MT,true,false,SF,CCAs...>::trim( size_t j )
1251 {
1252  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1253 
1254  matrix_.trim( idx(j) );
1255 }
1257 //*************************************************************************************************
1258 
1259 
1260 //*************************************************************************************************
1270 template< typename MT // Type of the sparse matrix
1271  , bool SF // Symmetry flag
1272  , size_t... CCAs > // Compile time column arguments
1273 inline size_t Columns<MT,true,false,SF,CCAs...>::extendCapacity( size_t j ) const noexcept
1274 {
1275  using blaze::max;
1276  using blaze::min;
1277 
1278  size_t nonzeros( 2UL*capacity( j )+1UL );
1279  nonzeros = max( nonzeros, 7UL );
1280  nonzeros = min( nonzeros, rows() );
1281 
1282  BLAZE_INTERNAL_ASSERT( nonzeros > capacity( j ), "Invalid capacity value" );
1283 
1284  return nonzeros;
1285 }
1287 //*************************************************************************************************
1288 
1289 
1290 
1291 
1292 //=================================================================================================
1293 //
1294 // INSERTION FUNCTIONS
1295 //
1296 //=================================================================================================
1297 
1298 //*************************************************************************************************
1311 template< typename MT // Type of the sparse matrix
1312  , bool SF // Symmetry flag
1313  , size_t... CCAs > // Compile time column arguments
1314 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1315  Columns<MT,true,false,SF,CCAs...>::set( size_t i, size_t j, const ElementType& value )
1316 {
1317  return matrix_.set( i, idx(j), value );
1318 }
1320 //*************************************************************************************************
1321 
1322 
1323 //*************************************************************************************************
1337 template< typename MT // Type of the sparse matrix
1338  , bool SF // Symmetry flag
1339  , size_t... CCAs > // Compile time column arguments
1340 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1341  Columns<MT,true,false,SF,CCAs...>::insert( size_t i, size_t j, const ElementType& value )
1342 {
1343  return matrix_.insert( i, idx(j), value );
1344 }
1346 //*************************************************************************************************
1347 
1348 
1349 //*************************************************************************************************
1393 template< typename MT // Type of the sparse matrix
1394  , bool SF // Symmetry flag
1395  , size_t... CCAs > // Compile time column arguments
1396 inline void Columns<MT,true,false,SF,CCAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
1397 {
1398  if( !check || !isDefault<strict>( value ) )
1399  matrix_.insert( i, idx(j), value );
1400 }
1402 //*************************************************************************************************
1403 
1404 
1405 //*************************************************************************************************
1419 template< typename MT // Type of the sparse matrix
1420  , bool SF // Symmetry flag
1421  , size_t... CCAs > // Compile time column arguments
1422 inline void Columns<MT,true,false,SF,CCAs...>::finalize( size_t j )
1423 {
1424  UNUSED_PARAMETER( j );
1425 
1426  return;
1427 }
1429 //*************************************************************************************************
1430 
1431 
1432 
1433 
1434 //=================================================================================================
1435 //
1436 // ERASE FUNCTIONS
1437 //
1438 //=================================================================================================
1439 
1440 //*************************************************************************************************
1450 template< typename MT // Type of the sparse matrix
1451  , bool SF // Symmetry flag
1452  , size_t... CCAs > // Compile time column arguments
1453 inline void Columns<MT,true,false,SF,CCAs...>::erase( size_t i, size_t j )
1454 {
1455  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1456  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1457 
1458  matrix_.erase( i, idx(j) );
1459 }
1461 //*************************************************************************************************
1462 
1463 
1464 //*************************************************************************************************
1474 template< typename MT // Type of the sparse matrix
1475  , bool SF // Symmetry flag
1476  , size_t... CCAs > // Compile time column arguments
1477 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1478  Columns<MT,true,false,SF,CCAs...>::erase( size_t j, Iterator pos )
1479 {
1480  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1481 
1482  return matrix_.erase( idx(j), pos );
1483 }
1485 //*************************************************************************************************
1486 
1487 
1488 //*************************************************************************************************
1499 template< typename MT // Type of the sparse matrix
1500  , bool SF // Symmetry flag
1501  , size_t... CCAs > // Compile time column arguments
1502 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1503  Columns<MT,true,false,SF,CCAs...>::erase( size_t j, Iterator first, Iterator last )
1504 {
1505  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1506 
1507  return matrix_.erase( idx(j), first, last );
1508 }
1510 //*************************************************************************************************
1511 
1512 
1513 //*************************************************************************************************
1536 template< typename MT // Type of the sparse matrix
1537  , bool SF // Symmetry flag
1538  , size_t... CCAs > // Compile time column arguments
1539 template< typename Pred > // Type of the unary predicate
1540 inline void Columns<MT,true,false,SF,CCAs...>::erase( Pred predicate )
1541 {
1542  for( size_t j=0UL; j<columns(); ++j ) {
1543  matrix_.erase( idx(j), begin(j), end(j), predicate );
1544  }
1545 }
1547 //*************************************************************************************************
1548 
1549 
1550 //*************************************************************************************************
1577 template< typename MT // Type of the sparse matrix
1578  , bool SF // Symmetry flag
1579  , size_t... CCAs > // Compile time column arguments
1580 template< typename Pred > // Type of the unary predicate
1581 inline void Columns<MT,true,false,SF,CCAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
1582 {
1583  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1584 
1585  matrix_.erase( idx(j), first, last, predicate );
1586 }
1588 //*************************************************************************************************
1589 
1590 
1591 
1592 
1593 //=================================================================================================
1594 //
1595 // LOOKUP FUNCTIONS
1596 //
1597 //=================================================================================================
1598 
1599 //*************************************************************************************************
1614 template< typename MT // Type of the sparse matrix
1615  , bool SF // Symmetry flag
1616  , size_t... CCAs > // Compile time column arguments
1617 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1618  Columns<MT,true,false,SF,CCAs...>::find( size_t i, size_t j )
1619 {
1620  return matrix_.find( i, idx(j) );
1621 }
1623 //*************************************************************************************************
1624 
1625 
1626 //*************************************************************************************************
1641 template< typename MT // Type of the sparse matrix
1642  , bool SF // Symmetry flag
1643  , size_t... CCAs > // Compile time column arguments
1644 inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
1645  Columns<MT,true,false,SF,CCAs...>::find( size_t i, size_t j ) const
1646 {
1647  return matrix_.find( i, idx(j) );
1648 }
1650 //*************************************************************************************************
1651 
1652 
1653 //*************************************************************************************************
1667 template< typename MT // Type of the sparse matrix
1668  , bool SF // Symmetry flag
1669  , size_t... CCAs > // Compile time column arguments
1670 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1671  Columns<MT,true,false,SF,CCAs...>::lowerBound( size_t i, size_t j )
1672 {
1673  return matrix_.lowerBound( i, idx(j) );
1674 }
1676 //*************************************************************************************************
1677 
1678 
1679 //*************************************************************************************************
1693 template< typename MT // Type of the sparse matrix
1694  , bool SF // Symmetry flag
1695  , size_t... CCAs > // Compile time column arguments
1696 inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
1697  Columns<MT,true,false,SF,CCAs...>::lowerBound( size_t i, size_t j ) const
1698 {
1699  return matrix_.lowerBound( i, idx(j) );
1700 }
1702 //*************************************************************************************************
1703 
1704 
1705 //*************************************************************************************************
1719 template< typename MT // Type of the sparse matrix
1720  , bool SF // Symmetry flag
1721  , size_t... CCAs > // Compile time column arguments
1722 inline typename Columns<MT,true,false,SF,CCAs...>::Iterator
1723  Columns<MT,true,false,SF,CCAs...>::upperBound( size_t i, size_t j )
1724 {
1725  return matrix_.upperBound( i, idx(j) );
1726 }
1728 //*************************************************************************************************
1729 
1730 
1731 //*************************************************************************************************
1745 template< typename MT // Type of the sparse matrix
1746  , bool SF // Symmetry flag
1747  , size_t... CCAs > // Compile time column arguments
1748 inline typename Columns<MT,true,false,SF,CCAs...>::ConstIterator
1749  Columns<MT,true,false,SF,CCAs...>::upperBound( size_t i, size_t j ) const
1750 {
1751  return matrix_.upperBound( i, idx(j) );
1752 }
1754 //*************************************************************************************************
1755 
1756 
1757 
1758 
1759 //=================================================================================================
1760 //
1761 // NUMERIC FUNCTIONS
1762 //
1763 //=================================================================================================
1764 
1765 //*************************************************************************************************
1778 template< typename MT // Type of the sparse matrix
1779  , bool SF // Symmetry flag
1780  , size_t... CCAs > // Compile time column arguments
1781 inline Columns<MT,true,false,SF,CCAs...>&
1783 {
1784  if( rows() != columns() ) {
1785  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1786  }
1787 
1788  const ResultType tmp( trans( *this ) );
1789 
1790  if( IsRestricted<MT>::value ) {
1791  for( size_t j=0UL; j<columns(); ++j ) {
1792  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
1793  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1794  }
1795  }
1796  }
1797 
1798  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1799 
1800  left.reset();
1801  smpAssign( left, tmp );
1802 
1803  return *this;
1804 }
1806 //*************************************************************************************************
1807 
1808 
1809 //*************************************************************************************************
1822 template< typename MT // Type of the sparse matrix
1823  , bool SF // Symmetry flag
1824  , size_t... CCAs > // Compile time column arguments
1825 inline Columns<MT,true,false,SF,CCAs...>&
1827 {
1828  if( rows() != columns() ) {
1829  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1830  }
1831 
1832  const ResultType tmp( ctrans( *this ) );
1833 
1834  if( IsRestricted<MT>::value ) {
1835  for( size_t j=0UL; j<columns(); ++j ) {
1836  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
1837  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1838  }
1839  }
1840  }
1841 
1842  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1843 
1844  left.reset();
1845  smpAssign( left, tmp );
1846 
1847  return *this;
1848 }
1850 //*************************************************************************************************
1851 
1852 
1853 //*************************************************************************************************
1866 template< typename MT // Type of the sparse matrix
1867  , bool SF // Symmetry flag
1868  , size_t... CCAs > // Compile time column arguments
1869 template< typename Other > // Data type of the scalar value
1870 inline Columns<MT,true,false,SF,CCAs...>&
1871  Columns<MT,true,false,SF,CCAs...>::scale( const Other& scalar )
1872 {
1874 
1875  for( size_t j=0UL; j<columns(); ++j ) {
1876  const Iterator last( end(j) );
1877  for( Iterator element=begin(j); element!=last; ++element )
1878  element->value() *= scalar;
1879  }
1880 
1881  return *this;
1882 }
1884 //*************************************************************************************************
1885 
1886 
1887 
1888 
1889 //=================================================================================================
1890 //
1891 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1892 //
1893 //=================================================================================================
1894 
1895 //*************************************************************************************************
1906 template< typename MT // Type of the sparse matrix
1907  , bool SF // Symmetry flag
1908  , size_t... CCAs > // Compile time column arguments
1909 template< typename Other > // Data type of the foreign expression
1910 inline bool Columns<MT,true,false,SF,CCAs...>::canAlias( const Other* alias ) const noexcept
1911 {
1912  return matrix_.isAliased( alias );
1913 }
1915 //*************************************************************************************************
1916 
1917 
1918 //*************************************************************************************************
1929 template< typename MT // Type of the sparse matrix
1930  , bool SF // Symmetry flag
1931  , size_t... CCAs > // Compile time column arguments
1932 template< typename Other > // Data type of the foreign expression
1933 inline bool Columns<MT,true,false,SF,CCAs...>::isAliased( const Other* alias ) const noexcept
1934 {
1935  return matrix_.isAliased( alias );
1936 }
1938 //*************************************************************************************************
1939 
1940 
1941 //*************************************************************************************************
1952 template< typename MT // Type of the sparse matrix
1953  , bool SF // Symmetry flag
1954  , size_t... CCAs > // Compile time column arguments
1955 inline bool Columns<MT,true,false,SF,CCAs...>::canSMPAssign() const noexcept
1956 {
1957  return false;
1958 }
1960 //*************************************************************************************************
1961 
1962 
1963 //*************************************************************************************************
1975 template< typename MT // Type of the sparse matrix
1976  , bool SF // Symmetry flag
1977  , size_t... CCAs > // Compile time column arguments
1978 template< typename MT2 // Type of the right-hand side dense matrix
1979  , bool SO > // Storage order of the right-hand side dense matrix
1980 inline void Columns<MT,true,false,SF,CCAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
1981 {
1984 
1985  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
1986  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
1987  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
1988 
1989  for( size_t j=0UL; j<columns(); ++j )
1990  {
1991  const size_t index( idx(j) );
1992  size_t remaining( matrix_.capacity( index ) );
1993 
1994  for( size_t i=0UL; i<rows(); ++i )
1995  {
1996  if( remaining == 0UL ) {
1997  matrix_.reserve( index, extendCapacity( j ) );
1998  remaining = matrix_.capacity( index ) - matrix_.nonZeros( index );
1999  }
2000 
2001  matrix_.append( i, index, (~rhs)(i,j), true );
2002  --remaining;
2003  }
2004  }
2005 }
2007 //*************************************************************************************************
2008 
2009 
2010 //*************************************************************************************************
2022 template< typename MT // Type of the sparse matrix
2023  , bool SF // Symmetry flag
2024  , size_t... CCAs > // Compile time column arguments
2025 template< typename MT2 > // Type of the right-hand side sparse matrix
2026 inline void Columns<MT,true,false,SF,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2027 {
2030 
2031  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2032  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2033  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2034 
2035  for( size_t j=0UL; j<columns(); ++j )
2036  {
2037  const size_t index( idx(j) );
2038  size_t remaining( matrix_.capacity( index ) );
2039 
2040  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2041  {
2042  if( remaining == 0UL ) {
2043  matrix_.reserve( index, extendCapacity( j ) );
2044  remaining = matrix_.capacity( index ) - matrix_.nonZeros( index );
2045  }
2046 
2047  matrix_.append( element->index(), index, element->value(), true );
2048  --remaining;
2049  }
2050  }
2051 }
2053 //*************************************************************************************************
2054 
2055 
2056 //*************************************************************************************************
2068 template< typename MT // Type of the sparse matrix
2069  , bool SF // Symmetry flag
2070  , size_t... CCAs > // Compile time column arguments
2071 template< typename MT2 > // Type of the right-hand side sparse matrix
2072 inline void Columns<MT,true,false,SF,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2073 {
2076 
2078 
2079  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2080  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2081  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2082 
2083  using RhsIterator = ConstIterator_<MT2>;
2084 
2085  // Counting the number of elements per column
2086  std::vector<size_t> columnLengths( columns(), 0UL );
2087  for( size_t i=0UL; i<rows(); ++i ) {
2088  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2089  ++columnLengths[element->index()];
2090  }
2091 
2092  // Resizing the sparse matrix
2093  for( size_t j=0UL; j<columns(); ++j ) {
2094  reserve( j, columnLengths[j] );
2095  }
2096 
2097  // Appending the elements to the columns of the sparse column selection
2098  for( size_t i=0UL; i<rows(); ++i ) {
2099  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2100  append( i, element->index(), element->value(), true );
2101  }
2102 }
2104 //*************************************************************************************************
2105 
2106 
2107 //*************************************************************************************************
2119 template< typename MT // Type of the sparse matrix
2120  , bool SF // Symmetry flag
2121  , size_t... CCAs > // Compile time column arguments
2122 template< typename MT2 // Type of the right-hand side matrix
2123  , bool SO > // Storage order of the right-hand side matrix
2124 inline void Columns<MT,true,false,SF,CCAs...>::addAssign( const Matrix<MT2,SO>& rhs )
2125 {
2128 
2129  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
2130 
2132 
2133  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2134  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2135 
2136  const AddType tmp( serial( *this + (~rhs) ) );
2137  reset();
2138  assign( tmp );
2139 }
2141 //*************************************************************************************************
2142 
2143 
2144 //*************************************************************************************************
2156 template< typename MT // Type of the sparse matrix
2157  , bool SF // Symmetry flag
2158  , size_t... CCAs > // Compile time column arguments
2159 template< typename MT2 // Type of the right-hand side matrix
2160  , bool SO > // Storage order of the right-hand side matrix
2161 inline void Columns<MT,true,false,SF,CCAs...>::subAssign( const Matrix<MT2,SO>& rhs )
2162 {
2165 
2166  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
2167 
2169 
2170  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2171  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2172 
2173  const SubType tmp( serial( *this - (~rhs) ) );
2174  reset();
2175  assign( tmp );
2176 }
2178 //*************************************************************************************************
2179 
2180 
2181 //*************************************************************************************************
2193 template< typename MT // Type of the sparse matrix
2194  , bool SF // Symmetry flag
2195  , size_t... CCAs > // Compile time column arguments
2196 template< typename MT2 // Type of the right-hand side matrix
2197  , bool SO > // Storage order of the right-hand side matrix
2198 inline void Columns<MT,true,false,SF,CCAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
2199 {
2202 
2203  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
2204 
2207 
2208  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2209  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2210 
2211  const SchurType tmp( serial( *this % (~rhs) ) );
2212  reset();
2213  assign( tmp );
2214 }
2216 //*************************************************************************************************
2217 
2218 
2219 
2220 
2221 
2222 
2223 
2224 
2225 //=================================================================================================
2226 //
2227 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR SPARSE MATRICES
2228 //
2229 //=================================================================================================
2230 
2231 //*************************************************************************************************
2239 template< typename MT // Type of the sparse matrix
2240  , size_t... CCAs > // Compile time column arguments
2241 class Columns<MT,false,false,false,CCAs...>
2242  : public View< SparseMatrix< Columns<MT,false,false,false,CCAs...>, true > >
2243  , private ColumnsData<CCAs...>
2244 {
2245  private:
2246  //**Type definitions****************************************************************************
2247  using DataType = ColumnsData<CCAs...>;
2248  using Operand = If_< IsExpression<MT>, MT, MT& >;
2249  //**********************************************************************************************
2250 
2251  public:
2252  //**Type definitions****************************************************************************
2254  using This = Columns<MT,false,false,false,CCAs...>;
2255 
2256  using BaseType = SparseMatrix<This,true>;
2257  using ViewedType = MT;
2258  using ResultType = ColumnsTrait_<MT,CCAs...>;
2259  using OppositeType = OppositeType_<ResultType>;
2260  using TransposeType = TransposeType_<ResultType>;
2261  using ElementType = ElementType_<MT>;
2262  using ReturnType = ReturnType_<MT>;
2263  using CompositeType = const Columns&;
2264 
2266  using ConstReference = ConstReference_<MT>;
2267 
2269  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
2270  //**********************************************************************************************
2271 
2272  //**ColumnsElement class definition*************************************************************
2275  template< typename MatrixType // Type of the sparse matrix
2276  , typename IteratorType > // Type of the sparse matrix iterator
2277  class ColumnsElement
2278  : private SparseElement
2279  {
2280  public:
2281  //**Constructor******************************************************************************
2287  inline ColumnsElement( IteratorType pos, size_t row )
2288  : pos_( pos ) // Iterator to the current position of the sparse column element
2289  , row_( row ) // Index of the according row
2290  {}
2291  //*******************************************************************************************
2292 
2293  //**Assignment operator**********************************************************************
2299  template< typename T > inline ColumnsElement& operator=( const T& v ) {
2300  *pos_ = v;
2301  return *this;
2302  }
2303  //*******************************************************************************************
2304 
2305  //**Addition assignment operator*************************************************************
2311  template< typename T > inline ColumnsElement& operator+=( const T& v ) {
2312  *pos_ += v;
2313  return *this;
2314  }
2315  //*******************************************************************************************
2316 
2317  //**Subtraction assignment operator**********************************************************
2323  template< typename T > inline ColumnsElement& operator-=( const T& v ) {
2324  *pos_ -= v;
2325  return *this;
2326  }
2327  //*******************************************************************************************
2328 
2329  //**Multiplication assignment operator*******************************************************
2335  template< typename T > inline ColumnsElement& operator*=( const T& v ) {
2336  *pos_ *= v;
2337  return *this;
2338  }
2339  //*******************************************************************************************
2340 
2341  //**Division assignment operator*************************************************************
2347  template< typename T > inline ColumnsElement& operator/=( const T& v ) {
2348  *pos_ /= v;
2349  return *this;
2350  }
2351  //*******************************************************************************************
2352 
2353  //**Element access operator******************************************************************
2358  inline const ColumnsElement* operator->() const {
2359  return this;
2360  }
2361  //*******************************************************************************************
2362 
2363  //**Value function***************************************************************************
2368  inline decltype(auto) value() const {
2369  return pos_->value();
2370  }
2371  //*******************************************************************************************
2372 
2373  //**Index function***************************************************************************
2378  inline size_t index() const {
2379  return row_;
2380  }
2381  //*******************************************************************************************
2382 
2383  private:
2384  //**Member variables*************************************************************************
2385  IteratorType pos_;
2386  size_t row_;
2387  //*******************************************************************************************
2388  };
2389  //**********************************************************************************************
2390 
2391  //**ColumnsIterator class definition************************************************************
2394  template< typename MatrixType // Type of the sparse matrix
2395  , typename IteratorType > // Type of the sparse matrix iterator
2396  class ColumnsIterator
2397  {
2398  public:
2399  //**Type definitions*************************************************************************
2400  using IteratorCategory = std::forward_iterator_tag;
2401  using ValueType = ColumnsElement<MatrixType,IteratorType>;
2402  using PointerType = ValueType;
2403  using ReferenceType = ValueType;
2404  using DifferenceType = ptrdiff_t;
2405 
2406  // STL iterator requirements
2407  using iterator_category = IteratorCategory;
2408  using value_type = ValueType;
2409  using pointer = PointerType;
2410  using reference = ReferenceType;
2411  using difference_type = DifferenceType;
2412  //*******************************************************************************************
2413 
2414  //**Constructor******************************************************************************
2417  inline ColumnsIterator()
2418  : matrix_( nullptr ) // The sparse matrix containing the selected column
2419  , row_ ( 0UL ) // The current row index
2420  , column_( 0UL ) // The current column index
2421  , pos_ () // Iterator to the current sparse element
2422  {}
2423  //*******************************************************************************************
2424 
2425  //**Constructor******************************************************************************
2432  inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column )
2433  : matrix_( &matrix ) // The sparse matrix containing the selected column
2434  , row_ ( row ) // The current row index
2435  , column_( column ) // The current column index
2436  , pos_ () // Iterator to the current sparse element
2437  {
2438  for( ; row_<matrix_->rows(); ++row_ ) {
2439  pos_ = matrix_->find( row_, column_ );
2440  if( pos_ != matrix_->end( row_ ) ) break;
2441  }
2442  }
2443  //*******************************************************************************************
2444 
2445  //**Constructor******************************************************************************
2453  inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column, IteratorType pos )
2454  : matrix_( &matrix ) // The sparse matrix containing the selected column
2455  , row_ ( row ) // The current row index
2456  , column_( column ) // The current column index
2457  , pos_ ( pos ) // Iterator to the current sparse element
2458  {
2459  BLAZE_INTERNAL_ASSERT( matrix.find( row, column ) == pos, "Invalid initial iterator position" );
2460  }
2461  //*******************************************************************************************
2462 
2463  //**Constructor******************************************************************************
2468  template< typename MatrixType2, typename IteratorType2 >
2469  inline ColumnsIterator( const ColumnsIterator<MatrixType2,IteratorType2>& it )
2470  : matrix_( it.matrix_ ) // The sparse matrix containing the selected column
2471  , row_ ( it.row_ ) // The current row index
2472  , column_( it.column_ ) // The current column index
2473  , pos_ ( it.pos_ ) // Iterator to the current sparse element
2474  {}
2475  //*******************************************************************************************
2476 
2477  //**Prefix increment operator****************************************************************
2482  inline ColumnsIterator& operator++() {
2483  ++row_;
2484  for( ; row_<matrix_->rows(); ++row_ ) {
2485  pos_ = matrix_->find( row_, column_ );
2486  if( pos_ != matrix_->end( row_ ) ) break;
2487  }
2488 
2489  return *this;
2490  }
2491  //*******************************************************************************************
2492 
2493  //**Postfix increment operator***************************************************************
2498  inline const ColumnsIterator operator++( int ) {
2499  const ColumnsIterator tmp( *this );
2500  ++(*this);
2501  return tmp;
2502  }
2503  //*******************************************************************************************
2504 
2505  //**Element access operator******************************************************************
2510  inline ReferenceType operator*() const {
2511  return ReferenceType( pos_, row_ );
2512  }
2513  //*******************************************************************************************
2514 
2515  //**Element access operator******************************************************************
2520  inline PointerType operator->() const {
2521  return PointerType( pos_, row_ );
2522  }
2523  //*******************************************************************************************
2524 
2525  //**Equality operator************************************************************************
2531  template< typename MatrixType2, typename IteratorType2 >
2532  inline bool operator==( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2533  return row_ == rhs.row_;
2534  }
2535  //*******************************************************************************************
2536 
2537  //**Inequality operator**********************************************************************
2543  template< typename MatrixType2, typename IteratorType2 >
2544  inline bool operator!=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2545  return !( *this == rhs );
2546  }
2547  //*******************************************************************************************
2548 
2549  //**Subtraction operator*********************************************************************
2555  inline DifferenceType operator-( const ColumnsIterator& rhs ) const {
2556  size_t counter( 0UL );
2557  for( size_t i=rhs.row_; i<row_; ++i ) {
2558  if( matrix_->find( i, column_ ) != matrix_->end( i ) )
2559  ++counter;
2560  }
2561  return counter;
2562  }
2563  //*******************************************************************************************
2564 
2565  private:
2566  //**Member variables*************************************************************************
2567  MatrixType* matrix_;
2568  size_t row_;
2569  size_t column_;
2570  IteratorType pos_;
2571  //*******************************************************************************************
2572 
2573  //**Friend declarations**********************************************************************
2574  template< typename MatrixType2, typename IteratorType2 > friend class ColumnsIterator;
2575  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Columns;
2576  //*******************************************************************************************
2577  };
2578  //**********************************************************************************************
2579 
2580  //**Type definitions****************************************************************************
2582  using ConstIterator = ColumnsIterator< const MT, ConstIterator_<MT> >;
2583 
2585  using Iterator = If_< IsConst<MT>, ConstIterator, ColumnsIterator< MT, Iterator_<MT> > >;
2586  //**********************************************************************************************
2587 
2588  //**Compilation flags***************************************************************************
2590  enum : bool { smpAssignable = MT::smpAssignable };
2591  //**********************************************************************************************
2592 
2593  //**Constructors********************************************************************************
2596  template< typename... RCAs >
2597  explicit inline Columns( MT& matrix, RCAs... args );
2598 
2599  inline Columns( const Columns& ) = default;
2600  inline Columns( Columns&& ) = default;
2602  //**********************************************************************************************
2603 
2604  //**Destructor**********************************************************************************
2605  // No explicitly declared destructor.
2606  //**********************************************************************************************
2607 
2608  //**Data access functions***********************************************************************
2611  inline Reference operator()( size_t i, size_t j );
2612  inline ConstReference operator()( size_t i, size_t j ) const;
2613  inline Reference at( size_t i, size_t j );
2614  inline ConstReference at( size_t i, size_t j ) const;
2615  inline Iterator begin ( size_t j );
2616  inline ConstIterator begin ( size_t j ) const;
2617  inline ConstIterator cbegin( size_t j ) const;
2618  inline Iterator end ( size_t j );
2619  inline ConstIterator end ( size_t j ) const;
2620  inline ConstIterator cend ( size_t j ) const;
2622  //**********************************************************************************************
2623 
2624  //**Assignment operators************************************************************************
2627  inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
2628  inline Columns& operator=( const Columns& rhs );
2629 
2630  template< typename MT2, bool SO > inline Columns& operator= ( const Matrix<MT2,SO>& rhs );
2631  template< typename MT2, bool SO > inline Columns& operator+=( const Matrix<MT2,SO>& rhs );
2632  template< typename MT2, bool SO > inline Columns& operator-=( const Matrix<MT2,SO>& rhs );
2633  template< typename MT2, bool SO > inline Columns& operator%=( const Matrix<MT2,SO>& rhs );
2635  //**********************************************************************************************
2636 
2637  //**Utility functions***************************************************************************
2640  using DataType::idx;
2641  using DataType::idces;
2642  using DataType::columns;
2643 
2644  inline MT& operand() noexcept;
2645  inline const MT& operand() const noexcept;
2646 
2647  inline size_t rows() const noexcept;
2648  inline size_t capacity() const noexcept;
2649  inline size_t capacity( size_t j ) const noexcept;
2650  inline size_t nonZeros() const;
2651  inline size_t nonZeros( size_t j ) const;
2652  inline void reset();
2653  inline void reset( size_t j );
2654  inline void reserve( size_t nonzeros );
2655  void reserve( size_t j, size_t nonzeros );
2656  inline void trim();
2657  inline void trim( size_t j );
2659  //**********************************************************************************************
2660 
2661  //**Insertion functions*************************************************************************
2664  inline Iterator set ( size_t i, size_t j, const ElementType& value );
2665  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
2666  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
2667  inline void finalize( size_t j );
2669  //**********************************************************************************************
2670 
2671  //**Erase functions*****************************************************************************
2674  inline void erase( size_t i, size_t j );
2675  inline Iterator erase( size_t j, Iterator pos );
2676  inline Iterator erase( size_t j, Iterator first, Iterator last );
2677 
2678  template< typename Pred >
2679  inline void erase( Pred predicate );
2680 
2681  template< typename Pred >
2682  inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
2684  //**********************************************************************************************
2685 
2686  //**Lookup functions****************************************************************************
2689  inline Iterator find ( size_t i, size_t j );
2690  inline ConstIterator find ( size_t i, size_t j ) const;
2691  inline Iterator lowerBound( size_t i, size_t j );
2692  inline ConstIterator lowerBound( size_t i, size_t j ) const;
2693  inline Iterator upperBound( size_t i, size_t j );
2694  inline ConstIterator upperBound( size_t i, size_t j ) const;
2696  //**********************************************************************************************
2697 
2698  //**Numeric functions***************************************************************************
2701  inline Columns& transpose();
2702  inline Columns& ctranspose();
2703 
2704  template< typename Other > inline Columns& scale( const Other& scalar );
2706  //**********************************************************************************************
2707 
2708  //**Expression template evaluation functions****************************************************
2711  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
2712  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
2713 
2714  inline bool canSMPAssign() const noexcept;
2715 
2716  template< typename MT2, bool SO > inline void assign ( const DenseMatrix<MT2,SO>& rhs );
2717  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,false>& rhs );
2718  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,true>& rhs );
2719  template< typename MT2, bool SO > inline void addAssign ( const Matrix<MT2,SO>& rhs );
2720  template< typename MT2, bool SO > inline void subAssign ( const Matrix<MT2,SO>& rhs );
2721  template< typename MT2, bool SO > inline void schurAssign( const Matrix<MT2,SO>& rhs );
2723  //**********************************************************************************************
2724 
2725  private:
2726  //**Member variables****************************************************************************
2729  Operand matrix_;
2730 
2731  //**********************************************************************************************
2732 
2733  //**Compile time checks*************************************************************************
2743  //**********************************************************************************************
2744 };
2746 //*************************************************************************************************
2747 
2748 
2749 
2750 
2751 //=================================================================================================
2752 //
2753 // CONSTRUCTORS
2754 //
2755 //=================================================================================================
2756 
2757 //*************************************************************************************************
2770 template< typename MT // Type of the sparse matrix
2771  , size_t... CCAs > // Compile time column arguments
2772 template< typename... RCAs > // Runtime column arguments
2773 inline Columns<MT,false,false,false,CCAs...>::Columns( MT& matrix, RCAs... args )
2774  : DataType( args... ) // Base class initialization
2775  , matrix_ ( matrix ) // The matrix containing the columns
2776 {
2777  if( !Contains< TypeList<RCAs...>, Unchecked >::value ) {
2778  for( size_t j=0UL; j<columns(); ++j ) {
2779  if( matrix_.columns() <= idx(j) ) {
2780  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2781  }
2782  }
2783  }
2784 }
2786 //*************************************************************************************************
2787 
2788 
2789 
2790 
2791 //=================================================================================================
2792 //
2793 // DATA ACCESS FUNCTIONS
2794 //
2795 //=================================================================================================
2796 
2797 //*************************************************************************************************
2808 template< typename MT // Type of the sparse matrix
2809  , size_t... CCAs > // Compile time column arguments
2810 inline typename Columns<MT,false,false,false,CCAs...>::Reference
2811  Columns<MT,false,false,false,CCAs...>::operator()( size_t i, size_t j )
2812 {
2813  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2814  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2815 
2816  return matrix_(i,idx(j));
2817 }
2819 //*************************************************************************************************
2820 
2821 
2822 //*************************************************************************************************
2833 template< typename MT // Type of the sparse matrix
2834  , size_t... CCAs > // Compile time column arguments
2835 inline typename Columns<MT,false,false,false,CCAs...>::ConstReference
2836  Columns<MT,false,false,false,CCAs...>::operator()( size_t i, size_t j ) const
2837 {
2838  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
2839  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2840 
2841  return const_cast<const MT&>( matrix_ )(i,idx(j));
2842 }
2844 //*************************************************************************************************
2845 
2846 
2847 //*************************************************************************************************
2859 template< typename MT // Type of the sparse matrix
2860  , size_t... CCAs > // Compile time column arguments
2861 inline typename Columns<MT,false,false,false,CCAs...>::Reference
2862  Columns<MT,false,false,false,CCAs...>::at( size_t i, size_t j )
2863 {
2864  if( i >= rows() ) {
2865  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2866  }
2867  if( j >= columns() ) {
2868  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2869  }
2870  return (*this)(i,j);
2871 }
2873 //*************************************************************************************************
2874 
2875 
2876 //*************************************************************************************************
2888 template< typename MT // Type of the sparse matrix
2889  , size_t... CCAs > // Compile time column arguments
2890 inline typename Columns<MT,false,false,false,CCAs...>::ConstReference
2891  Columns<MT,false,false,false,CCAs...>::at( size_t i, size_t j ) const
2892 {
2893  if( i >= rows() ) {
2894  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2895  }
2896  if( j >= columns() ) {
2897  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2898  }
2899  return (*this)(i,j);
2900 }
2902 //*************************************************************************************************
2903 
2904 
2905 //*************************************************************************************************
2914 template< typename MT // Type of the sparse matrix
2915  , size_t... CCAs > // Compile time column arguments
2916 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
2918 {
2919  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2920 
2921  return Iterator( matrix_, 0UL, idx(j) );
2922 }
2924 //*************************************************************************************************
2925 
2926 
2927 //*************************************************************************************************
2936 template< typename MT // Type of the sparse matrix
2937  , size_t... CCAs > // Compile time column arguments
2938 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
2940 {
2941  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2942 
2943  return ConstIterator( matrix_, 0UL, idx(j) );
2944 }
2946 //*************************************************************************************************
2947 
2948 
2949 //*************************************************************************************************
2958 template< typename MT // Type of the sparse matrix
2959  , size_t... CCAs > // Compile time column arguments
2960 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
2962 {
2963  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
2964 
2965  return ConstIterator( matrix_, 0UL, idx(j) );
2966 }
2968 //*************************************************************************************************
2969 
2970 
2971 //*************************************************************************************************
2980 template< typename MT // Type of the sparse matrix
2981  , size_t... CCAs > // Compile time column arguments
2982 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
2984 {
2985  BLAZE_USER_ASSERT( j < columns(), "Invalid row access index" );
2986 
2987  return Iterator( matrix_, rows(), idx(j) );
2988 }
2990 //*************************************************************************************************
2991 
2992 
2993 //*************************************************************************************************
3002 template< typename MT // Type of the sparse matrix
3003  , size_t... CCAs > // Compile time column arguments
3004 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
3006 {
3007  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3008 
3009  return ConstIterator( matrix_, rows(), idx(j) );
3010 }
3012 //*************************************************************************************************
3013 
3014 
3015 //*************************************************************************************************
3024 template< typename MT // Type of the sparse matrix
3025  , size_t... CCAs > // Compile time column arguments
3026 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
3028 {
3029  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3030 
3031  return ConstIterator( matrix_, rows(), idx(j) );
3032 }
3034 //*************************************************************************************************
3035 
3036 
3037 
3038 
3039 //=================================================================================================
3040 //
3041 // ASSIGNMENT OPERATORS
3042 //
3043 //=================================================================================================
3044 
3045 //*************************************************************************************************
3061 template< typename MT // Type of the sparse matrix
3062  , size_t... CCAs > // Compile time column arguments
3063 inline Columns<MT,false,false,false,CCAs...>&
3064  Columns<MT,false,false,false,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
3065 {
3068 
3069  if( list.size() != rows() ) {
3070  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
3071  }
3072 
3073  const InitializerMatrix<ElementType> tmp( list, columns() );
3074 
3075  if( IsRestricted<MT>::value ) {
3076  for( size_t j=0UL; j<columns(); ++j ) {
3077  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, j ) ) {
3078  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3079  }
3080  }
3081  }
3082 
3083  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3084 
3085  smpAssign( left, tmp );
3086 
3087  return *this;
3088 }
3090 //*************************************************************************************************
3091 
3092 
3093 //*************************************************************************************************
3108 template< typename MT // Type of the sparse matrix
3109  , size_t... CCAs > // Compile time column arguments
3110 inline Columns<MT,false,false,false,CCAs...>&
3111  Columns<MT,false,false,false,CCAs...>::operator=( const Columns& rhs )
3112 {
3115 
3118 
3119  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && idces() == rhs.idces() ) )
3120  return *this;
3121 
3122  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
3123  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3124  }
3125 
3126  if( IsRestricted<MT>::value ) {
3127  for( size_t j=0UL; j<columns(); ++j ) {
3128  if( !tryAssign( matrix_, column( rhs, j, unchecked ), 0UL, idx(j) ) ) {
3129  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3130  }
3131  }
3132  }
3133 
3134  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3135 
3136  if( rhs.canAlias( &matrix_ ) ) {
3137  const ResultType tmp( rhs );
3138  left.reset();
3139  smpAssign( left, tmp );
3140  }
3141  else {
3142  left.reset();
3143  smpAssign( left, rhs );
3144  }
3145 
3146  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3147 
3148  return *this;
3149 }
3151 //*************************************************************************************************
3152 
3153 
3154 //*************************************************************************************************
3169 template< typename MT // Type of the sparse matrix
3170  , size_t... CCAs > // Compile time column arguments
3171 template< typename MT2 // Type of the right-hand side matrix
3172  , bool SO > // Storage order of the right-hand side matrix
3173 inline Columns<MT,false,false,false,CCAs...>&
3174  Columns<MT,false,false,false,CCAs...>::operator=( const Matrix<MT2,SO>& rhs )
3175 {
3178 
3180 
3181  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3182  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3183  }
3184 
3185  using Right = CompositeType_<MT2>;
3186  Right right( ~rhs );
3187 
3188  if( IsRestricted<MT>::value ) {
3189  for( size_t j=0UL; j<columns(); ++j ) {
3190  if( !tryAssign( matrix_, column( right, j, unchecked ), 0UL, idx(j) ) ) {
3191  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3192  }
3193  }
3194  }
3195 
3196  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3197 
3198  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3199  const ResultType_<MT2> tmp( right );
3200  if( IsSparseMatrix< ResultType_<MT2> >::value )
3201  left.reset();
3202  smpAssign( left, tmp );
3203  }
3204  else {
3205  if( IsSparseMatrix<MT2>::value )
3206  left.reset();
3207  smpAssign( left, right );
3208  }
3209 
3210  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3211 
3212  return *this;
3213 }
3215 //*************************************************************************************************
3216 
3217 
3218 //*************************************************************************************************
3232 template< typename MT // Type of the sparse matrix
3233  , size_t... CCAs > // Compile time column arguments
3234 template< typename MT2 // Type of the right-hand side matrix
3235  , bool SO > // Storage order of the right-hand side matrix
3236 inline Columns<MT,false,false,false,CCAs...>&
3237  Columns<MT,false,false,false,CCAs...>::operator+=( const Matrix<MT2,SO>& rhs )
3238 {
3241 
3245 
3246  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
3247 
3249 
3250  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3251  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3252  }
3253 
3254  const AddType tmp( *this + (~rhs) );
3255 
3256  if( IsRestricted<MT>::value ) {
3257  for( size_t j=0UL; j<columns(); ++j ) {
3258  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
3259  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3260  }
3261  }
3262  }
3263 
3264  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3265 
3266  if( IsSparseMatrix<AddType>::value ) {
3267  left.reset();
3268  }
3269 
3270  smpAssign( left, tmp );
3271 
3272  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3273 
3274  return *this;
3275 }
3277 //*************************************************************************************************
3278 
3279 
3280 //*************************************************************************************************
3294 template< typename MT // Type of the sparse matrix
3295  , size_t... CCAs > // Compile time column arguments
3296 template< typename MT2 // Type of the right-hand side matrix
3297  , bool SO > // Storage order of the right-hand side matrix
3298 inline Columns<MT,false,false,false,CCAs...>&
3299  Columns<MT,false,false,false,CCAs...>::operator-=( const Matrix<MT2,SO>& rhs )
3300 {
3303 
3307 
3308  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
3309 
3311 
3312  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3313  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3314  }
3315 
3316  const SubType tmp( *this - (~rhs) );
3317 
3318  if( IsRestricted<MT>::value ) {
3319  for( size_t j=0UL; j<columns(); ++j ) {
3320  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
3321  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3322  }
3323  }
3324  }
3325 
3326  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3327 
3328  if( IsSparseMatrix<SubType>::value ) {
3329  left.reset();
3330  }
3331 
3332  smpAssign( left, tmp );
3333 
3334  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3335 
3336  return *this;
3337 }
3339 //*************************************************************************************************
3340 
3341 
3342 //*************************************************************************************************
3356 template< typename MT // Type of the sparse matrix
3357  , size_t... CCAs > // Compile time column arguments
3358 template< typename MT2 // Type of the right-hand side matrix
3359  , bool SO > // Storage order of the right-hand side matrix
3360 inline Columns<MT,false,false,false,CCAs...>&
3361  Columns<MT,false,false,false,CCAs...>::operator%=( const Matrix<MT2,SO>& rhs )
3362 {
3365 
3369 
3370  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
3371 
3373 
3374  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
3375  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
3376  }
3377 
3378  const SchurType tmp( *this % (~rhs) );
3379 
3380  if( IsRestricted<MT>::value ) {
3381  for( size_t j=0UL; j<columns(); ++j ) {
3382  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
3383  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3384  }
3385  }
3386  }
3387 
3388  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
3389 
3390  if( IsSparseMatrix<SchurType>::value ) {
3391  left.reset();
3392  }
3393 
3394  smpAssign( left, tmp );
3395 
3396  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3397 
3398  return *this;
3399 }
3401 //*************************************************************************************************
3402 
3403 
3404 
3405 
3406 //=================================================================================================
3407 //
3408 // UTILITY FUNCTIONS
3409 //
3410 //=================================================================================================
3411 
3412 //*************************************************************************************************
3418 template< typename MT // Type of the sparse matrix
3419  , size_t... CCAs > // Compile time column arguments
3420 inline MT& Columns<MT,false,false,false,CCAs...>::operand() noexcept
3421 {
3422  return matrix_;
3423 }
3425 //*************************************************************************************************
3426 
3427 
3428 //*************************************************************************************************
3434 template< typename MT // Type of the sparse matrix
3435  , size_t... CCAs > // Compile time column arguments
3436 inline const MT& Columns<MT,false,false,false,CCAs...>::operand() const noexcept
3437 {
3438  return matrix_;
3439 }
3441 //*************************************************************************************************
3442 
3443 
3444 //*************************************************************************************************
3450 template< typename MT // Type of the sparse matrix
3451  , size_t... CCAs > // Compile time column arguments
3452 inline size_t Columns<MT,false,false,false,CCAs...>::rows() const noexcept
3453 {
3454  return matrix_.rows();
3455 }
3457 //*************************************************************************************************
3458 
3459 
3460 //*************************************************************************************************
3466 template< typename MT // Type of the sparse matrix
3467  , size_t... CCAs > // Compile time column arguments
3468 inline size_t Columns<MT,false,false,false,CCAs...>::capacity() const noexcept
3469 {
3470  return rows() * columns();
3471 }
3473 //*************************************************************************************************
3474 
3475 
3476 //*************************************************************************************************
3485 template< typename MT // Type of the sparse matrix
3486  , size_t... CCAs > // Compile time column arguments
3487 inline size_t Columns<MT,false,false,false,CCAs...>::capacity( size_t j ) const noexcept
3488 {
3489  UNUSED_PARAMETER( j );
3490 
3491  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3492 
3493  return rows();
3494 }
3496 //*************************************************************************************************
3497 
3498 
3499 //*************************************************************************************************
3505 template< typename MT // Type of the sparse matrix
3506  , size_t... CCAs > // Compile time column arguments
3508 {
3509  size_t nonzeros( 0UL );
3510 
3511  for( size_t i=0UL; i<rows(); ++i ) {
3512  const auto end( matrix_.end( i ) );
3513  for( size_t j=0UL; j<columns(); ++j ) {
3514  auto pos = matrix_.find( i, idx(j) );
3515  if( pos != end ) {
3516  ++nonzeros;
3517  }
3518  }
3519  }
3520 
3521  return nonzeros;
3522 }
3524 //*************************************************************************************************
3525 
3526 
3527 //*************************************************************************************************
3536 template< typename MT // Type of the sparse matrix
3537  , size_t... CCAs > // Compile time column arguments
3538 inline size_t Columns<MT,false,false,false,CCAs...>::nonZeros( size_t j ) const
3539 {
3540  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3541 
3542  size_t counter( 0UL );
3543 
3544  const ConstIterator last( end(j) );
3545  for( ConstIterator element=begin(j); element!=last; ++element ) {
3546  ++counter;
3547  }
3548 
3549  return counter;
3550 }
3552 //*************************************************************************************************
3553 
3554 
3555 //*************************************************************************************************
3561 template< typename MT // Type of the sparse matrix
3562  , size_t... CCAs > // Compile time column arguments
3564 {
3565  for( size_t j=0UL; j<columns(); ++j ) {
3566  reset( j );
3567  }
3568 }
3570 //*************************************************************************************************
3571 
3572 
3573 //*************************************************************************************************
3583 template< typename MT // Type of the sparse matrix
3584  , size_t... CCAs > // Compile time column arguments
3585 inline void Columns<MT,false,false,false,CCAs...>::reset( size_t j )
3586 {
3587  const size_t index( idx(j) );
3588 
3589  const size_t ibegin( ( IsLower<MT>::value )
3590  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3591  ?( index+1UL )
3592  :( index ) )
3593  :( 0UL ) );
3594  const size_t iend ( ( IsUpper<MT>::value )
3595  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3596  ?( index )
3597  :( index+1UL ) )
3598  :( rows() ) );
3599 
3600  for( size_t i=ibegin; i<iend; ++i ) {
3601  matrix_.erase( i, index );
3602  }
3603 }
3605 //*************************************************************************************************
3606 
3607 
3608 //*************************************************************************************************
3619 template< typename MT // Type of the sparse matrix
3620  , size_t... CCAs > // Compile time column arguments
3621 inline void Columns<MT,false,false,false,CCAs...>::reserve( size_t nonzeros )
3622 {
3623  UNUSED_PARAMETER( nonzeros );
3624 
3625  return;
3626 }
3628 //*************************************************************************************************
3629 
3630 
3631 //*************************************************************************************************
3644 template< typename MT // Type of the sparse matrix
3645  , size_t... CCAs > // Compile time column arguments
3646 void Columns<MT,false,false,false,CCAs...>::reserve( size_t j, size_t nonzeros )
3647 {
3648  UNUSED_PARAMETER( j, nonzeros );
3649 
3650  return;
3651 }
3653 //*************************************************************************************************
3654 
3655 
3656 //*************************************************************************************************
3666 template< typename MT // Type of the sparse matrix
3667  , size_t... CCAs > // Compile time column arguments
3668 void Columns<MT,false,false,false,CCAs...>::trim()
3669 {
3670  return;
3671 }
3673 //*************************************************************************************************
3674 
3675 
3676 //*************************************************************************************************
3687 template< typename MT // Type of the sparse matrix
3688  , size_t... CCAs > // Compile time column arguments
3689 void Columns<MT,false,false,false,CCAs...>::trim( size_t j )
3690 {
3691  UNUSED_PARAMETER( j );
3692 
3693  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3694 
3695  return;
3696 }
3698 //*************************************************************************************************
3699 
3700 
3701 
3702 
3703 //=================================================================================================
3704 //
3705 // INSERTION FUNCTIONS
3706 //
3707 //=================================================================================================
3708 
3709 //*************************************************************************************************
3722 template< typename MT // Type of the sparse matrix
3723  , size_t... CCAs > // Compile time column arguments
3724 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3725  Columns<MT,false,false,false,CCAs...>::set( size_t i, size_t j, const ElementType& value )
3726 {
3727  return Iterator( matrix_, i, idx(j), matrix_.set( i, idx(j), value ) );
3728 }
3730 //*************************************************************************************************
3731 
3732 
3733 //*************************************************************************************************
3747 template< typename MT // Type of the sparse matrix
3748  , size_t... CCAs > // Compile time column arguments
3749 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3750  Columns<MT,false,false,false,CCAs...>::insert( size_t i, size_t j, const ElementType& value )
3751 {
3752  return Iterator( matrix_, i, idx(j), matrix_.insert( i, idx(j), value ) );
3753 }
3755 //*************************************************************************************************
3756 
3757 
3758 //*************************************************************************************************
3802 template< typename MT // Type of the sparse matrix
3803  , size_t... CCAs > // Compile time column arguments
3804 inline void Columns<MT,false,false,false,CCAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
3805 {
3806  if( !check || !isDefault<strict>( value ) )
3807  matrix_.insert( i, idx(j), value );
3808 }
3810 //*************************************************************************************************
3811 
3812 
3813 //*************************************************************************************************
3827 template< typename MT // Type of the sparse matrix
3828  , size_t... CCAs > // Compile time column arguments
3829 inline void Columns<MT,false,false,false,CCAs...>::finalize( size_t j )
3830 {
3831  UNUSED_PARAMETER( j );
3832 
3833  return;
3834 }
3836 //*************************************************************************************************
3837 
3838 
3839 
3840 
3841 //=================================================================================================
3842 //
3843 // ERASE FUNCTIONS
3844 //
3845 //=================================================================================================
3846 
3847 //*************************************************************************************************
3857 template< typename MT // Type of the sparse matrix
3858  , size_t... CCAs > // Compile time column arguments
3859 inline void Columns<MT,false,false,false,CCAs...>::erase( size_t i, size_t j )
3860 {
3861  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3862  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3863 
3864  matrix_.erase( i, idx(j) );
3865 }
3867 //*************************************************************************************************
3868 
3869 
3870 //*************************************************************************************************
3880 template< typename MT // Type of the sparse matrix
3881  , size_t... CCAs > // Compile time column arguments
3882 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3883  Columns<MT,false,false,false,CCAs...>::erase( size_t j, Iterator pos )
3884 {
3885  const size_t row( pos.row_ );
3886 
3887  if( row == rows() )
3888  return pos;
3889 
3890  matrix_.erase( row, pos.pos_ );
3891  return Iterator( matrix_, row+1UL, idx(j) );
3892 }
3894 //*************************************************************************************************
3895 
3896 
3897 //*************************************************************************************************
3908 template< typename MT // Type of the sparse matrix
3909  , size_t... CCAs > // Compile time column arguments
3910 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
3911  Columns<MT,false,false,false,CCAs...>::erase( size_t j, Iterator first, Iterator last )
3912 {
3913  UNUSED_PARAMETER( j );
3914 
3915  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3916 
3917  for( ; first!=last; ++first ) {
3918  matrix_.erase( first.row_, first.pos_ );
3919  }
3920 
3921  return last;
3922 }
3924 //*************************************************************************************************
3925 
3926 
3927 //*************************************************************************************************
3950 template< typename MT // Type of the sparse matrix
3951  , size_t... CCAs > // Compile time column arguments
3952 template< typename Pred > // Type of the unary predicate
3953 inline void Columns<MT,false,false,false,CCAs...>::erase( Pred predicate )
3954 {
3955  for( size_t j=0UL; j<columns(); ++j ) {
3956  for( Iterator element=begin(j); element!=end(j); ++element ) {
3957  if( predicate( element->value() ) )
3958  matrix_.erase( element.row_, element.pos_ );
3959  }
3960  }
3961 }
3963 //*************************************************************************************************
3964 
3965 
3966 //*************************************************************************************************
3993 template< typename MT // Type of the sparse matrix
3994  , size_t... CCAs > // Compile time column arguments
3995 template< typename Pred > // Type of the unary predicate
3996 inline void Columns<MT,false,false,false,CCAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
3997 {
3998  UNUSED_PARAMETER( j );
3999 
4000  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4001 
4002  for( ; first!=last; ++first ) {
4003  if( predicate( first->value() ) )
4004  matrix_.erase( first.row_, first.pos_ );
4005  }
4006 }
4008 //*************************************************************************************************
4009 
4010 
4011 
4012 
4013 //=================================================================================================
4014 //
4015 // LOOKUP FUNCTIONS
4016 //
4017 //=================================================================================================
4018 
4019 //*************************************************************************************************
4034 template< typename MT // Type of the sparse matrix
4035  , size_t... CCAs > // Compile time column arguments
4036 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
4037  Columns<MT,false,false,false,CCAs...>::find( size_t i, size_t j )
4038 {
4039  const size_t index( idx(j) );
4040  const Iterator_<MT> pos( matrix_.find( i, index ) );
4041 
4042  if( pos != matrix_.end( i ) )
4043  return Iterator( matrix_, i, index, pos );
4044  else
4045  return end( j );
4046 }
4048 //*************************************************************************************************
4049 
4050 
4051 //*************************************************************************************************
4066 template< typename MT // Type of the sparse matrix
4067  , size_t... CCAs > // Compile time column arguments
4068 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
4069  Columns<MT,false,false,false,CCAs...>::find( size_t i, size_t j ) const
4070 {
4071  const size_t index( idx(j) );
4072  const ConstIterator_<MT> pos( matrix_.find( i, index ) );
4073 
4074  if( pos != matrix_.end( i ) )
4075  return ConstIterator( matrix_, i, index, pos );
4076  else
4077  return end( j );
4078 }
4080 //*************************************************************************************************
4081 
4082 
4083 //*************************************************************************************************
4097 template< typename MT // Type of the sparse matrix
4098  , size_t... CCAs > // Compile time column arguments
4099 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
4100  Columns<MT,false,false,false,CCAs...>::lowerBound( size_t i, size_t j )
4101 {
4102  const size_t index( idx(j) );
4103 
4104  for( ; i<rows(); ++i )
4105  {
4106  const Iterator_<MT> pos( matrix_.find( i, index ) );
4107 
4108  if( pos != matrix_.end( i ) )
4109  return Iterator( matrix_, i, index, pos );
4110  }
4111 
4112  return end( j );
4113 }
4115 //*************************************************************************************************
4116 
4117 
4118 //*************************************************************************************************
4132 template< typename MT // Type of the sparse matrix
4133  , size_t... CCAs > // Compile time column arguments
4134 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
4135  Columns<MT,false,false,false,CCAs...>::lowerBound( size_t i, size_t j ) const
4136 {
4137  const size_t index( idx(j) );
4138 
4139  for( ; i<rows(); ++i )
4140  {
4141  const ConstIterator_<MT> pos( matrix_.find( i, index ) );
4142 
4143  if( pos != matrix_.end( i ) )
4144  return ConstIterator( matrix_, i, index, pos );
4145  }
4146 
4147  return end( j );
4148 }
4150 //*************************************************************************************************
4151 
4152 
4153 //*************************************************************************************************
4167 template< typename MT // Type of the sparse matrix
4168  , size_t... CCAs > // Compile time column arguments
4169 inline typename Columns<MT,false,false,false,CCAs...>::Iterator
4170  Columns<MT,false,false,false,CCAs...>::upperBound( size_t i, size_t j )
4171 {
4172  return lowerBound( i+1UL, j );
4173 }
4175 //*************************************************************************************************
4176 
4177 
4178 //*************************************************************************************************
4192 template< typename MT // Type of the sparse matrix
4193  , size_t... CCAs > // Compile time column arguments
4194 inline typename Columns<MT,false,false,false,CCAs...>::ConstIterator
4195  Columns<MT,false,false,false,CCAs...>::upperBound( size_t i, size_t j ) const
4196 {
4197  return lowerBound( i+1UL, j );
4198 }
4200 //*************************************************************************************************
4201 
4202 
4203 
4204 
4205 //=================================================================================================
4206 //
4207 // NUMERIC FUNCTIONS
4208 //
4209 //=================================================================================================
4210 
4211 //*************************************************************************************************
4224 template< typename MT // Type of the sparse matrix
4225  , size_t... CCAs > // Compile time column arguments
4226 inline Columns<MT,false,false,false,CCAs...>&
4228 {
4231 
4232  if( rows() != columns() ) {
4233  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4234  }
4235 
4236  const ResultType tmp( trans( *this ) );
4237 
4238  if( IsRestricted<MT>::value ) {
4239  for( size_t j=0UL; j<columns(); ++j ) {
4240  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
4241  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4242  }
4243  }
4244  }
4245 
4246  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4247 
4248  left.reset();
4249  smpAssign( left, tmp );
4250 
4251  return *this;
4252 }
4254 //*************************************************************************************************
4255 
4256 
4257 //*************************************************************************************************
4270 template< typename MT // Type of the sparse matrix
4271  , size_t... CCAs > // Compile time column arguments
4272 inline Columns<MT,false,false,false,CCAs...>&
4274 {
4277 
4278  if( rows() != columns() ) {
4279  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4280  }
4281 
4282  const ResultType tmp( ctrans( *this ) );
4283 
4284  if( IsRestricted<MT>::value ) {
4285  for( size_t j=0UL; j<columns(); ++j ) {
4286  if( !tryAssign( matrix_, column( tmp, j, unchecked ), 0UL, idx(j) ) ) {
4287  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4288  }
4289  }
4290  }
4291 
4292  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4293 
4294  left.reset();
4295  smpAssign( left, tmp );
4296 
4297  return *this;
4298 }
4300 //*************************************************************************************************
4301 
4302 
4303 //*************************************************************************************************
4316 template< typename MT // Type of the sparse matrix
4317  , size_t... CCAs > // Compile time column arguments
4318 template< typename Other > // Data type of the scalar value
4319 inline Columns<MT,false,false,false,CCAs...>&
4320  Columns<MT,false,false,false,CCAs...>::scale( const Other& scalar )
4321 {
4325 
4326  for( size_t i=0UL; i<rows(); ++i ) {
4327  const auto end( matrix_.end( i ) );
4328  for( size_t j=0UL; j<columns(); ++j ) {
4329  auto pos = matrix_.find( i, idx(j) );
4330  if( pos != end ) {
4331  pos->value() *= scalar;
4332  }
4333  }
4334  }
4335 
4336  return *this;
4337 }
4339 //*************************************************************************************************
4340 
4341 
4342 
4343 
4344 //=================================================================================================
4345 //
4346 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4347 //
4348 //=================================================================================================
4349 
4350 //*************************************************************************************************
4361 template< typename MT // Type of the sparse matrix
4362  , size_t... CCAs > // Compile time column arguments
4363 template< typename Other > // Data type of the foreign expression
4364 inline bool Columns<MT,false,false,false,CCAs...>::canAlias( const Other* alias ) const noexcept
4365 {
4366  return matrix_.isAliased( alias );
4367 }
4369 //*************************************************************************************************
4370 
4371 
4372 //*************************************************************************************************
4383 template< typename MT // Type of the sparse matrix
4384  , size_t... CCAs > // Compile time column arguments
4385 template< typename Other > // Data type of the foreign expression
4386 inline bool Columns<MT,false,false,false,CCAs...>::isAliased( const Other* alias ) const noexcept
4387 {
4388  return matrix_.isAliased( alias );
4389 }
4391 //*************************************************************************************************
4392 
4393 
4394 //*************************************************************************************************
4405 template< typename MT // Type of the sparse matrix
4406  , size_t... CCAs > // Compile time column arguments
4407 inline bool Columns<MT,false,false,false,CCAs...>::canSMPAssign() const noexcept
4408 {
4409  return false;
4410 }
4412 //*************************************************************************************************
4413 
4414 
4415 //*************************************************************************************************
4427 template< typename MT // Type of the sparse matrix
4428  , size_t... CCAs > // Compile time column arguments
4429 template< typename MT2 // Type of the right-hand side dense matrix
4430  , bool SO > // Storage order of the right-hand side dense matrix
4431 inline void Columns<MT,false,false,false,CCAs...>::assign( const DenseMatrix<MT2,SO>& rhs )
4432 {
4435 
4436  using RT = If_< IsComputation<MT2>, ElementType_<MT>, const ElementType_<MT2>& >;
4437 
4438  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4439  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4440 
4441  for( size_t i=0UL; i<rows(); ++i ) {
4442  for( size_t j=0UL; j<columns(); ++j ) {
4443  RT value( (~rhs)(i,j) );
4444  if( !isDefault<strict>( value ) )
4445  matrix_.set( i, idx(j), std::move( value ) );
4446  else matrix_.erase( i, idx(j) );
4447  }
4448  }
4449 }
4451 //*************************************************************************************************
4452 
4453 
4454 //*************************************************************************************************
4466 template< typename MT // Type of the sparse matrix
4467  , size_t... CCAs > // Compile time column arguments
4468 template< typename MT2 > // Type of the right-hand side sparse matrix
4469 inline void Columns<MT,false,false,false,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
4470 {
4473 
4475 
4476  using RT = If_< IsComputation<MT2>, ElementType_<MT>, const ElementType_<MT2>& >;
4477 
4478  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4479  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4480  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4481 
4482  for( size_t i=0UL; i<rows(); ++i ) {
4483  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
4484  RT value( element->value() );
4485  if( !isDefault<strict>( value ) )
4486  matrix_.set( i, idx( element->index() ), std::move( value ) );
4487  else matrix_.erase( i, idx( element->index() ) );
4488  }
4489  }
4490 }
4492 //*************************************************************************************************
4493 
4494 
4495 //*************************************************************************************************
4507 template< typename MT // Type of the sparse matrix
4508  , size_t... CCAs > // Compile time column arguments
4509 template< typename MT2 > // Type of the right-hand side sparse matrix
4510 inline void Columns<MT,false,false,false,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
4511 {
4514 
4515  using RT = If_< IsComputation<MT2>, ElementType_<MT>, const ElementType_<MT2>& >;
4516 
4517  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4518  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4519  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
4520 
4521  for( size_t j=0UL; j<columns(); ++j ) {
4522  const size_t index( idx(j) );
4523  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
4524  RT value( element->value() );
4525  if( !isDefault<strict>( value ) )
4526  matrix_.set( element->index(), index, std::move( value ) );
4527  else matrix_.erase( element->index(), index );
4528  }
4529  }
4530 }
4532 //*************************************************************************************************
4533 
4534 
4535 //*************************************************************************************************
4547 template< typename MT // Type of the sparse matrix
4548  , size_t... CCAs > // Compile time column arguments
4549 template< typename MT2 // Type of the right-hand side matrix
4550  , bool SO > // Storage order of the right-hand side matrix
4551 inline void Columns<MT,false,false,false,CCAs...>::addAssign( const Matrix<MT2,SO>& rhs )
4552 {
4555 
4556  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
4557 
4559 
4560  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4561  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4562 
4563  const AddType tmp( serial( *this + (~rhs) ) );
4564  reset();
4565  assign( tmp );
4566 }
4568 //*************************************************************************************************
4569 
4570 
4571 //*************************************************************************************************
4583 template< typename MT // Type of the sparse matrix
4584  , size_t... CCAs > // Compile time column arguments
4585 template< typename MT2 // Type of the right-hand side matrix
4586  , bool SO > // Storage order of the right-hand side matrix
4587 inline void Columns<MT,false,false,false,CCAs...>::subAssign( const Matrix<MT2,SO>& rhs )
4588 {
4591 
4592  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
4593 
4595 
4596  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4597  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4598 
4599  const SubType tmp( serial( *this - (~rhs) ) );
4600  reset();
4601  assign( tmp );
4602 }
4604 //*************************************************************************************************
4605 
4606 
4607 //*************************************************************************************************
4619 template< typename MT // Type of the sparse matrix
4620  , size_t... CCAs > // Compile time column arguments
4621 template< typename MT2 // Type of the right-hand side matrix
4622  , bool SO > // Storage order of the right-hand side matrix
4623 inline void Columns<MT,false,false,false,CCAs...>::schurAssign( const Matrix<MT2,SO>& rhs )
4624 {
4627 
4628  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
4629 
4632 
4633  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
4634  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
4635 
4636  const SchurType tmp( serial( *this % (~rhs) ) );
4637  reset();
4638  assign( tmp );
4639 }
4641 //*************************************************************************************************
4642 
4643 
4644 
4645 
4646 
4647 
4648 
4649 
4650 //=================================================================================================
4651 //
4652 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR SPARSE MATRICES
4653 //
4654 //=================================================================================================
4655 
4656 //*************************************************************************************************
4664 template< typename MT // Type of the sparse matrix
4665  , size_t... CCAs > // Compile time column arguments
4666 class Columns<MT,false,false,true,CCAs...>
4667  : public View< SparseMatrix< Columns<MT,false,false,true,CCAs...>, true > >
4668  , private ColumnsData<CCAs...>
4669 {
4670  private:
4671  //**Type definitions****************************************************************************
4672  using DataType = ColumnsData<CCAs...>;
4673  using Operand = If_< IsExpression<MT>, MT, MT& >;
4674  //**********************************************************************************************
4675 
4676  public:
4677  //**Type definitions****************************************************************************
4679  using This = Columns<MT,false,false,true,CCAs...>;
4680 
4681  using BaseType = SparseMatrix<This,true>;
4682  using ViewedType = MT;
4683  using ResultType = ColumnsTrait_<MT,CCAs...>;
4684  using OppositeType = OppositeType_<ResultType>;
4685  using TransposeType = TransposeType_<ResultType>;
4686  using ElementType = ElementType_<MT>;
4687  using ReturnType = ReturnType_<MT>;
4688  using CompositeType = const Columns&;
4689 
4691  using ConstReference = ConstReference_<MT>;
4692 
4694  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
4695 
4697  using ConstIterator = ConstIterator_<MT>;
4698 
4700  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
4701  //**********************************************************************************************
4702 
4703  //**Compilation flags***************************************************************************
4705  enum : bool { smpAssignable = MT::smpAssignable };
4706  //**********************************************************************************************
4707 
4708  //**Constructors********************************************************************************
4711  template< typename... RCAs >
4712  explicit inline Columns( MT& matrix, RCAs... args );
4713 
4714  inline Columns( const Columns& ) = default;
4715  inline Columns( Columns&& ) = default;
4717  //**********************************************************************************************
4718 
4719  //**Destructor**********************************************************************************
4720  // No explicitly declared destructor.
4721  //**********************************************************************************************
4722 
4723  //**Data access functions***********************************************************************
4726  inline Reference operator()( size_t i, size_t j );
4727  inline ConstReference operator()( size_t i, size_t j ) const;
4728  inline Reference at( size_t i, size_t j );
4729  inline ConstReference at( size_t i, size_t j ) const;
4730  inline Iterator begin ( size_t j );
4731  inline ConstIterator begin ( size_t j ) const;
4732  inline ConstIterator cbegin( size_t j ) const;
4733  inline Iterator end ( size_t j );
4734  inline ConstIterator end ( size_t j ) const;
4735  inline ConstIterator cend ( size_t j ) const;
4737  //**********************************************************************************************
4738 
4739  //**Assignment operators************************************************************************
4742  Columns& operator=( const Columns& ) = delete;
4744  //**********************************************************************************************
4745 
4746  //**Utility functions***************************************************************************
4749  using DataType::idx;
4750  using DataType::idces;
4751  using DataType::columns;
4752 
4753  inline MT& operand() noexcept;
4754  inline const MT& operand() const noexcept;
4755 
4756  inline size_t rows() const noexcept;
4757  inline size_t capacity() const noexcept;
4758  inline size_t capacity( size_t j ) const noexcept;
4759  inline size_t nonZeros() const;
4760  inline size_t nonZeros( size_t j ) const;
4761  inline void reset();
4762  inline void reset( size_t j );
4763  inline void reserve( size_t nonzeros );
4764  void reserve( size_t j, size_t nonzeros );
4765  inline void trim();
4766  inline void trim( size_t j );
4768  //**********************************************************************************************
4769 
4770  //**Insertion functions*************************************************************************
4773  inline Iterator set ( size_t i, size_t j, const ElementType& value );
4774  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
4775  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
4776  inline void finalize( size_t j );
4778  //**********************************************************************************************
4779 
4780  //**Erase functions*****************************************************************************
4783  inline void erase( size_t i, size_t j );
4784  inline Iterator erase( size_t j, Iterator pos );
4785  inline Iterator erase( size_t j, Iterator first, Iterator last );
4786 
4787  template< typename Pred >
4788  inline void erase( Pred predicate );
4789 
4790  template< typename Pred >
4791  inline void erase( size_t j, Iterator first, Iterator last, Pred predicate );
4793  //**********************************************************************************************
4794 
4795  //**Lookup functions****************************************************************************
4798  inline Iterator find ( size_t i, size_t j );
4799  inline ConstIterator find ( size_t i, size_t j ) const;
4800  inline Iterator lowerBound( size_t i, size_t j );
4801  inline ConstIterator lowerBound( size_t i, size_t j ) const;
4802  inline Iterator upperBound( size_t i, size_t j );
4803  inline ConstIterator upperBound( size_t i, size_t j ) const;
4805  //**********************************************************************************************
4806 
4807  //**Expression template evaluation functions****************************************************
4810  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
4811  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
4812 
4813  inline bool canSMPAssign() const noexcept;
4815  //**********************************************************************************************
4816 
4817  private:
4818  //**Member variables****************************************************************************
4821  Operand matrix_;
4822 
4823  //**********************************************************************************************
4824 
4825  //**Compile time checks*************************************************************************
4835  //**********************************************************************************************
4836 };
4838 //*************************************************************************************************
4839 
4840 
4841 
4842 
4843 //=================================================================================================
4844 //
4845 // CONSTRUCTORS
4846 //
4847 //=================================================================================================
4848 
4849 //*************************************************************************************************
4862 template< typename MT // Type of the sparse matrix
4863  , size_t... CCAs > // Compile time column arguments
4864 template< typename... RCAs > // Runtime column arguments
4865 inline Columns<MT,false,false,true,CCAs...>::Columns( MT& matrix, RCAs... args )
4866  : DataType( args... ) // Base class initialization
4867  , matrix_ ( matrix ) // The matrix containing the columns
4868 {
4869  if( !Contains< TypeList<RCAs...>, Unchecked >::value ) {
4870  for( size_t j=0UL; j<columns(); ++j ) {
4871  if( matrix_.columns() <= idx(j) ) {
4872  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
4873  }
4874  }
4875  }
4876 }
4878 //*************************************************************************************************
4879 
4880 
4881 
4882 
4883 //=================================================================================================
4884 //
4885 // DATA ACCESS FUNCTIONS
4886 //
4887 //=================================================================================================
4888 
4889 //*************************************************************************************************
4900 template< typename MT // Type of the sparse matrix
4901  , size_t... CCAs > // Compile time column arguments
4902 inline typename Columns<MT,false,false,true,CCAs...>::Reference
4903  Columns<MT,false,false,true,CCAs...>::operator()( size_t i, size_t j )
4904 {
4905  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4906  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4907 
4908  return matrix_(idx(j),i);
4909 }
4911 //*************************************************************************************************
4912 
4913 
4914 //*************************************************************************************************
4925 template< typename MT // Type of the sparse matrix
4926  , size_t... CCAs > // Compile time column arguments
4927 inline typename Columns<MT,false,false,true,CCAs...>::ConstReference
4928  Columns<MT,false,false,true,CCAs...>::operator()( size_t i, size_t j ) const
4929 {
4930  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4931  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4932 
4933  return const_cast<const MT&>( matrix_ )(idx(j),i);
4934 }
4936 //*************************************************************************************************
4937 
4938 
4939 //*************************************************************************************************
4951 template< typename MT // Type of the sparse matrix
4952  , size_t... CCAs > // Compile time column arguments
4953 inline typename Columns<MT,false,false,true,CCAs...>::Reference
4954  Columns<MT,false,false,true,CCAs...>::at( size_t i, size_t j )
4955 {
4956  if( i >= rows() ) {
4957  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4958  }
4959  if( j >= columns() ) {
4960  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4961  }
4962  return (*this)(i,j);
4963 }
4965 //*************************************************************************************************
4966 
4967 
4968 //*************************************************************************************************
4980 template< typename MT // Type of the sparse matrix
4981  , size_t... CCAs > // Compile time column arguments
4982 inline typename Columns<MT,false,false,true,CCAs...>::ConstReference
4983  Columns<MT,false,false,true,CCAs...>::at( size_t i, size_t j ) const
4984 {
4985  if( i >= rows() ) {
4986  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4987  }
4988  if( j >= columns() ) {
4989  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4990  }
4991  return (*this)(i,j);
4992 }
4994 //*************************************************************************************************
4995 
4996 
4997 //*************************************************************************************************
5006 template< typename MT // Type of the sparse matrix
5007  , size_t... CCAs > // Compile time column arguments
5008 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5010 {
5011  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5012 
5013  return matrix_.begin( idx(j) );
5014 }
5016 //*************************************************************************************************
5017 
5018 
5019 //*************************************************************************************************
5028 template< typename MT // Type of the sparse matrix
5029  , size_t... CCAs > // Compile time column arguments
5030 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5032 {
5033  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5034 
5035  return matrix_.cbegin( idx(j) );
5036 }
5038 //*************************************************************************************************
5039 
5040 
5041 //*************************************************************************************************
5050 template< typename MT // Type of the sparse matrix
5051  , size_t... CCAs > // Compile time column arguments
5052 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5054 {
5055  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5056 
5057  return matrix_.cbegin( idx(j) );
5058 }
5060 //*************************************************************************************************
5061 
5062 
5063 //*************************************************************************************************
5072 template< typename MT // Type of the sparse matrix
5073  , size_t... CCAs > // Compile time column arguments
5074 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5076 {
5077  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5078 
5079  return matrix_.end( idx(j) );
5080 }
5082 //*************************************************************************************************
5083 
5084 
5085 //*************************************************************************************************
5094 template< typename MT // Type of the sparse matrix
5095  , size_t... CCAs > // Compile time column arguments
5096 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5098 {
5099  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5100 
5101  return matrix_.cend( idx(j) );
5102 }
5104 //*************************************************************************************************
5105 
5106 
5107 //*************************************************************************************************
5116 template< typename MT // Type of the sparse matrix
5117  , size_t... CCAs > // Compile time column arguments
5118 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5120 {
5121  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5122 
5123  return matrix_.cend( idx(j) );
5124 }
5126 //*************************************************************************************************
5127 
5128 
5129 
5130 
5131 //=================================================================================================
5132 //
5133 // UTILITY FUNCTIONS
5134 //
5135 //=================================================================================================
5136 
5137 //*************************************************************************************************
5143 template< typename MT // Type of the sparse matrix
5144  , size_t... CCAs > // Compile time column arguments
5145 inline MT& Columns<MT,false,false,true,CCAs...>::operand() noexcept
5146 {
5147  return matrix_;
5148 }
5150 //*************************************************************************************************
5151 
5152 
5153 //*************************************************************************************************
5159 template< typename MT // Type of the sparse matrix
5160  , size_t... CCAs > // Compile time column arguments
5161 inline const MT& Columns<MT,false,false,true,CCAs...>::operand() const noexcept
5162 {
5163  return matrix_;
5164 }
5166 //*************************************************************************************************
5167 
5168 
5169 //*************************************************************************************************
5175 template< typename MT // Type of the sparse matrix
5176  , size_t... CCAs > // Compile time column arguments
5177 inline size_t Columns<MT,false,false,true,CCAs...>::rows() const noexcept
5178 {
5179  return matrix_.rows();
5180 }
5182 //*************************************************************************************************
5183 
5184 
5185 //*************************************************************************************************
5191 template< typename MT // Type of the sparse matrix
5192  , size_t... CCAs > // Compile time column arguments
5193 inline size_t Columns<MT,false,false,true,CCAs...>::capacity() const noexcept
5194 {
5195  return nonZeros() + matrix_.capacity() - matrix_.nonZeros();
5196 }
5198 //*************************************************************************************************
5199 
5200 
5201 //*************************************************************************************************
5210 template< typename MT // Type of the sparse matrix
5211  , size_t... CCAs > // Compile time column arguments
5212 inline size_t Columns<MT,false,false,true,CCAs...>::capacity( size_t j ) const noexcept
5213 {
5214  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5215 
5216  return matrix_.capacity( idx(j) );
5217 }
5219 //*************************************************************************************************
5220 
5221 
5222 //*************************************************************************************************
5228 template< typename MT // Type of the sparse matrix
5229  , size_t... CCAs > // Compile time column arguments
5231 {
5232  size_t nonzeros( 0UL );
5233 
5234  for( size_t j=0UL; j<columns(); ++j )
5235  nonzeros += nonZeros( j );
5236 
5237  return nonzeros;
5238 }
5240 //*************************************************************************************************
5241 
5242 
5243 //*************************************************************************************************
5252 template< typename MT // Type of the sparse matrix
5253  , size_t... CCAs > // Compile time column arguments
5254 inline size_t Columns<MT,false,false,true,CCAs...>::nonZeros( size_t j ) const
5255 {
5256  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5257 
5258  return matrix_.nonZeros( idx(j) );
5259 }
5261 //*************************************************************************************************
5262 
5263 
5264 //*************************************************************************************************
5270 template< typename MT // Type of the sparse matrix
5271  , size_t... CCAs > // Compile time column arguments
5273 {
5274  for( size_t j=0UL; j<columns(); ++j ) {
5275  matrix_.reset( idx(j) );
5276  }
5277 }
5279 //*************************************************************************************************
5280 
5281 
5282 //*************************************************************************************************
5292 template< typename MT // Type of the sparse matrix
5293  , size_t... CCAs > // Compile time column arguments
5294 inline void Columns<MT,false,false,true,CCAs...>::reset( size_t j )
5295 {
5296  matrix_.reset( idx(j) );
5297 }
5299 //*************************************************************************************************
5300 
5301 
5302 //*************************************************************************************************
5313 template< typename MT // Type of the sparse matrix
5314  , size_t... CCAs > // Compile time column arguments
5315 inline void Columns<MT,false,false,true,CCAs...>::reserve( size_t nonzeros )
5316 {
5317  const size_t current( capacity() );
5318 
5319  if( nonzeros > current ) {
5320  matrix_.reserve( matrix_.capacity() + nonzeros - current );
5321  }
5322 }
5324 //*************************************************************************************************
5325 
5326 
5327 //*************************************************************************************************
5339 template< typename MT // Type of the sparse matrix
5340  , size_t... CCAs > // Compile time column arguments
5341 void Columns<MT,false,false,true,CCAs...>::reserve( size_t j, size_t nonzeros )
5342 {
5343  matrix_.reserve( idx(j), nonzeros );
5344 }
5346 //*************************************************************************************************
5347 
5348 
5349 //*************************************************************************************************
5359 template< typename MT // Type of the sparse matrix
5360  , size_t... CCAs > // Compile time column arguments
5361 void Columns<MT,false,false,true,CCAs...>::trim()
5362 {
5363  for( size_t j=0UL; j<columns(); ++j ) {
5364  trim( j );
5365  }
5366 }
5368 //*************************************************************************************************
5369 
5370 
5371 //*************************************************************************************************
5382 template< typename MT // Type of the sparse matrix
5383  , size_t... CCAs > // Compile time column arguments
5384 void Columns<MT,false,false,true,CCAs...>::trim( size_t j )
5385 {
5386  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5387 
5388  matrix_.trim( idx(j) );
5389 }
5391 //*************************************************************************************************
5392 
5393 
5394 
5395 
5396 //=================================================================================================
5397 //
5398 // INSERTION FUNCTIONS
5399 //
5400 //=================================================================================================
5401 
5402 //*************************************************************************************************
5415 template< typename MT // Type of the sparse matrix
5416  , size_t... CCAs > // Compile time column arguments
5417 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5418  Columns<MT,false,false,true,CCAs...>::set( size_t i, size_t j, const ElementType& value )
5419 {
5420  return matrix_.set( idx(j), i, value );
5421 }
5423 //*************************************************************************************************
5424 
5425 
5426 //*************************************************************************************************
5440 template< typename MT // Type of the sparse matrix
5441  , size_t... CCAs > // Compile time column arguments
5442 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5443  Columns<MT,false,false,true,CCAs...>::insert( size_t i, size_t j, const ElementType& value )
5444 {
5445  return matrix_.insert( idx(j), i, value );
5446 }
5448 //*************************************************************************************************
5449 
5450 
5451 //*************************************************************************************************
5495 template< typename MT // Type of the sparse matrix
5496  , size_t... CCAs > // Compile time column arguments
5497 inline void Columns<MT,false,false,true,CCAs...>::append( size_t i, size_t j, const ElementType& value, bool check )
5498 {
5499  if( !check || !isDefault<strict>( value ) )
5500  matrix_.insert( idx(j), i, value );
5501 }
5503 //*************************************************************************************************
5504 
5505 
5506 //*************************************************************************************************
5520 template< typename MT // Type of the sparse matrix
5521  , size_t... CCAs > // Compile time column arguments
5522 inline void Columns<MT,false,false,true,CCAs...>::finalize( size_t j )
5523 {
5524  UNUSED_PARAMETER( j );
5525 
5526  return;
5527 }
5529 //*************************************************************************************************
5530 
5531 
5532 
5533 
5534 //=================================================================================================
5535 //
5536 // ERASE FUNCTIONS
5537 //
5538 //=================================================================================================
5539 
5540 //*************************************************************************************************
5550 template< typename MT // Type of the sparse matrix
5551  , size_t... CCAs > // Compile time column arguments
5552 inline void Columns<MT,false,false,true,CCAs...>::erase( size_t i, size_t j )
5553 {
5554  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
5555  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5556 
5557  matrix_.erase( idx(j), i );
5558 }
5560 //*************************************************************************************************
5561 
5562 
5563 //*************************************************************************************************
5573 template< typename MT // Type of the sparse matrix
5574  , size_t... CCAs > // Compile time column arguments
5575 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5576  Columns<MT,false,false,true,CCAs...>::erase( size_t j, Iterator pos )
5577 {
5578  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5579 
5580  return matrix_.erase( idx(j), pos );
5581 }
5583 //*************************************************************************************************
5584 
5585 
5586 //*************************************************************************************************
5597 template< typename MT // Type of the sparse matrix
5598  , size_t... CCAs > // Compile time column arguments
5599 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5600  Columns<MT,false,false,true,CCAs...>::erase( size_t j, Iterator first, Iterator last )
5601 {
5602  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5603 
5604  return matrix_.erase( idx(j), first, last );
5605 }
5607 //*************************************************************************************************
5608 
5609 
5610 //*************************************************************************************************
5633 template< typename MT // Type of the sparse matrix
5634  , size_t... CCAs > // Compile time column arguments
5635 template< typename Pred > // Type of the unary predicate
5636 inline void Columns<MT,false,false,true,CCAs...>::erase( Pred predicate )
5637 {
5638  for( size_t j=0UL; j<columns(); ++j ) {
5639  matrix_.erase( idx(j), begin(j), end(j), predicate );
5640  }
5641 }
5643 //*************************************************************************************************
5644 
5645 
5646 //*************************************************************************************************
5673 template< typename MT // Type of the sparse matrix
5674  , size_t... CCAs > // Compile time column arguments
5675 template< typename Pred > // Type of the unary predicate
5676 inline void Columns<MT,false,false,true,CCAs...>::erase( size_t j, Iterator first, Iterator last, Pred predicate )
5677 {
5678  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5679 
5680  matrix_.erase( idx(j), first, last, predicate );
5681 }
5683 //*************************************************************************************************
5684 
5685 
5686 
5687 
5688 //=================================================================================================
5689 //
5690 // LOOKUP FUNCTIONS
5691 //
5692 //=================================================================================================
5693 
5694 //*************************************************************************************************
5709 template< typename MT // Type of the sparse matrix
5710  , size_t... CCAs > // Compile time column arguments
5711 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5712  Columns<MT,false,false,true,CCAs...>::find( size_t i, size_t j )
5713 {
5714  return matrix_.find( idx(j), i );
5715 }
5717 //*************************************************************************************************
5718 
5719 
5720 //*************************************************************************************************
5735 template< typename MT // Type of the sparse matrix
5736  , size_t... CCAs > // Compile time column arguments
5737 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5738  Columns<MT,false,false,true,CCAs...>::find( size_t i, size_t j ) const
5739 {
5740  return matrix_.find( idx(j), i );
5741 }
5743 //*************************************************************************************************
5744 
5745 
5746 //*************************************************************************************************
5760 template< typename MT // Type of the sparse matrix
5761  , size_t... CCAs > // Compile time column arguments
5762 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5763  Columns<MT,false,false,true,CCAs...>::lowerBound( size_t i, size_t j )
5764 {
5765  return matrix_.lowerBound( idx(j), i );
5766 }
5768 //*************************************************************************************************
5769 
5770 
5771 //*************************************************************************************************
5785 template< typename MT // Type of the sparse matrix
5786  , size_t... CCAs > // Compile time column arguments
5787 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5788  Columns<MT,false,false,true,CCAs...>::lowerBound( size_t i, size_t j ) const
5789 {
5790  return matrix_.lowerBound( idx(j), i );
5791 }
5793 //*************************************************************************************************
5794 
5795 
5796 //*************************************************************************************************
5810 template< typename MT // Type of the sparse matrix
5811  , size_t... CCAs > // Compile time column arguments
5812 inline typename Columns<MT,false,false,true,CCAs...>::Iterator
5813  Columns<MT,false,false,true,CCAs...>::upperBound( size_t i, size_t j )
5814 {
5815  return matrix_.upperBound( idx(j), i );
5816 }
5818 //*************************************************************************************************
5819 
5820 
5821 //*************************************************************************************************
5835 template< typename MT // Type of the sparse matrix
5836  , size_t... CCAs > // Compile time column arguments
5837 inline typename Columns<MT,false,false,true,CCAs...>::ConstIterator
5838  Columns<MT,false,false,true,CCAs...>::upperBound( size_t i, size_t j ) const
5839 {
5840  return matrix_.upperBound( idx(j), i );
5841 }
5843 //*************************************************************************************************
5844 
5845 
5846 
5847 
5848 //=================================================================================================
5849 //
5850 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5851 //
5852 //=================================================================================================
5853 
5854 //*************************************************************************************************
5865 template< typename MT // Type of the sparse matrix
5866  , size_t... CCAs > // Compile time column arguments
5867 template< typename Other > // Data type of the foreign expression
5868 inline bool Columns<MT,false,false,true,CCAs...>::canAlias( const Other* alias ) const noexcept
5869 {
5870  return matrix_.isAliased( alias );
5871 }
5873 //*************************************************************************************************
5874 
5875 
5876 //*************************************************************************************************
5887 template< typename MT // Type of the sparse matrix
5888  , size_t... CCAs > // Compile time column arguments
5889 template< typename Other > // Data type of the foreign expression
5890 inline bool Columns<MT,false,false,true,CCAs...>::isAliased( const Other* alias ) const noexcept
5891 {
5892  return matrix_.isAliased( alias );
5893 }
5895 //*************************************************************************************************
5896 
5897 
5898 //*************************************************************************************************
5909 template< typename MT // Type of the sparse matrix
5910  , size_t... CCAs > // Compile time column arguments
5911 inline bool Columns<MT,false,false,true,CCAs...>::canSMPAssign() const noexcept
5912 {
5913  return false;
5914 }
5916 //*************************************************************************************************
5917 
5918 } // namespace blaze
5919 
5920 #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:131
Headerfile for the generic min algorithm.
Header file for the blaze::checked and blaze::unchecked instances.
Header file for the implementation of the Columns base template.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3077
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, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
Header file for the subtraction trait.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:522
Header file for basic type definitions.
Header file for the View base class.
#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
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3076
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:364
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3074
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3078
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
#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. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:81
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:827
#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
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3083
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:560
#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
Header file for the decltype(auto) workaround.
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:733
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3084
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.
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1950
BLAZE_ALWAYS_INLINE 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:474
BLAZE_ALWAYS_INLINE 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:408
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.
Header file for the IsSymmetric type trait.
typename ColumnsTrait< MT, CCAs... >::Type ColumnsTrait_
Auxiliary alias declaration for the ColumnsTrait type trait.The ColumnsTrait_ alias declaration provi...
Definition: ColumnsTrait.h:145
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3082
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:1359
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
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
#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
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3079
#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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:506
Header file for the SparseElement base class.
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:430
#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
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:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for the IsStrictlyLower type trait.
Constraint on the data type.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#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.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the relaxation flag types.
Header file for the addition trait.
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:131
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the isDefault shim.
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:816
#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.
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:490
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
EnableIf_< IsNumeric< ST >, MT &> operator/=(DenseMatrix< MT, SO > &mat, ST scalar)
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:655
Header file for the implementation of the ColumnsData class template.
Header file for the IsComputation type trait class.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3081
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
#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, a compilation error is created.
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
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
EnableIf_< IsNumeric< ST >, MT &> operator*=(DenseMatrix< MT, SO > &mat, ST scalar)
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:593
Header file for the IsHermitian 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, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#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
Header file for the IsExpression type trait class.
Constraint on the data type.
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:801