Blaze  3.6
Sparse.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_ADAPTORS_UNIUPPERMATRIX_SPARSE_H_
36 #define _BLAZE_MATH_ADAPTORS_UNIUPPERMATRIX_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 UniUpperMatrix<MT,SO,false>
113  : public SparseMatrix< UniUpperMatrix<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 = UniUpperMatrix<MT,SO,false>;
125  using BaseType = SparseMatrix<This,SO>;
126  using ResultType = This;
127  using OppositeType = UniUpperMatrix<OT,!SO,false>;
128  using TransposeType = UniLowerMatrix<TT,!SO,false>;
129  using ElementType = ET;
130  using ReturnType = ReturnType_t<MT>;
131  using CompositeType = const This&;
132  using Reference = UniUpperProxy<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 = UniUpperMatrix< 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 = UniUpperMatrix< 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 = UniUpperElement<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 upper 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 upper 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 UniUpperMatrix();
315  explicit inline UniUpperMatrix( size_t n );
316  explicit inline UniUpperMatrix( size_t n, size_t nonzeros );
317  explicit inline UniUpperMatrix( size_t n, const std::vector<size_t>& nonzeros );
318  inline UniUpperMatrix( initializer_list< initializer_list<ElementType> > list );
319 
320  inline UniUpperMatrix( const UniUpperMatrix& m );
321  inline UniUpperMatrix( UniUpperMatrix&& m ) noexcept;
322 
323  template< typename MT2, bool SO2 >
324  inline UniUpperMatrix( const Matrix<MT2,SO2>& m );
326  //**********************************************************************************************
327 
328  //**Destructor**********************************************************************************
331  ~UniUpperMatrix() = 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 UniUpperMatrix& operator=( initializer_list< initializer_list<ElementType> > list );
355 
356  inline UniUpperMatrix& operator=( const UniUpperMatrix& rhs );
357  inline UniUpperMatrix& operator=( UniUpperMatrix&& rhs ) noexcept;
358 
359  template< typename MT2, bool SO2 >
360  inline auto operator=( const Matrix<MT2,SO2>& rhs )
361  -> DisableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >;
362 
363  template< typename MT2, bool SO2 >
364  inline auto operator=( const Matrix<MT2,SO2>& rhs )
365  -> EnableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >;
366 
367  template< typename MT2, bool SO2 >
368  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
369  -> DisableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >;
370 
371  template< typename MT2, bool SO2 >
372  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
373  -> EnableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >;
374 
375  template< typename MT2, bool SO2 >
376  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
377  -> DisableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >;
378 
379  template< typename MT2, bool SO2 >
380  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
381  -> EnableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >;
382 
383  template< typename MT2, bool SO2 >
384  inline auto operator%=( const Matrix<MT2,SO2>& rhs ) -> UniUpperMatrix&;
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( UniUpperMatrix& 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 resetLower();
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( UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::UniUpperMatrix()
526  : matrix_() // The adapted sparse matrix
527 {
528  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::UniUpperMatrix( 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 uniupper 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 UniUpperMatrix<MT,SO,false>::UniUpperMatrix( 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 uniupper 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 UniUpperMatrix<MT,SO,false>::UniUpperMatrix( 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 uniupper 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 UniUpperMatrix<MT,SO,false>::UniUpperMatrix( initializer_list< initializer_list<ElementType> > list )
652  : matrix_( list ) // The adapted sparse matrix
653 {
654  if( !isUniUpper( matrix_ ) ) {
655  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of uniupper 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 UniUpperMatrix<MT,SO,false>::UniUpperMatrix( const UniUpperMatrix& m )
673  : matrix_( m.matrix_ ) // The adapted sparse matrix
674 {
675  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::UniUpperMatrix( UniUpperMatrix&& m ) noexcept
691  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
692 {
693  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::UniUpperMatrix( const Matrix<MT2,SO2>& m )
715  : matrix_( ~m ) // The adapted sparse matrix
716 {
717  if( !IsUniUpper_v<MT2> && !isUniUpper( matrix_ ) ) {
718  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of uniupper matrix" );
719  }
720 
721  if( !IsUniUpper_v<MT2> )
722  resetLower();
723 
724  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::Reference
758  UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::ConstReference
788  UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::Reference
819  UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::ConstReference
853  UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::ConstIterator
905  UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::ConstIterator
928  UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::ConstIterator
974  UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::ConstIterator
997  UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>&
1041  UniUpperMatrix<MT,SO,false>::operator=( initializer_list< initializer_list<ElementType> > list )
1042 {
1043  const InitializerMatrix<ElementType> tmp( list, list.size() );
1044 
1045  if( !isUniUpper( tmp ) ) {
1046  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1047  }
1048 
1049  matrix_ = list;
1050 
1051  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>&
1073  UniUpperMatrix<MT,SO,false>::operator=( const UniUpperMatrix& rhs )
1074 {
1075  matrix_ = rhs.matrix_;
1076 
1077  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>&
1096  UniUpperMatrix<MT,SO,false>::operator=( UniUpperMatrix&& rhs ) noexcept
1097 {
1098  matrix_ = std::move( rhs.matrix_ );
1099 
1100  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1127  -> DisableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >
1128 {
1129  if( IsStrictlyTriangular_v<MT2> || ( !IsUniUpper_v<MT2> && !isUniUpper( ~rhs ) ) ) {
1130  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1131  }
1132 
1133  matrix_ = declupp( ~rhs );
1134 
1135  if( !IsUniUpper_v<MT2> )
1136  resetLower();
1137 
1138  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1165  -> EnableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >
1166 {
1167  if( IsStrictlyTriangular_v<MT2> || ( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) ) {
1168  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1169  }
1170 
1171  if( IsUniUpper_v<MT2> ) {
1172  matrix_ = ~rhs;
1173  }
1174  else {
1175  MT tmp( ~rhs );
1176 
1177  if( !isUniUpper( tmp ) ) {
1178  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1179  }
1180 
1181  matrix_ = std::move( tmp );
1182  }
1183 
1184  if( !IsUniUpper_v<MT2> )
1185  resetLower();
1186 
1187  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1214  -> DisableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >
1215 {
1216  if( IsLower_v<MT2> || IsUniTriangular_v<MT2> ||
1217  ( !IsStrictlyUpper_v<MT2> && !isStrictlyUpper( ~rhs ) ) ) {
1218  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1219  }
1220 
1221  matrix_ += declupp( ~rhs );
1222 
1223  if( !IsStrictlyUpper_v<MT2> )
1224  resetLower();
1225 
1226  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1253  -> EnableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >
1254 {
1255  if( IsLower_v<MT2> || IsUniTriangular_v<MT2> ||
1256  ( IsSquare_v<MT2> && !isSquare( ~rhs ) ) ) {
1257  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1258  }
1259 
1260  if( IsStrictlyUpper_v<MT2> ) {
1261  matrix_ += ~rhs;
1262  }
1263  else {
1264  const ResultType_t<MT2> tmp( ~rhs );
1265 
1266  if( !isStrictlyUpper( tmp ) ) {
1267  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1268  }
1269 
1270  matrix_ += declupp( tmp );
1271  }
1272 
1273  if( !IsStrictlyUpper_v<MT2> )
1274  resetLower();
1275 
1276  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1303  -> DisableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >
1304 {
1305  if( IsLower_v<MT2> || IsUniTriangular_v<MT2> ||
1306  ( !IsStrictlyUpper_v<MT2> && !isStrictlyUpper( ~rhs ) ) ) {
1307  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1308  }
1309 
1310  matrix_ -= declupp( ~rhs );
1311 
1312  if( !IsStrictlyUpper_v<MT2> )
1313  resetLower();
1314 
1315  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1342  -> EnableIf_t< IsComputation_v<MT2>, UniUpperMatrix& >
1343 {
1344  if( IsLower_v<MT2> || IsUniTriangular_v<MT2> ||
1345  ( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) ) {
1346  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1347  }
1348 
1349  if( IsStrictlyUpper_v<MT2> ) {
1350  matrix_ -= ~rhs;
1351  }
1352  else {
1353  const ResultType_t<MT2> tmp( ~rhs );
1354 
1355  if( !isStrictlyUpper( tmp ) ) {
1356  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper matrix" );
1357  }
1358 
1359  matrix_ -= declupp( tmp );
1360  }
1361 
1362  if( !IsStrictlyUpper_v<MT2> )
1363  resetLower();
1364 
1365  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<MT,SO,false>::operator%=( const Matrix<MT2,SO2>& rhs )
1392  -> UniUpperMatrix&
1393 {
1394  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1395  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to uniupper 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 uniupper matrix" );
1403  }
1404  }
1405 
1406  matrix_ %= tmp;
1407 
1408  if( !IsUniUpper_v<MT2> )
1409  resetLower();
1410 
1411  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<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=1UL; j<columns(); ++j ) {
1548  matrix_.erase( j, matrix_.begin(j), matrix_.lowerBound(j,j) );
1549  }
1550  }
1551  else {
1552  for( size_t i=0UL; i<rows(); ++i ) {
1553  matrix_.erase( i, matrix_.lowerBound(i,i+1UL), matrix_.end(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 UniUpperMatrix<MT,SO,false>::reset( size_t i )
1577 {
1578  if( SO ) {
1579  matrix_.erase( i, matrix_.begin(i), matrix_.lowerBound(i,i) );
1580  }
1581  else {
1582  matrix_.erase( i, matrix_.lowerBound(i,i+1UL), matrix_.end(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 UniUpperMatrix<MT,SO,false>::resize( size_t n, bool preserve )
1632 {
1634 
1635  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square uniupper 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 UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::swap( UniUpperMatrix& 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 UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::resetLower()
1829 {
1830  if( SO ) {
1831  for( size_t j=0UL; j<columns(); ++j )
1832  matrix_.erase( j, matrix_.upperBound( j, j ), matrix_.end( j ) );
1833  }
1834  else {
1835  for( size_t i=1UL; i<rows(); ++i )
1836  matrix_.erase( i, matrix_.begin( i ), matrix_.lowerBound( i, 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 UniUpperMatrix<MT,SO,false>::Iterator
1870  UniUpperMatrix<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 lower 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 UniUpperMatrix<MT,SO,false>::Iterator
1902  UniUpperMatrix<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 lower 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 UniUpperMatrix<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 lower 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 UniUpperMatrix<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 UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::Iterator
2054  UniUpperMatrix<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 UniUpperMatrix<MT,SO,false>::Iterator
2084  UniUpperMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last )
2085 {
2086  if( first == last )
2087  return last;
2088 
2089  if( ( !SO && first.base() == matrix_.begin(i) ) ||
2090  ( SO && last.base() == matrix_.end(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 UniUpperMatrix<MT,SO,false>::erase( Pred predicate )
2126 {
2127  if( SO ) {
2128  for( size_t j=1UL; j<columns(); ++j ) {
2129  matrix_.erase( j, matrix_.begin(j), matrix_.find(j,j), predicate );
2130  }
2131  }
2132  else {
2133  for( size_t i=0UL; (i+1UL) < rows(); ++i ) {
2134  matrix_.erase( i, matrix_.lowerBound(i,i+1UL), matrix_.end(i), predicate );
2135  }
2136  }
2137 
2138  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2139 }
2141 //*************************************************************************************************
2142 
2143 
2144 //*************************************************************************************************
2172 template< typename MT // Type of the adapted sparse matrix
2173  , bool SO > // Storage order of the adapted sparse matrix
2174 template< typename Pred > // Type of the unary predicate
2175 inline void UniUpperMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2176 {
2177  if( first == last )
2178  return;
2179 
2180  if( ( !SO && first.base() == matrix_.begin(i) && predicate( ElementType(1) ) ) ||
2181  ( SO && last.base() == matrix_.end(i) && predicate( ElementType(1) ) ) ) {
2182  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2183  }
2184 
2185  matrix_.erase( i, first.base(), last.base(), predicate );
2186 
2187  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2188 }
2190 //*************************************************************************************************
2191 
2192 
2193 
2194 
2195 //=================================================================================================
2196 //
2197 // LOOKUP FUNCTIONS
2198 //
2199 //=================================================================================================
2200 
2201 //*************************************************************************************************
2217 template< typename MT // Type of the adapted sparse matrix
2218  , bool SO > // Storage order of the adapted sparse matrix
2219 inline typename UniUpperMatrix<MT,SO,false>::Iterator
2220  UniUpperMatrix<MT,SO,false>::find( size_t i, size_t j )
2221 {
2222  return Iterator( matrix_.find( i, j ), ( SO ? j : i ) );
2223 }
2225 //*************************************************************************************************
2226 
2227 
2228 //*************************************************************************************************
2244 template< typename MT // Type of the adapted sparse matrix
2245  , bool SO > // Storage order of the adapted sparse matrix
2246 inline typename UniUpperMatrix<MT,SO,false>::ConstIterator
2247  UniUpperMatrix<MT,SO,false>::find( size_t i, size_t j ) const
2248 {
2249  return matrix_.find( i, j );
2250 }
2252 //*************************************************************************************************
2253 
2254 
2255 //*************************************************************************************************
2271 template< typename MT // Type of the adapted sparse matrix
2272  , bool SO > // Storage order of the adapted sparse matrix
2273 inline typename UniUpperMatrix<MT,SO,false>::Iterator
2274  UniUpperMatrix<MT,SO,false>::lowerBound( size_t i, size_t j )
2275 {
2276  return Iterator( matrix_.lowerBound( i, j ), ( SO ? j : i ) );
2277 }
2279 //*************************************************************************************************
2280 
2281 
2282 //*************************************************************************************************
2298 template< typename MT // Type of the adapted sparse matrix
2299  , bool SO > // Storage order of the adapted sparse matrix
2300 inline typename UniUpperMatrix<MT,SO,false>::ConstIterator
2301  UniUpperMatrix<MT,SO,false>::lowerBound( size_t i, size_t j ) const
2302 {
2303  return matrix_.lowerBound( i, j );
2304 }
2306 //*************************************************************************************************
2307 
2308 
2309 //*************************************************************************************************
2325 template< typename MT // Type of the adapted sparse matrix
2326  , bool SO > // Storage order of the adapted sparse matrix
2327 inline typename UniUpperMatrix<MT,SO,false>::Iterator
2328  UniUpperMatrix<MT,SO,false>::upperBound( size_t i, size_t j )
2329 {
2330  return Iterator( matrix_.upperBound( i, j ), ( SO ? j : i ) );
2331 }
2333 //*************************************************************************************************
2334 
2335 
2336 //*************************************************************************************************
2352 template< typename MT // Type of the adapted sparse matrix
2353  , bool SO > // Storage order of the adapted sparse matrix
2354 inline typename UniUpperMatrix<MT,SO,false>::ConstIterator
2355  UniUpperMatrix<MT,SO,false>::upperBound( size_t i, size_t j ) const
2356 {
2357  return matrix_.upperBound( i, j );
2358 }
2360 //*************************************************************************************************
2361 
2362 
2363 
2364 
2365 //=================================================================================================
2366 //
2367 // DEBUGGING FUNCTIONS
2368 //
2369 //=================================================================================================
2370 
2371 //*************************************************************************************************
2381 template< typename MT // Type of the adapted sparse matrix
2382  , bool SO > // Storage order of the adapted sparse matrix
2383 inline bool UniUpperMatrix<MT,SO,false>::isIntact() const noexcept
2384 {
2385  using blaze::isIntact;
2386 
2387  return ( isIntact( matrix_ ) && isUniUpper( matrix_ ) );
2388 }
2390 //*************************************************************************************************
2391 
2392 
2393 
2394 
2395 //=================================================================================================
2396 //
2397 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2398 //
2399 //=================================================================================================
2400 
2401 //*************************************************************************************************
2412 template< typename MT // Type of the adapted sparse matrix
2413  , bool SO > // Storage order of the adapted sparse matrix
2414 template< typename Other > // Data type of the foreign expression
2415 inline bool UniUpperMatrix<MT,SO,false>::canAlias( const Other* alias ) const noexcept
2416 {
2417  return matrix_.canAlias( alias );
2418 }
2420 //*************************************************************************************************
2421 
2422 
2423 //*************************************************************************************************
2434 template< typename MT // Type of the adapted sparse matrix
2435  , bool SO > // Storage order of the adapted sparse matrix
2436 template< typename Other > // Data type of the foreign expression
2437 inline bool UniUpperMatrix<MT,SO,false>::isAliased( const Other* alias ) const noexcept
2438 {
2439  return matrix_.isAliased( alias );
2440 }
2442 //*************************************************************************************************
2443 
2444 
2445 //*************************************************************************************************
2456 template< typename MT // Type of the adapted sparse matrix
2457  , bool SO > // Storage order of the adapted sparse matrix
2458 inline bool UniUpperMatrix<MT,SO,false>::canSMPAssign() const noexcept
2459 {
2460  return matrix_.canSMPAssign();
2461 }
2463 //*************************************************************************************************
2464 
2465 } // namespace blaze
2466 
2467 #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 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.
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
Header file for the IsUniUpper type trait.
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:750
#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
void shrinkToFit(Matrix< MT, SO > &matrix)
Requesting the removal of unused capacity.
Definition: Matrix.h:799
Header file for all adaptor forward declarations.
decltype(auto) declupp(const DenseMatrix< MT, SO > &dm)
Declares the given dense matrix expression dm as upper.
Definition: DMatDeclUppExpr.h:1001
#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.
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.
Header file for the IsStrictlyUpper type trait.
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.
Header file for the IsLower type trait.
Header file for the UniUpperProxy class.
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.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:615
Header file for the isOne shim.
Header file for the UniUpperValue 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
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:2235
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.
Header file for the UniUpperElement class.
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 isUniUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper unitriangular matrix.
Definition: DenseMatrix.h:2148
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
#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 implementation of the base template of the UniUpperMatrix.
Header file for the clear shim.