Blaze  3.6
Sparse.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_ADAPTORS_UNILOWERMATRIX_SPARSE_H_
36 #define _BLAZE_MATH_ADAPTORS_UNILOWERMATRIX_SPARSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <utility>
45 #include <vector>
51 #include <blaze/math/Aliases.h>
65 #include <blaze/math/Exception.h>
68 #include <blaze/math/shims/Clear.h>
70 #include <blaze/math/shims/IsOne.h>
82 #include <blaze/util/Assert.h>
88 #include <blaze/util/DisableIf.h>
89 #include <blaze/util/EnableIf.h>
91 #include <blaze/util/Types.h>
92 
93 
94 namespace blaze {
95 
96 //=================================================================================================
97 //
98 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES
99 //
100 //=================================================================================================
101 
102 //*************************************************************************************************
110 template< typename MT // Type of the adapted sparse matrix
111  , bool SO > // Storage order of the adapted sparse matrix
112 class UniLowerMatrix<MT,SO,false>
113  : public SparseMatrix< UniLowerMatrix<MT,SO,false>, SO >
114 {
115  private:
116  //**Type definitions****************************************************************************
117  using OT = OppositeType_t<MT>;
118  using TT = TransposeType_t<MT>;
119  using ET = ElementType_t<MT>;
120  //**********************************************************************************************
121 
122  public:
123  //**Type definitions****************************************************************************
124  using This = UniLowerMatrix<MT,SO,false>;
125  using BaseType = SparseMatrix<This,SO>;
126  using ResultType = This;
127  using OppositeType = UniLowerMatrix<OT,!SO,false>;
128  using TransposeType = UniUpperMatrix<TT,!SO,false>;
129  using ElementType = ET;
130  using ReturnType = ReturnType_t<MT>;
131  using CompositeType = const This&;
132  using Reference = UniLowerProxy<MT>;
133  using ConstReference = ConstReference_t<MT>;
134  using ConstIterator = ConstIterator_t<MT>;
135  //**********************************************************************************************
136 
137  //**Rebind struct definition********************************************************************
140  template< typename NewType > // Data type of the other matrix
141  struct Rebind {
143  using Other = UniLowerMatrix< typename MT::template Rebind<NewType>::Other >;
144  };
145  //**********************************************************************************************
146 
147  //**Resize struct definition********************************************************************
150  template< size_t NewM // Number of rows of the other matrix
151  , size_t NewN > // Number of columns of the other matrix
152  struct Resize {
154  using Other = UniLowerMatrix< typename MT::template Resize<NewM,NewN>::Other >;
155  };
156  //**********************************************************************************************
157 
158  //**Iterator class definition*******************************************************************
161  class Iterator
162  {
163  public:
164  //**Type definitions*************************************************************************
165  using IteratorType = Iterator_t<MT>;
166 
167  using IteratorCategory = std::forward_iterator_tag;
168  using ValueType = UniLowerElement<MT>;
169  using PointerType = ValueType;
170  using ReferenceType = ValueType;
171  using DifferenceType = ptrdiff_t;
172 
173  // STL iterator requirements
174  using iterator_category = IteratorCategory;
175  using value_type = ValueType;
176  using pointer = PointerType;
177  using reference = ReferenceType;
178  using difference_type = DifferenceType;
179  //*******************************************************************************************
180 
181  //**Default constructor**********************************************************************
184  inline Iterator()
185  : pos_ ( ) // Iterator to the current lower unitriangular matrix element
186  , index_ ( 0UL ) // The row/column index of the iterator
187  {}
188  //*******************************************************************************************
189 
190  //**Constructor******************************************************************************
196  inline Iterator( IteratorType pos, size_t index )
197  : pos_ ( pos ) // Iterator to the current lower unitriangular matrix element
198  , index_( index ) // The row/column index of the iterator
199  {}
200  //*******************************************************************************************
201 
202  //**Prefix increment operator****************************************************************
207  inline Iterator& operator++() {
208  ++pos_;
209  return *this;
210  }
211  //*******************************************************************************************
212 
213  //**Postfix increment operator***************************************************************
218  inline const Iterator operator++( int ) {
219  const Iterator tmp( *this );
220  ++(*this);
221  return tmp;
222  }
223  //*******************************************************************************************
224 
225  //**Element access operator******************************************************************
230  inline ReferenceType operator*() const {
231  return ReferenceType( pos_, pos_->index() == index_ );
232  }
233  //*******************************************************************************************
234 
235  //**Element access operator******************************************************************
240  inline PointerType operator->() const {
241  return PointerType( pos_, pos_->index() == index_ );
242  }
243  //*******************************************************************************************
244 
245  //**Conversion operator**********************************************************************
250  inline operator ConstIterator() const {
251  return pos_;
252  }
253  //*******************************************************************************************
254 
255  //**Equality operator************************************************************************
261  inline bool operator==( const Iterator& rhs ) const {
262  return pos_ == rhs.pos_;
263  }
264  //*******************************************************************************************
265 
266  //**Inequality operator**********************************************************************
272  inline bool operator!=( const Iterator& rhs ) const {
273  return !( *this == rhs );
274  }
275  //*******************************************************************************************
276 
277  //**Subtraction operator*********************************************************************
283  inline DifferenceType operator-( const Iterator& rhs ) const {
284  return pos_ - rhs.pos_;
285  }
286  //*******************************************************************************************
287 
288  //**Base function****************************************************************************
293  inline IteratorType base() const {
294  return pos_;
295  }
296  //*******************************************************************************************
297 
298  private:
299  //**Member variables*************************************************************************
300  IteratorType pos_;
301  size_t index_;
302  //*******************************************************************************************
303  };
304  //**********************************************************************************************
305 
306  //**Compilation flags***************************************************************************
308  static constexpr bool smpAssignable = false;
309  //**********************************************************************************************
310 
311  //**Constructors********************************************************************************
314  explicit inline UniLowerMatrix();
315  explicit inline UniLowerMatrix( size_t n );
316  explicit inline UniLowerMatrix( size_t n, size_t nonzeros );
317  explicit inline UniLowerMatrix( size_t n, const std::vector<size_t>& nonzeros );
318  inline UniLowerMatrix( initializer_list< initializer_list<ElementType> > list );
319 
320  inline UniLowerMatrix( const UniLowerMatrix& m );
321  inline UniLowerMatrix( UniLowerMatrix&& m ) noexcept;
322 
323  template< typename MT2, bool SO2 >
324  inline UniLowerMatrix( const Matrix<MT2,SO2>& m );
326  //**********************************************************************************************
327 
328  //**Destructor**********************************************************************************
331  ~UniLowerMatrix() = default;
333  //**********************************************************************************************
334 
335  //**Data access functions***********************************************************************
338  inline Reference operator()( size_t i, size_t j );
339  inline ConstReference operator()( size_t i, size_t j ) const;
340  inline Reference at( size_t i, size_t j );
341  inline ConstReference at( size_t i, size_t j ) const;
342  inline Iterator begin ( size_t i );
343  inline ConstIterator begin ( size_t i ) const;
344  inline ConstIterator cbegin( size_t i ) const;
345  inline Iterator end ( size_t i );
346  inline ConstIterator end ( size_t i ) const;
347  inline ConstIterator cend ( size_t i ) const;
349  //**********************************************************************************************
350 
351  //**Assignment operators************************************************************************
354  inline UniLowerMatrix& operator=( initializer_list< initializer_list<ElementType> > list );
355 
356  inline UniLowerMatrix& operator=( const UniLowerMatrix& rhs );
357  inline UniLowerMatrix& operator=( UniLowerMatrix&& rhs ) noexcept;
358 
359  template< typename MT2, bool SO2 >
360  inline auto operator=( const Matrix<MT2,SO2>& rhs )
361  -> DisableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >;
362 
363  template< typename MT2, bool SO2 >
364  inline auto operator=( const Matrix<MT2,SO2>& rhs )
365  -> EnableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >;
366 
367  template< typename MT2, bool SO2 >
368  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
369  -> DisableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >;
370 
371  template< typename MT2, bool SO2 >
372  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
373  -> EnableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >;
374 
375  template< typename MT2, bool SO2 >
376  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
377  -> DisableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >;
378 
379  template< typename MT2, bool SO2 >
380  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
381  -> EnableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >;
382 
383  template< typename MT2, bool SO2 >
384  inline auto operator%=( const Matrix<MT2,SO2>& rhs ) -> UniLowerMatrix&;
386  //**********************************************************************************************
387 
388  //**Utility functions***************************************************************************
391  inline size_t rows() const noexcept;
392  inline size_t columns() const noexcept;
393  inline size_t capacity() const noexcept;
394  inline size_t capacity( size_t i ) const noexcept;
395  inline size_t nonZeros() const;
396  inline size_t nonZeros( size_t i ) const;
397  inline void reset();
398  inline void reset( size_t i );
399  inline void clear();
400  inline void resize ( size_t n, bool preserve=true );
401  inline void reserve( size_t nonzeros );
402  inline void reserve( size_t i, size_t nonzeros );
403  inline void trim();
404  inline void trim( size_t i );
405  inline void shrinkToFit();
406  inline void swap( UniLowerMatrix& m ) noexcept;
407 
408  static inline constexpr size_t maxNonZeros() noexcept;
409  static inline constexpr size_t maxNonZeros( size_t n ) noexcept;
411  //**********************************************************************************************
412 
413  //**Insertion functions*************************************************************************
416  inline Iterator set ( size_t i, size_t j, const ElementType& value );
417  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
418  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
419  inline void finalize( size_t i );
421  //**********************************************************************************************
422 
423  //**Erase functions*****************************************************************************
426  inline void erase( size_t i, size_t j );
427  inline Iterator erase( size_t i, Iterator pos );
428  inline Iterator erase( size_t i, Iterator first, Iterator last );
429 
430  template< typename Pred >
431  inline void erase( Pred predicate );
432 
433  template< typename Pred >
434  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
436  //**********************************************************************************************
437 
438  //**Lookup functions****************************************************************************
441  inline Iterator find ( size_t i, size_t j );
442  inline ConstIterator find ( size_t i, size_t j ) const;
443  inline Iterator lowerBound( size_t i, size_t j );
444  inline ConstIterator lowerBound( size_t i, size_t j ) const;
445  inline Iterator upperBound( size_t i, size_t j );
446  inline ConstIterator upperBound( size_t i, size_t j ) const;
448  //**********************************************************************************************
449 
450  //**Debugging functions*************************************************************************
453  inline bool isIntact() const noexcept;
455  //**********************************************************************************************
456 
457  //**Expression template evaluation functions****************************************************
460  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
461  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
462 
463  inline bool canSMPAssign() const noexcept;
465  //**********************************************************************************************
466 
467  private:
468  //**Utility functions***************************************************************************
471  inline void resetUpper();
473  //**********************************************************************************************
474 
475  //**Member variables****************************************************************************
478  MT matrix_;
479 
480  //**********************************************************************************************
481 
482  //**Friend declarations*************************************************************************
483  template< typename MT2, bool SO2, bool DF2 >
484  friend MT2& derestrict( UniLowerMatrix<MT2,SO2,DF2>& m );
485  //**********************************************************************************************
486 
487  //**Compile time checks*************************************************************************
504  BLAZE_STATIC_ASSERT( ( Size_v<MT,0UL> == Size_v<MT,1UL> ) );
505  //**********************************************************************************************
506 };
508 //*************************************************************************************************
509 
510 
511 
512 
513 //=================================================================================================
514 //
515 // CONSTRUCTORS
516 //
517 //=================================================================================================
518 
519 //*************************************************************************************************
523 template< typename MT // Type of the adapted sparse matrix
524  , bool SO > // Storage order of the adapted sparse matrix
525 inline UniLowerMatrix<MT,SO,false>::UniLowerMatrix()
526  : matrix_() // The adapted sparse matrix
527 {
528  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
529 }
531 //*************************************************************************************************
532 
533 
534 //*************************************************************************************************
542 template< typename MT // Type of the adapted sparse matrix
543  , bool SO > // Storage order of the adapted sparse matrix
544 inline UniLowerMatrix<MT,SO,false>::UniLowerMatrix( size_t n )
545  : matrix_( n, n, n ) // The adapted sparse matrix
546 {
548 
549  for( size_t i=0UL; i<n; ++i ) {
550  matrix_.append( i, i, ElementType(1) );
551  matrix_.finalize( i );
552  }
553 
554  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
555 }
557 //*************************************************************************************************
558 
559 
560 //*************************************************************************************************
570 template< typename MT // Type of the adapted sparse matrix
571  , bool SO > // Storage order of the adapted sparse matrix
572 inline UniLowerMatrix<MT,SO,false>::UniLowerMatrix( size_t n, size_t nonzeros )
573  : matrix_( n, n, max( nonzeros, n ) ) // The adapted sparse matrix
574 {
576 
577  for( size_t i=0UL; i<n; ++i ) {
578  matrix_.append( i, i, ElementType(1) );
579  matrix_.finalize( i );
580  }
581 
582  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
583 }
585 //*************************************************************************************************
586 
587 
588 //*************************************************************************************************
602 template< typename MT // Type of the adapted sparse matrix
603  , bool SO > // Storage order of the adapted sparse matrix
604 inline UniLowerMatrix<MT,SO,false>::UniLowerMatrix( size_t n, const std::vector<size_t>& nonzeros )
605  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
606 {
608 
609  for( size_t i=0UL; i<n; ++i )
610  {
611  if( nonzeros[i] == 0UL ) {
612  BLAZE_THROW_INVALID_ARGUMENT( "Invalid capacity specification" );
613  }
614 
615  matrix_.append( i, i, ElementType(1) );
616  matrix_.finalize( i );
617  }
618 
619  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
620 }
622 //*************************************************************************************************
623 
624 
625 //*************************************************************************************************
649 template< typename MT // Type of the adapted sparse matrix
650  , bool SO > // Storage order of the adapted sparse matrix
651 inline UniLowerMatrix<MT,SO,false>::UniLowerMatrix( initializer_list< initializer_list<ElementType> > list )
652  : matrix_( list ) // The adapted sparse matrix
653 {
654  if( !isUniLower( matrix_ ) ) {
655  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of unilower matrix" );
656  }
657 
658  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
659 }
661 //*************************************************************************************************
662 
663 
664 //*************************************************************************************************
670 template< typename MT // Type of the adapted sparse matrix
671  , bool SO > // Storage order of the adapted sparse matrix
672 inline UniLowerMatrix<MT,SO,false>::UniLowerMatrix( const UniLowerMatrix& m )
673  : matrix_( m.matrix_ ) // The adapted sparse matrix
674 {
675  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
676  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
677 }
679 //*************************************************************************************************
680 
681 
682 //*************************************************************************************************
688 template< typename MT // Type of the adapted sparse matrix
689  , bool SO > // Storage order of the adapted sparse matrix
690 inline UniLowerMatrix<MT,SO,false>::UniLowerMatrix( UniLowerMatrix&& m ) noexcept
691  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
692 {
693  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
694  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
695 }
697 //*************************************************************************************************
698 
699 
700 //*************************************************************************************************
710 template< typename MT // Type of the adapted sparse matrix
711  , bool SO > // Storage order of the adapted sparse matrix
712 template< typename MT2 // Type of the foreign matrix
713  , bool SO2 > // Storage order of the foreign matrix
714 inline UniLowerMatrix<MT,SO,false>::UniLowerMatrix( const Matrix<MT2,SO2>& m )
715  : matrix_( ~m ) // The adapted sparse matrix
716 {
717  if( !IsUniLower_v<MT2> && !isUniLower( matrix_ ) ) {
718  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of unilower matrix" );
719  }
720 
721  if( !IsUniLower_v<MT2> )
722  resetUpper();
723 
724  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
725  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
726 }
728 //*************************************************************************************************
729 
730 
731 
732 
733 //=================================================================================================
734 //
735 // DATA ACCESS FUNCTIONS
736 //
737 //=================================================================================================
738 
739 //*************************************************************************************************
755 template< typename MT // Type of the adapted sparse matrix
756  , bool SO > // Storage order of the adapted sparse matrix
757 inline typename UniLowerMatrix<MT,SO,false>::Reference
758  UniLowerMatrix<MT,SO,false>::operator()( size_t i, size_t j )
759 {
760  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
761  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
762 
763  return Reference( matrix_, i, j );
764 }
766 //*************************************************************************************************
767 
768 
769 //*************************************************************************************************
785 template< typename MT // Type of the adapted sparse matrix
786  , bool SO > // Storage order of the adapted sparse matrix
787 inline typename UniLowerMatrix<MT,SO,false>::ConstReference
788  UniLowerMatrix<MT,SO,false>::operator()( size_t i, size_t j ) const
789 {
790  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
791  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
792 
793  return matrix_(i,j);
794 }
796 //*************************************************************************************************
797 
798 
799 //*************************************************************************************************
816 template< typename MT // Type of the adapted sparse matrix
817  , bool SO > // Storage order of the adapted sparse matrix
818 inline typename UniLowerMatrix<MT,SO,false>::Reference
819  UniLowerMatrix<MT,SO,false>::at( size_t i, size_t j )
820 {
821  if( i >= rows() ) {
822  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
823  }
824  if( j >= columns() ) {
825  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
826  }
827  return (*this)(i,j);
828 }
830 //*************************************************************************************************
831 
832 
833 //*************************************************************************************************
850 template< typename MT // Type of the adapted sparse matrix
851  , bool SO > // Storage order of the adapted sparse matrix
852 inline typename UniLowerMatrix<MT,SO,false>::ConstReference
853  UniLowerMatrix<MT,SO,false>::at( size_t i, size_t j ) const
854 {
855  if( i >= rows() ) {
856  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
857  }
858  if( j >= columns() ) {
859  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
860  }
861  return (*this)(i,j);
862 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
879 template< typename MT // Type of the adapted sparse matrix
880  , bool SO > // Storage order of the adapted sparse matrix
881 inline typename UniLowerMatrix<MT,SO,false>::Iterator
883 {
884  return Iterator( matrix_.begin(i), i );
885 }
887 //*************************************************************************************************
888 
889 
890 //*************************************************************************************************
902 template< typename MT // Type of the adapted sparse matrix
903  , bool SO > // Storage order of the adapted sparse matrix
904 inline typename UniLowerMatrix<MT,SO,false>::ConstIterator
905  UniLowerMatrix<MT,SO,false>::begin( size_t i ) const
906 {
907  return matrix_.begin(i);
908 }
910 //*************************************************************************************************
911 
912 
913 //*************************************************************************************************
925 template< typename MT // Type of the adapted sparse matrix
926  , bool SO > // Storage order of the adapted sparse matrix
927 inline typename UniLowerMatrix<MT,SO,false>::ConstIterator
928  UniLowerMatrix<MT,SO,false>::cbegin( size_t i ) const
929 {
930  return matrix_.cbegin(i);
931 }
933 //*************************************************************************************************
934 
935 
936 //*************************************************************************************************
948 template< typename MT // Type of the adapted sparse matrix
949  , bool SO > // Storage order of the adapted sparse matrix
950 inline typename UniLowerMatrix<MT,SO,false>::Iterator
952 {
953  return Iterator( matrix_.end(i), i );
954 }
956 //*************************************************************************************************
957 
958 
959 //*************************************************************************************************
971 template< typename MT // Type of the adapted sparse matrix
972  , bool SO > // Storage order of the adapted sparse matrix
973 inline typename UniLowerMatrix<MT,SO,false>::ConstIterator
974  UniLowerMatrix<MT,SO,false>::end( size_t i ) const
975 {
976  return matrix_.end(i);
977 }
979 //*************************************************************************************************
980 
981 
982 //*************************************************************************************************
994 template< typename MT // Type of the adapted sparse matrix
995  , bool SO > // Storage order of the adapted sparse matrix
996 inline typename UniLowerMatrix<MT,SO,false>::ConstIterator
997  UniLowerMatrix<MT,SO,false>::cend( size_t i ) const
998 {
999  return matrix_.cend(i);
1000 }
1002 //*************************************************************************************************
1003 
1004 
1005 
1006 
1007 //=================================================================================================
1008 //
1009 // ASSIGNMENT OPERATORS
1010 //
1011 //=================================================================================================
1012 
1013 //*************************************************************************************************
1038 template< typename MT // Type of the adapted sparse matrix
1039  , bool SO > // Storage order of the adapted sparse matrix
1040 inline UniLowerMatrix<MT,SO,false>&
1041  UniLowerMatrix<MT,SO,false>::operator=( initializer_list< initializer_list<ElementType> > list )
1042 {
1043  const InitializerMatrix<ElementType> tmp( list, list.size() );
1044 
1045  if( !isUniLower( tmp ) ) {
1046  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1047  }
1048 
1049  matrix_ = list;
1050 
1051  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1052  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1053 
1054  return *this;
1055 }
1057 //*************************************************************************************************
1058 
1059 
1060 //*************************************************************************************************
1070 template< typename MT // Type of the adapted sparse matrix
1071  , bool SO > // Storage order of the adapted sparse matrix
1072 inline UniLowerMatrix<MT,SO,false>&
1073  UniLowerMatrix<MT,SO,false>::operator=( const UniLowerMatrix& rhs )
1074 {
1075  matrix_ = rhs.matrix_;
1076 
1077  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1078  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1079 
1080  return *this;
1081 }
1083 //*************************************************************************************************
1084 
1085 
1086 //*************************************************************************************************
1093 template< typename MT // Type of the adapted sparse matrix
1094  , bool SO > // Storage order of the adapted sparse matrix
1095 inline UniLowerMatrix<MT,SO,false>&
1096  UniLowerMatrix<MT,SO,false>::operator=( UniLowerMatrix&& rhs ) noexcept
1097 {
1098  matrix_ = std::move( rhs.matrix_ );
1099 
1100  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1101  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1102 
1103  return *this;
1104 }
1106 //*************************************************************************************************
1107 
1108 
1109 //*************************************************************************************************
1122 template< typename MT // Type of the adapted sparse matrix
1123  , bool SO > // Storage order of the adapted sparse matrix
1124 template< typename MT2 // Type of the right-hand side matrix
1125  , bool SO2 > // Storage order of the right-hand side matrix
1126 inline auto UniLowerMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1127  -> DisableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >
1128 {
1129  if( IsStrictlyTriangular_v<MT2> || ( !IsUniLower_v<MT2> && !isUniLower( ~rhs ) ) ) {
1130  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1131  }
1132 
1133  matrix_ = decllow( ~rhs );
1134 
1135  if( !IsUniLower_v<MT2> )
1136  resetUpper();
1137 
1138  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1139  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1140 
1141  return *this;
1142 }
1144 //*************************************************************************************************
1145 
1146 
1147 //*************************************************************************************************
1160 template< typename MT // Type of the adapted sparse matrix
1161  , bool SO > // Storage order of the adapted sparse matrix
1162 template< typename MT2 // Type of the right-hand side matrix
1163  , bool SO2 > // Storage order of the right-hand side matrix
1164 inline auto UniLowerMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1165  -> EnableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >
1166 {
1167  if( IsStrictlyTriangular_v<MT2> || ( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) ) {
1168  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1169  }
1170 
1171  if( IsUniLower_v<MT2> ) {
1172  matrix_ = ~rhs;
1173  }
1174  else {
1175  MT tmp( ~rhs );
1176 
1177  if( !isUniLower( tmp ) ) {
1178  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1179  }
1180 
1181  matrix_ = std::move( tmp );
1182  }
1183 
1184  if( !IsUniLower_v<MT2> )
1185  resetUpper();
1186 
1187  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1188  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1189 
1190  return *this;
1191 }
1193 //*************************************************************************************************
1194 
1195 
1196 //*************************************************************************************************
1209 template< typename MT // Type of the adapted sparse matrix
1210  , bool SO > // Storage order of the adapted sparse matrix
1211 template< typename MT2 // Type of the right-hand side matrix
1212  , bool SO2 > // Storage order of the right-hand side matrix
1213 inline auto UniLowerMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1214  -> DisableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >
1215 {
1216  if( IsUpper_v<MT2> || IsUniTriangular_v<MT2> ||
1217  ( !IsStrictlyLower_v<MT2> && !isStrictlyLower( ~rhs ) ) ) {
1218  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1219  }
1220 
1221  matrix_ += decllow( ~rhs );
1222 
1223  if( !IsStrictlyLower_v<MT2> )
1224  resetUpper();
1225 
1226  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1227  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1228 
1229  return *this;
1230 }
1232 //*************************************************************************************************
1233 
1234 
1235 //*************************************************************************************************
1248 template< typename MT // Type of the adapted sparse matrix
1249  , bool SO > // Storage order of the adapted sparse matrix
1250 template< typename MT2 // Type of the right-hand side matrix
1251  , bool SO2 > // Storage order of the right-hand side matrix
1252 inline auto UniLowerMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1253  -> EnableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >
1254 {
1255  if( IsUpper_v<MT2> || IsUniTriangular_v<MT2> ||
1256  ( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) ) {
1257  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1258  }
1259 
1260  if( IsStrictlyLower_v<MT2> ) {
1261  matrix_ += ~rhs;
1262  }
1263  else {
1264  const ResultType_t<MT2> tmp( ~rhs );
1265 
1266  if( !isStrictlyLower( tmp ) ) {
1267  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1268  }
1269 
1270  matrix_ += decllow( tmp );
1271  }
1272 
1273  if( !IsStrictlyLower_v<MT2> )
1274  resetUpper();
1275 
1276  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1277  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1278 
1279  return *this;
1280 }
1282 //*************************************************************************************************
1283 
1284 
1285 //*************************************************************************************************
1298 template< typename MT // Type of the adapted sparse matrix
1299  , bool SO > // Storage order of the adapted sparse matrix
1300 template< typename MT2 // Type of the right-hand side matrix
1301  , bool SO2 > // Storage order of the right-hand side matrix
1302 inline auto UniLowerMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1303  -> DisableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >
1304 {
1305  if( IsUpper_v<MT2> || IsUniTriangular_v<MT2> ||
1306  ( !IsStrictlyLower_v<MT2> && !isStrictlyLower( ~rhs ) ) ) {
1307  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1308  }
1309 
1310  matrix_ -= decllow( ~rhs );
1311 
1312  if( !IsStrictlyLower_v<MT2> )
1313  resetUpper();
1314 
1315  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1316  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1317 
1318  return *this;
1319 }
1321 //*************************************************************************************************
1322 
1323 
1324 //*************************************************************************************************
1337 template< typename MT // Type of the adapted sparse matrix
1338  , bool SO > // Storage order of the adapted sparse matrix
1339 template< typename MT2 // Type of the right-hand side matrix
1340  , bool SO2 > // Storage order of the right-hand side matrix
1341 inline auto UniLowerMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1342  -> EnableIf_t< IsComputation_v<MT2>, UniLowerMatrix& >
1343 {
1344  if( IsUpper_v<MT2> || IsUniTriangular_v<MT2> ||
1345  ( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) ) {
1346  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1347  }
1348 
1349  if( IsStrictlyLower_v<MT2> ) {
1350  matrix_ -= ~rhs;
1351  }
1352  else {
1353  const ResultType_t<MT2> tmp( ~rhs );
1354 
1355  if( !isStrictlyLower( tmp ) ) {
1356  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1357  }
1358 
1359  matrix_ -= decllow( tmp );
1360  }
1361 
1362  if( !IsStrictlyLower_v<MT2> )
1363  resetUpper();
1364 
1365  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1366  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1367 
1368  return *this;
1369 }
1371 //*************************************************************************************************
1372 
1373 
1374 //*************************************************************************************************
1387 template< typename MT // Type of the adapted sparse matrix
1388  , bool SO > // Storage order of the adapted sparse matrix
1389 template< typename MT2 // Type of the right-hand side matrix
1390  , bool SO2 > // Storage order of the right-hand side matrix
1391 inline auto UniLowerMatrix<MT,SO,false>::operator%=( const Matrix<MT2,SO2>& rhs )
1392  -> UniLowerMatrix&
1393 {
1394  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1395  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1396  }
1397 
1398  If_t< IsComputation_v<MT2>, ResultType_t<MT2>, const MT2& > tmp( ~rhs );
1399 
1400  for( size_t i=0UL; i<(~rhs).rows(); ++i ) {
1401  if( !isOne( tmp(i,i) ) ) {
1402  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to unilower matrix" );
1403  }
1404  }
1405 
1406  matrix_ %= tmp;
1407 
1408  if( !IsUniLower_v<MT2> )
1409  resetUpper();
1410 
1411  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1412  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1413 
1414  return *this;
1415 }
1417 //*************************************************************************************************
1418 
1419 
1420 
1421 
1422 //=================================================================================================
1423 //
1424 // UTILITY FUNCTIONS
1425 //
1426 //=================================================================================================
1427 
1428 //*************************************************************************************************
1434 template< typename MT // Type of the adapted sparse matrix
1435  , bool SO > // Storage order of the adapted sparse matrix
1436 inline size_t UniLowerMatrix<MT,SO,false>::rows() const noexcept
1437 {
1438  return matrix_.rows();
1439 }
1441 //*************************************************************************************************
1442 
1443 
1444 //*************************************************************************************************
1450 template< typename MT // Type of the adapted sparse matrix
1451  , bool SO > // Storage order of the adapted sparse matrix
1452 inline size_t UniLowerMatrix<MT,SO,false>::columns() const noexcept
1453 {
1454  return matrix_.columns();
1455 }
1457 //*************************************************************************************************
1458 
1459 
1460 //*************************************************************************************************
1466 template< typename MT // Type of the adapted sparse matrix
1467  , bool SO > // Storage order of the adapted sparse matrix
1468 inline size_t UniLowerMatrix<MT,SO,false>::capacity() const noexcept
1469 {
1470  return matrix_.capacity();
1471 }
1473 //*************************************************************************************************
1474 
1475 
1476 //*************************************************************************************************
1488 template< typename MT // Type of the adapted sparse matrix
1489  , bool SO > // Storage order of the adapted sparse matrix
1490 inline size_t UniLowerMatrix<MT,SO,false>::capacity( size_t i ) const noexcept
1491 {
1492  return matrix_.capacity(i);
1493 }
1495 //*************************************************************************************************
1496 
1497 
1498 //*************************************************************************************************
1504 template< typename MT // Type of the adapted sparse matrix
1505  , bool SO > // Storage order of the adapted sparse matrix
1506 inline size_t UniLowerMatrix<MT,SO,false>::nonZeros() const
1507 {
1508  return matrix_.nonZeros();
1509 }
1511 //*************************************************************************************************
1512 
1513 
1514 //*************************************************************************************************
1526 template< typename MT // Type of the adapted sparse matrix
1527  , bool SO > // Storage order of the adapted sparse matrix
1528 inline size_t UniLowerMatrix<MT,SO,false>::nonZeros( size_t i ) const
1529 {
1530  return matrix_.nonZeros(i);
1531 }
1533 //*************************************************************************************************
1534 
1535 
1536 //*************************************************************************************************
1542 template< typename MT // Type of the adapted sparse matrix
1543  , bool SO > // Storage order of the adapted sparse matrix
1545 {
1546  if( SO ) {
1547  for( size_t j=0UL; j<columns(); ++j ) {
1548  matrix_.erase( j, matrix_.lowerBound(j+1UL,j), matrix_.end(j) );
1549  }
1550  }
1551  else {
1552  for( size_t i=1UL; i<rows(); ++i ) {
1553  matrix_.erase( i, matrix_.begin(i), matrix_.lowerBound(i,i) );
1554  }
1555  }
1556 }
1558 //*************************************************************************************************
1559 
1560 
1561 //*************************************************************************************************
1574 template< typename MT // Type of the adapted sparse matrix
1575  , bool SO > // Storage order of the adapted sparse matrix
1576 inline void UniLowerMatrix<MT,SO,false>::reset( size_t i )
1577 {
1578  if( SO ) {
1579  matrix_.erase( i, matrix_.lowerBound(i+1UL,i), matrix_.end(i) );
1580  }
1581  else {
1582  matrix_.erase( i, matrix_.begin(i), matrix_.lowerBound(i,i) );
1583  }
1584 }
1586 //*************************************************************************************************
1587 
1588 
1589 //*************************************************************************************************
1597 template< typename MT // Type of the adapted sparse matrix
1598  , bool SO > // Storage order of the adapted sparse matrix
1600 {
1601  using blaze::clear;
1602 
1603  if( IsResizable_v<MT> ) {
1604  clear( matrix_ );
1605  }
1606  else {
1607  reset();
1608  }
1609 }
1611 //*************************************************************************************************
1612 
1613 
1614 //*************************************************************************************************
1629 template< typename MT // Type of the adapted sparse matrix
1630  , bool SO > // Storage order of the adapted sparse matrix
1631 void UniLowerMatrix<MT,SO,false>::resize( size_t n, bool preserve )
1632 {
1634 
1635  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square unilower matrix detected" );
1636 
1637  const size_t oldsize( matrix_.rows() );
1638 
1639  matrix_.resize( n, n, preserve );
1640 
1641  if( n > oldsize ) {
1642  for( size_t i=oldsize; i<n; ++i )
1643  matrix_.insert( i, i, ElementType(1) );
1644  }
1645 }
1647 //*************************************************************************************************
1648 
1649 
1650 //*************************************************************************************************
1661 template< typename MT // Type of the adapted sparse matrix
1662  , bool SO > // Storage order of the adapted sparse matrix
1663 inline void UniLowerMatrix<MT,SO,false>::reserve( size_t nonzeros )
1664 {
1665  matrix_.reserve( nonzeros );
1666 }
1668 //*************************************************************************************************
1669 
1670 
1671 //*************************************************************************************************
1685 template< typename MT // Type of the adapted sparse matrix
1686  , bool SO > // Storage order of the adapted sparse matrix
1687 inline void UniLowerMatrix<MT,SO,false>::reserve( size_t i, size_t nonzeros )
1688 {
1689  matrix_.reserve( i, nonzeros );
1690 }
1692 //*************************************************************************************************
1693 
1694 
1695 //*************************************************************************************************
1706 template< typename MT // Type of the adapted sparse matrix
1707  , bool SO > // Storage order of the adapted sparse matrix
1708 inline void UniLowerMatrix<MT,SO,false>::trim()
1709 {
1710  matrix_.trim();
1711 }
1713 //*************************************************************************************************
1714 
1715 
1716 //*************************************************************************************************
1728 template< typename MT // Type of the adapted sparse matrix
1729  , bool SO > // Storage order of the adapted sparse matrix
1730 inline void UniLowerMatrix<MT,SO,false>::trim( size_t i )
1731 {
1732  matrix_.trim( i );
1733 }
1735 //*************************************************************************************************
1736 
1737 
1738 //*************************************************************************************************
1748 template< typename MT // Type of the adapted sparse matrix
1749  , bool SO > // Storage order of the adapted sparse matrix
1751 {
1752  matrix_.shrinkToFit();
1753 }
1755 //*************************************************************************************************
1756 
1757 
1758 //*************************************************************************************************
1765 template< typename MT // Type of the adapted sparse matrix
1766  , bool SO > // Storage order of the adapted sparse matrix
1767 inline void UniLowerMatrix<MT,SO,false>::swap( UniLowerMatrix& m ) noexcept
1768 {
1769  using std::swap;
1770 
1771  swap( matrix_, m.matrix_ );
1772 }
1774 //*************************************************************************************************
1775 
1776 
1777 //*************************************************************************************************
1788 template< typename MT // Type of the adapted dense matrix
1789  , bool SO > // Storage order of the adapted dense matrix
1790 inline constexpr size_t UniLowerMatrix<MT,SO,false>::maxNonZeros() noexcept
1791 {
1793 
1794  return maxNonZeros( Size_v<MT,0UL> );
1795 }
1797 //*************************************************************************************************
1798 
1799 
1800 //*************************************************************************************************
1810 template< typename MT // Type of the adapted dense matrix
1811  , bool SO > // Storage order of the adapted dense matrix
1812 inline constexpr size_t UniLowerMatrix<MT,SO,false>::maxNonZeros( size_t n ) noexcept
1813 {
1814  return ( ( n + 1UL ) * n ) / 2UL;
1815 }
1817 //*************************************************************************************************
1818 
1819 
1820 //*************************************************************************************************
1826 template< typename MT // Type of the adapted dense matrix
1827  , bool SO > // Storage order of the adapted dense matrix
1828 inline void UniLowerMatrix<MT,SO,false>::resetUpper()
1829 {
1830  if( SO ) {
1831  for( size_t j=1UL; j<columns(); ++j )
1832  matrix_.erase( j, matrix_.begin( j ), matrix_.lowerBound( j, j ) );
1833  }
1834  else {
1835  for( size_t i=0UL; i<rows(); ++i )
1836  matrix_.erase( i, matrix_.upperBound( i, i ), matrix_.end( i ) );
1837  }
1838 }
1840 //*************************************************************************************************
1841 
1842 
1843 
1844 
1845 //=================================================================================================
1846 //
1847 // INSERTION FUNCTIONS
1848 //
1849 //=================================================================================================
1850 
1851 //*************************************************************************************************
1867 template< typename MT // Type of the adapted sparse matrix
1868  , bool SO > // Storage order of the adapted sparse matrix
1869 inline typename UniLowerMatrix<MT,SO,false>::Iterator
1870  UniLowerMatrix<MT,SO,false>::set( size_t i, size_t j, const ElementType& value )
1871 {
1872  if( i <= j ) {
1873  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal or upper matrix element" );
1874  }
1875 
1876  return Iterator( matrix_.set( i, j, value ), ( SO ? j : i ) );
1877 }
1879 //*************************************************************************************************
1880 
1881 
1882 //*************************************************************************************************
1899 template< typename MT // Type of the adapted sparse matrix
1900  , bool SO > // Storage order of the adapted sparse matrix
1901 inline typename UniLowerMatrix<MT,SO,false>::Iterator
1902  UniLowerMatrix<MT,SO,false>::insert( size_t i, size_t j, const ElementType& value )
1903 {
1904  if( i <= j ) {
1905  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal or upper matrix element" );
1906  }
1907 
1908  return Iterator( matrix_.insert( i, j, value ), ( SO ? j : i ) );
1909 }
1911 //*************************************************************************************************
1912 
1913 
1914 //*************************************************************************************************
1964 template< typename MT // Type of the adapted sparse matrix
1965  , bool SO > // Storage order of the adapted sparse matrix
1966 inline void UniLowerMatrix<MT,SO,false>::append( size_t i, size_t j, const ElementType& value, bool check )
1967 {
1968  if( i <= j ) {
1969  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal or upper matrix element" );
1970  }
1971 
1972  if( !check || !isDefault<strict>( value ) )
1973  matrix_.insert( i, j, value );
1974 }
1976 //*************************************************************************************************
1977 
1978 
1979 //*************************************************************************************************
1993 template< typename MT // Type of the adapted sparse matrix
1994  , bool SO > // Storage order of the adapted sparse matrix
1995 inline void UniLowerMatrix<MT,SO,false>::finalize( size_t i )
1996 {
1997  matrix_.trim( i );
1998 }
2000 //*************************************************************************************************
2001 
2002 
2003 
2004 
2005 //=================================================================================================
2006 //
2007 // ERASE FUNCTIONS
2008 //
2009 //=================================================================================================
2010 
2011 //*************************************************************************************************
2023 template< typename MT // Type of the adapted sparse matrix
2024  , bool SO > // Storage order of the adapted sparse matrix
2025 inline void UniLowerMatrix<MT,SO,false>::erase( size_t i, size_t j )
2026 {
2027  if( i == j ) {
2028  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2029  }
2030 
2031  matrix_.erase( i, j );
2032 }
2034 //*************************************************************************************************
2035 
2036 
2037 //*************************************************************************************************
2051 template< typename MT // Type of the adapted sparse matrix
2052  , bool SO > // Storage order of the adapted sparse matrix
2053 inline typename UniLowerMatrix<MT,SO,false>::Iterator
2054  UniLowerMatrix<MT,SO,false>::erase( size_t i, Iterator pos )
2055 {
2056  if( pos != matrix_.end(i) && pos->index() == i ) {
2057  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2058  }
2059 
2060  return Iterator( matrix_.erase( i, pos.base() ), i );
2061 }
2063 //*************************************************************************************************
2064 
2065 
2066 //*************************************************************************************************
2081 template< typename MT // Type of the adapted sparse matrix
2082  , bool SO > // Storage order of the adapted sparse matrix
2083 inline typename UniLowerMatrix<MT,SO,false>::Iterator
2084  UniLowerMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last )
2085 {
2086  if( first == last )
2087  return last;
2088 
2089  if( ( !SO && last.base() == matrix_.end(i) ) ||
2090  ( SO && first.base() == matrix_.begin(i) ) ) {
2091  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2092  }
2093 
2094  return Iterator( matrix_.erase( i, first.base(), last.base() ), i );
2095 }
2097 //*************************************************************************************************
2098 
2099 
2100 //*************************************************************************************************
2122 template< typename MT // Type of the adapted sparse matrix
2123  , bool SO > // Storage order of the adapted sparse matrix
2124 template< typename Pred > // Type of the unary predicate
2125 inline void UniLowerMatrix<MT,SO,false>::erase( Pred predicate )
2126 {
2127  if( SO ) {
2128  for( size_t j=0UL; (j+1UL) < columns(); ++j ) {
2129  matrix_.erase( j, matrix_.lowerBound(j+1UL,j), matrix_.end(j), predicate );
2130  }
2131  }
2132  else {
2133  for( size_t i=1UL; i<rows(); ++i ) {
2134  matrix_.erase( i, matrix_.begin(i), matrix_.find(i,i), predicate );
2135  }
2136  }
2137 
2138  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2139 }
2141 //*************************************************************************************************
2142 
2143 
2144 //*************************************************************************************************
2175 template< typename MT // Type of the adapted sparse matrix
2176  , bool SO > // Storage order of the adapted sparse matrix
2177 template< typename Pred > // Type of the unary predicate
2178 inline void UniLowerMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2179 {
2180  if( first == last )
2181  return;
2182 
2183  if( ( !SO && last.base() == matrix_.end(i) && predicate( ElementType(1) ) ) ||
2184  ( SO && first.base() == matrix_.begin(i) && predicate( ElementType(1) ) ) ) {
2185  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2186  }
2187 
2188  matrix_.erase( i, first.base(), last.base(), predicate );
2189 
2190  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2191 }
2193 //*************************************************************************************************
2194 
2195 
2196 
2197 
2198 //=================================================================================================
2199 //
2200 // LOOKUP FUNCTIONS
2201 //
2202 //=================================================================================================
2203 
2204 //*************************************************************************************************
2220 template< typename MT // Type of the adapted sparse matrix
2221  , bool SO > // Storage order of the adapted sparse matrix
2222 inline typename UniLowerMatrix<MT,SO,false>::Iterator
2223  UniLowerMatrix<MT,SO,false>::find( size_t i, size_t j )
2224 {
2225  return Iterator( matrix_.find( i, j ), ( SO ? j : i ) );
2226 }
2228 //*************************************************************************************************
2229 
2230 
2231 //*************************************************************************************************
2247 template< typename MT // Type of the adapted sparse matrix
2248  , bool SO > // Storage order of the adapted sparse matrix
2249 inline typename UniLowerMatrix<MT,SO,false>::ConstIterator
2250  UniLowerMatrix<MT,SO,false>::find( size_t i, size_t j ) const
2251 {
2252  return matrix_.find( i, j );
2253 }
2255 //*************************************************************************************************
2256 
2257 
2258 //*************************************************************************************************
2274 template< typename MT // Type of the adapted sparse matrix
2275  , bool SO > // Storage order of the adapted sparse matrix
2276 inline typename UniLowerMatrix<MT,SO,false>::Iterator
2277  UniLowerMatrix<MT,SO,false>::lowerBound( size_t i, size_t j )
2278 {
2279  return Iterator( matrix_.lowerBound( i, j ), ( SO ? j : i ) );
2280 }
2282 //*************************************************************************************************
2283 
2284 
2285 //*************************************************************************************************
2301 template< typename MT // Type of the adapted sparse matrix
2302  , bool SO > // Storage order of the adapted sparse matrix
2303 inline typename UniLowerMatrix<MT,SO,false>::ConstIterator
2304  UniLowerMatrix<MT,SO,false>::lowerBound( size_t i, size_t j ) const
2305 {
2306  return matrix_.lowerBound( i, j );
2307 }
2309 //*************************************************************************************************
2310 
2311 
2312 //*************************************************************************************************
2328 template< typename MT // Type of the adapted sparse matrix
2329  , bool SO > // Storage order of the adapted sparse matrix
2330 inline typename UniLowerMatrix<MT,SO,false>::Iterator
2331  UniLowerMatrix<MT,SO,false>::upperBound( size_t i, size_t j )
2332 {
2333  return Iterator( matrix_.upperBound( i, j ), ( SO ? j : i ) );
2334 }
2336 //*************************************************************************************************
2337 
2338 
2339 //*************************************************************************************************
2355 template< typename MT // Type of the adapted sparse matrix
2356  , bool SO > // Storage order of the adapted sparse matrix
2357 inline typename UniLowerMatrix<MT,SO,false>::ConstIterator
2358  UniLowerMatrix<MT,SO,false>::upperBound( size_t i, size_t j ) const
2359 {
2360  return matrix_.upperBound( i, j );
2361 }
2363 //*************************************************************************************************
2364 
2365 
2366 
2367 
2368 //=================================================================================================
2369 //
2370 // DEBUGGING FUNCTIONS
2371 //
2372 //=================================================================================================
2373 
2374 //*************************************************************************************************
2384 template< typename MT // Type of the adapted sparse matrix
2385  , bool SO > // Storage order of the adapted sparse matrix
2386 inline bool UniLowerMatrix<MT,SO,false>::isIntact() const noexcept
2387 {
2388  using blaze::isIntact;
2389 
2390  return ( isIntact( matrix_ ) && isUniLower( matrix_ ) );
2391 }
2393 //*************************************************************************************************
2394 
2395 
2396 
2397 
2398 //=================================================================================================
2399 //
2400 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2401 //
2402 //=================================================================================================
2403 
2404 //*************************************************************************************************
2415 template< typename MT // Type of the adapted sparse matrix
2416  , bool SO > // Storage order of the adapted sparse matrix
2417 template< typename Other > // Data type of the foreign expression
2418 inline bool UniLowerMatrix<MT,SO,false>::canAlias( const Other* alias ) const noexcept
2419 {
2420  return matrix_.canAlias( alias );
2421 }
2423 //*************************************************************************************************
2424 
2425 
2426 //*************************************************************************************************
2437 template< typename MT // Type of the adapted sparse matrix
2438  , bool SO > // Storage order of the adapted sparse matrix
2439 template< typename Other > // Data type of the foreign expression
2440 inline bool UniLowerMatrix<MT,SO,false>::isAliased( const Other* alias ) const noexcept
2441 {
2442  return matrix_.isAliased( alias );
2443 }
2445 //*************************************************************************************************
2446 
2447 
2448 //*************************************************************************************************
2459 template< typename MT // Type of the adapted sparse matrix
2460  , bool SO > // Storage order of the adapted sparse matrix
2461 inline bool UniLowerMatrix<MT,SO,false>::canSMPAssign() const noexcept
2462 {
2463  return matrix_.canSMPAssign();
2464 }
2466 //*************************************************************************************************
2467 
2468 } // namespace blaze
2469 
2470 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSFORMATION_TYPE(T)
Constraint on the data type.In case the given data type T is a transformation expression (i....
Definition: Transformation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type,...
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for the implementation of the base template of the UniLowerMatrix.
Header file for auxiliary alias declarations.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
constexpr ptrdiff_t Size_v
Auxiliary variable template for the Size type trait.The Size_v variable template provides a convenien...
Definition: Size.h:176
Constraint on the data type.
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1968
Constraint on the data type.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:750
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.In case the given data type T is not a dense or sparse matrix type and in...
Definition: StorageOrder.h:63
#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
Constraint on the data type.
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:1881
void shrinkToFit(Matrix< MT, SO > &matrix)
Requesting the removal of unused capacity.
Definition: Matrix.h:799
Header file for all adaptor forward declarations.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type,...
Definition: Volatile.h:79
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
Header file for the extended initializer_list functionality.
Constraint on the data type.
Header file for the IsUniLower type trait.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:482
MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:416
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the SparseMatrix base class.
Header file for utility functions for sparse matrices.
Header file for the IsSquare type trait.
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 DisableIf class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_CONSTRAINT_MUST_BE_STATIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a static data type,...
Definition: Static.h:61
Compile time assertion.
decltype(auto) operator *(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9091
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
Constraint on the data type.
decltype(auto) decllow(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as lower.
Definition: DMatDeclLowExpr.h:1001
Header file for the IsUniTriangular type trait.
Header file for the IsStrictlyTriangular type trait.
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UPPER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a upper triangular matrix type,...
Definition: Upper.h:81
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1198
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:738
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
Constraint on the data type.
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:615
Header file for the UniLowerElement class.
Header file for the UniLowerProxy class.
Header file for the isOne shim.
Header file for the UniLowerValue class.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type,...
Definition: Symmetric.h:79
Header file for run time assertion macros.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNIFORM_TYPE(T)
Constraint on the data type.In case the given data type T is a uniform vector or matrix type,...
Definition: Uniform.h:81
Constraint on the data type.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_LOWER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower triangular matrix type,...
Definition: Lower.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type,...
Definition: Reference.h:79
bool isOne(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 1.
Definition: DiagonalProxy.h:697
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:282
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:75
Constraint on the data type.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VIEW_TYPE(T)
Constraint on the data type.In case the given data type T is a view type (i.e. a subvector,...
Definition: View.h:81
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
#define BLAZE_CONSTRAINT_MUST_BE_RESIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not resizable, i.e. does not have a 'res...
Definition: Resizable.h:61
Header file for the IsComputation type trait class.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type,...
Definition: Hermitian.h:79
Header file for the IsUpper type trait.
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:951
Header file for the IsResizable type trait.
Constraint on the data type.
Header file for the Size type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type,...
Definition: SparseMatrix.h:61
Header file for the clear shim.