SparseNumeric.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSENUMERIC_H_
36 #define _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSENUMERIC_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <vector>
49 #include <blaze/math/Aliases.h>
59 #include <blaze/math/Exception.h>
63 #include <blaze/math/shims/Clear.h>
72 #include <blaze/util/Assert.h>
78 #include <blaze/util/DisableIf.h>
79 #include <blaze/util/EnableIf.h>
83 #include <blaze/util/Types.h>
84 #include <blaze/util/Unused.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES WITH NUMERIC ELEMENT TYPE
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
103 template< typename MT // Type of the adapted sparse matrix
104  , bool SO > // Storage order of the adapted sparse matrix
105 class SymmetricMatrix<MT,SO,false,true>
106  : public SparseMatrix< SymmetricMatrix<MT,SO,false,true>, SO >
107 {
108  private:
109  //**Type definitions****************************************************************************
110  using OT = OppositeType_t<MT>;
111  using TT = TransposeType_t<MT>;
112  using ET = ElementType_t<MT>;
113  //**********************************************************************************************
114 
115  public:
116  //**Type definitions****************************************************************************
117  using This = SymmetricMatrix<MT,SO,false,true>;
118  using BaseType = SparseMatrix<This,SO>;
119  using ResultType = This;
120  using OppositeType = SymmetricMatrix<OT,!SO,false,true>;
121  using TransposeType = SymmetricMatrix<TT,!SO,false,true>;
122  using ElementType = ET;
123  using ReturnType = ReturnType_t<MT>;
124  using CompositeType = const This&;
125  using Reference = NumericProxy<MT>;
126  using ConstReference = ConstReference_t<MT>;
127  using ConstIterator = ConstIterator_t<MT>;
128  //**********************************************************************************************
129 
130  //**Rebind struct definition********************************************************************
133  template< typename NewType > // Data type of the other matrix
134  struct Rebind {
136  using Other = SymmetricMatrix< typename MT::template Rebind<NewType>::Other >;
137  };
138  //**********************************************************************************************
139 
140  //**Resize struct definition********************************************************************
143  template< size_t NewM // Number of rows of the other matrix
144  , size_t NewN > // Number of columns of the other matrix
145  struct Resize {
147  using Other = SymmetricMatrix< typename MT::template Resize<NewM,NewN>::Other >;
148  };
149  //**********************************************************************************************
150 
151  //**Iterator class definition*******************************************************************
154  class Iterator
155  {
156  public:
157  //**Type definitions*************************************************************************
158  using IteratorType = Iterator_t<MT>;
159 
160  using IteratorCategory = std::forward_iterator_tag;
161  using ValueType = SymmetricElement<MT>;
162  using PointerType = ValueType;
163  using ReferenceType = ValueType;
164  using DifferenceType = ptrdiff_t;
165 
166  // STL iterator requirements
167  using iterator_category = IteratorCategory;
168  using value_type = ValueType;
169  using pointer = PointerType;
170  using reference = ReferenceType;
171  using difference_type = DifferenceType;
172  //*******************************************************************************************
173 
174  //**Default constructor**********************************************************************
177  inline Iterator()
178  : pos_ () // Iterator to the current sparse symmetric matrix element
179  , matrix_( nullptr ) // The sparse matrix containing the iterator
180  , index_ ( 0UL ) // The row/column index of the iterator
181  {}
182  //*******************************************************************************************
183 
184  //**Constructor******************************************************************************
191  inline Iterator( IteratorType pos, MT& matrix, size_t index )
192  : pos_ ( pos ) // Iterator to the current sparse symmetric matrix element
193  , matrix_( &matrix ) // The sparse matrix containing the iterator
194  , index_ ( index ) // The row/column index of the iterator
195  {}
196  //*******************************************************************************************
197 
198  //**Prefix increment operator****************************************************************
203  inline Iterator& operator++() {
204  ++pos_;
205  return *this;
206  }
207  //*******************************************************************************************
208 
209  //**Postfix increment operator***************************************************************
214  inline const Iterator operator++( int ) {
215  const Iterator tmp( *this );
216  ++(*this);
217  return tmp;
218  }
219  //*******************************************************************************************
220 
221  //**Element access operator******************************************************************
226  inline ReferenceType operator*() const {
227  return ReferenceType( pos_, matrix_, index_ );
228  }
229  //*******************************************************************************************
230 
231  //**Element access operator******************************************************************
236  inline PointerType operator->() const {
237  return PointerType( pos_, matrix_, index_ );
238  }
239  //*******************************************************************************************
240 
241  //**Conversion operator**********************************************************************
246  inline operator ConstIterator() const {
247  return pos_;
248  }
249  //*******************************************************************************************
250 
251  //**Equality operator************************************************************************
257  inline bool operator==( const Iterator& rhs ) const {
258  return pos_ == rhs.pos_;
259  }
260  //*******************************************************************************************
261 
262  //**Inequality operator**********************************************************************
268  inline bool operator!=( const Iterator& rhs ) const {
269  return !( *this == rhs );
270  }
271  //*******************************************************************************************
272 
273  //**Subtraction operator*********************************************************************
279  inline DifferenceType operator-( const Iterator& rhs ) const {
280  return pos_ - rhs.pos_;
281  }
282  //*******************************************************************************************
283 
284  //**Base function****************************************************************************
289  inline IteratorType base() const {
290  return pos_;
291  }
292  //*******************************************************************************************
293 
294  private:
295  //**Member variables*************************************************************************
296  IteratorType pos_;
297  MT* matrix_;
298  size_t index_;
299  //*******************************************************************************************
300  };
301  //**********************************************************************************************
302 
303  //**Compilation flags***************************************************************************
305  static constexpr bool smpAssignable = false;
306  //**********************************************************************************************
307 
308  //**Constructors********************************************************************************
311  explicit inline SymmetricMatrix();
312  explicit inline SymmetricMatrix( size_t n );
313  explicit inline SymmetricMatrix( size_t n, size_t nonzeros );
314  explicit inline SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros );
315  explicit inline SymmetricMatrix( initializer_list< initializer_list<ElementType> > list );
316 
317  inline SymmetricMatrix( const SymmetricMatrix& m );
318  inline SymmetricMatrix( SymmetricMatrix&& m ) noexcept;
319 
320  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
321  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
323  //**********************************************************************************************
324 
325  //**Destructor**********************************************************************************
328  ~SymmetricMatrix() = default;
330  //**********************************************************************************************
331 
332  //**Data access functions***********************************************************************
335  inline Reference operator()( size_t i, size_t j );
336  inline ConstReference operator()( size_t i, size_t j ) const;
337  inline Reference at( size_t i, size_t j );
338  inline ConstReference at( size_t i, size_t j ) const;
339  inline Iterator begin ( size_t i );
340  inline ConstIterator begin ( size_t i ) const;
341  inline ConstIterator cbegin( size_t i ) const;
342  inline Iterator end ( size_t i );
343  inline ConstIterator end ( size_t i ) const;
344  inline ConstIterator cend ( size_t i ) const;
346  //**********************************************************************************************
347 
348  //**Assignment operators************************************************************************
351  inline SymmetricMatrix& operator=( initializer_list< initializer_list<ElementType> > list );
352 
353  inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
354  inline SymmetricMatrix& operator=( SymmetricMatrix&& rhs ) noexcept;
355 
356  template< typename MT2 >
357  inline auto operator=( const Matrix<MT2,SO>& rhs )
358  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
359 
360  template< typename MT2 >
361  inline auto operator=( const Matrix<MT2,SO>& rhs )
362  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
363 
364  template< typename MT2 >
365  inline auto operator=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
366 
367  template< typename MT2 >
368  inline auto operator+=( const Matrix<MT2,SO>& rhs )
369  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
370 
371  template< typename MT2 >
372  inline auto operator+=( const Matrix<MT2,SO>& rhs )
373  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
374 
375  template< typename MT2 >
376  inline auto operator+=( const Matrix<MT2,!SO>& rhs )
377  -> SymmetricMatrix&;
378 
379  template< typename MT2 >
380  inline auto operator-=( const Matrix<MT2,SO>& rhs )
381  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
382 
383  template< typename MT2 >
384  inline auto operator-=( const Matrix<MT2,SO>& rhs )
385  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
386 
387  template< typename MT2 >
388  inline auto operator-=( const Matrix<MT2,!SO>& rhs )
389  -> SymmetricMatrix&;
390 
391  template< typename MT2 >
392  inline auto operator%=( const Matrix<MT2,SO>& rhs )
393  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
394 
395  template< typename MT2 >
396  inline auto operator%=( const Matrix<MT2,SO>& rhs )
397  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
398 
399  template< typename MT2 >
400  inline auto operator%=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
401 
402  template< typename ST >
403  inline auto operator*=( ST rhs ) -> EnableIf_t< IsNumeric_v<ST>, SymmetricMatrix& >;
404 
405  template< typename ST >
406  inline auto operator/=( ST rhs ) -> EnableIf_t< IsNumeric_v<ST>, SymmetricMatrix& >;
408  //**********************************************************************************************
409 
410  //**Utility functions***************************************************************************
413  inline size_t rows() const noexcept;
414  inline size_t columns() const noexcept;
415  inline size_t capacity() const noexcept;
416  inline size_t capacity( size_t i ) const noexcept;
417  inline size_t nonZeros() const;
418  inline size_t nonZeros( size_t i ) const;
419  inline void reset();
420  inline void reset( size_t i );
421  inline void clear();
422  inline void resize ( size_t n, bool preserve=true );
423  inline void reserve( size_t nonzeros );
424  inline void reserve( size_t i, size_t nonzeros );
425  inline void trim();
426  inline void trim( size_t i );
427  inline void shrinkToFit();
428  inline void swap( SymmetricMatrix& m ) noexcept;
430  //**********************************************************************************************
431 
432  //**Insertion functions*************************************************************************
435  inline Iterator set ( size_t i, size_t j, const ElementType& value );
436  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
437  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
438  inline void finalize( size_t i );
440  //**********************************************************************************************
441 
442  //**Erase functions*****************************************************************************
445  inline void erase( size_t i, size_t j );
446  inline Iterator erase( size_t i, Iterator pos );
447  inline Iterator erase( size_t i, Iterator first, Iterator last );
448 
449  template< typename Pred >
450  inline void erase( Pred predicate );
451 
452  template< typename Pred >
453  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
455  //**********************************************************************************************
456 
457  //**Lookup functions****************************************************************************
460  inline Iterator find ( size_t i, size_t j );
461  inline ConstIterator find ( size_t i, size_t j ) const;
462  inline Iterator lowerBound( size_t i, size_t j );
463  inline ConstIterator lowerBound( size_t i, size_t j ) const;
464  inline Iterator upperBound( size_t i, size_t j );
465  inline ConstIterator upperBound( size_t i, size_t j ) const;
467  //**********************************************************************************************
468 
469  //**Numeric functions***************************************************************************
472  inline SymmetricMatrix& transpose();
473  inline SymmetricMatrix& ctranspose();
474 
475  template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
477  //**********************************************************************************************
478 
479  //**Debugging functions*************************************************************************
482  inline bool isIntact() const noexcept;
484  //**********************************************************************************************
485 
486  //**Expression template evaluation functions****************************************************
489  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
490  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
491 
492  inline bool canSMPAssign() const noexcept;
494  //**********************************************************************************************
495 
496  private:
497  //**Member variables****************************************************************************
500  MT matrix_;
501 
502  //**********************************************************************************************
503 
504  //**Friend declarations*************************************************************************
505  template< bool RF, typename MT2, bool SO2, bool DF2, bool NF2 >
506  friend bool isDefault( const SymmetricMatrix<MT2,SO2,DF2,NF2>& m );
507  //**********************************************************************************************
508 
509  //**Compile time checks*************************************************************************
523  BLAZE_STATIC_ASSERT( ( Size_v<MT,0UL> == Size_v<MT,1UL> ) );
524  //**********************************************************************************************
525 };
527 //*************************************************************************************************
528 
529 
530 
531 
532 //=================================================================================================
533 //
534 // CONSTRUCTORS
535 //
536 //=================================================================================================
537 
538 //*************************************************************************************************
542 template< typename MT // Type of the adapted sparse matrix
543  , bool SO > // Storage order of the adapted sparse matrix
544 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix()
545  : matrix_() // The adapted sparse matrix
546 {
547  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
548 }
550 //*************************************************************************************************
551 
552 
553 //*************************************************************************************************
561 template< typename MT // Type of the adapted sparse matrix
562  , bool SO > // Storage order of the adapted sparse matrix
563 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n )
564  : matrix_( n, n ) // The adapted sparse matrix
565 {
567 
568  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
569 }
571 //*************************************************************************************************
572 
573 
574 //*************************************************************************************************
583 template< typename MT // Type of the adapted sparse matrix
584  , bool SO > // Storage order of the adapted sparse matrix
585 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, size_t nonzeros )
586  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
587 {
589 
590  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
591 }
593 //*************************************************************************************************
594 
595 
596 //*************************************************************************************************
607 template< typename MT // Type of the adapted sparse matrix
608  , bool SO > // Storage order of the adapted sparse matrix
609 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
610  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
611 {
613 
614  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
615 }
617 //*************************************************************************************************
618 
619 
620 //*************************************************************************************************
644 template< typename MT // Type of the adapted sparse matrix
645  , bool SO > // Storage order of the adapted sparse matrix
646 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( initializer_list< initializer_list<ElementType> > list )
647  : matrix_( list ) // The adapted sparse matrix
648 {
649  if( !isSymmetric( matrix_ ) ) {
650  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
651  }
652 
653  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
654 }
656 //*************************************************************************************************
657 
658 
659 //*************************************************************************************************
665 template< typename MT // Type of the adapted sparse matrix
666  , bool SO > // Storage order of the adapted sparse matrix
667 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const SymmetricMatrix& m )
668  : matrix_( m.matrix_ ) // The adapted sparse matrix
669 {
670  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
671  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
672 }
674 //*************************************************************************************************
675 
676 
677 //*************************************************************************************************
683 template< typename MT // Type of the adapted sparse matrix
684  , bool SO > // Storage order of the adapted sparse matrix
685 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( SymmetricMatrix&& m ) noexcept
686  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
687 {
688  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
689  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
690 }
692 //*************************************************************************************************
693 
694 
695 //*************************************************************************************************
705 template< typename MT // Type of the adapted sparse matrix
706  , bool SO > // Storage order of the adapted sparse matrix
707 template< typename MT2 > // Type of the foreign matrix
708 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,SO>& m )
709  : matrix_( ~m ) // The adapted sparse matrix
710 {
711  if( !IsSymmetric_v<MT2> && !isSymmetric( matrix_ ) ) {
712  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
713  }
714 
715  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
716  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
717 }
719 //*************************************************************************************************
720 
721 
722 //*************************************************************************************************
732 template< typename MT // Type of the adapted sparse matrix
733  , bool SO > // Storage order of the adapted sparse matrix
734 template< typename MT2 > // Type of the foreign matrix
735 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
736  : matrix_( trans( ~m ) ) // The adapted sparse matrix
737 {
738  if( !IsSymmetric_v<MT2> && !isSymmetric( matrix_ ) ) {
739  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
740  }
741 
742  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
743  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
744 }
746 //*************************************************************************************************
747 
748 
749 
750 
751 //=================================================================================================
752 //
753 // DATA ACCESS FUNCTIONS
754 //
755 //=================================================================================================
756 
757 //*************************************************************************************************
772 template< typename MT // Type of the adapted sparse matrix
773  , bool SO > // Storage order of the adapted sparse matrix
775  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j )
776 {
777  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
778  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
779 
780  return Reference( matrix_, i, j );
781 }
783 //*************************************************************************************************
784 
785 
786 //*************************************************************************************************
801 template< typename MT // Type of the adapted sparse matrix
802  , bool SO > // Storage order of the adapted sparse matrix
804  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j ) const
805 {
806  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
807  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
808 
809  return matrix_(i,j);
810 }
812 //*************************************************************************************************
813 
814 
815 //*************************************************************************************************
831 template< typename MT // Type of the adapted dense matrix
832  , bool SO > // Storage order of the adapted dense matrix
834  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j )
835 {
836  if( i >= rows() ) {
837  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
838  }
839  if( j >= columns() ) {
840  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
841  }
842  return (*this)(i,j);
843 }
845 //*************************************************************************************************
846 
847 
848 //*************************************************************************************************
864 template< typename MT // Type of the adapted dense matrix
865  , bool SO > // Storage order of the adapted dense matrix
867  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j ) const
868 {
869  if( i >= rows() ) {
870  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
871  }
872  if( j >= columns() ) {
873  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
874  }
875  return (*this)(i,j);
876 }
878 //*************************************************************************************************
879 
880 
881 //*************************************************************************************************
893 template< typename MT // Type of the adapted sparse matrix
894  , bool SO > // Storage order of the adapted sparse matrix
897 {
898  return Iterator( matrix_.begin(i), matrix_, i );
899 }
901 //*************************************************************************************************
902 
903 
904 //*************************************************************************************************
916 template< typename MT // Type of the adapted sparse matrix
917  , bool SO > // Storage order of the adapted sparse matrix
920 {
921  return matrix_.begin(i);
922 }
924 //*************************************************************************************************
925 
926 
927 //*************************************************************************************************
939 template< typename MT // Type of the adapted sparse matrix
940  , bool SO > // Storage order of the adapted sparse matrix
943 {
944  return matrix_.cbegin(i);
945 }
947 //*************************************************************************************************
948 
949 
950 //*************************************************************************************************
962 template< typename MT // Type of the adapted sparse matrix
963  , bool SO > // Storage order of the adapted sparse matrix
966 {
967  return Iterator( matrix_.end(i), matrix_, i );
968 }
970 //*************************************************************************************************
971 
972 
973 //*************************************************************************************************
985 template< typename MT // Type of the adapted sparse matrix
986  , bool SO > // Storage order of the adapted sparse matrix
989 {
990  return matrix_.end(i);
991 }
993 //*************************************************************************************************
994 
995 
996 //*************************************************************************************************
1008 template< typename MT // Type of the adapted sparse matrix
1009  , bool SO > // Storage order of the adapted sparse matrix
1011  SymmetricMatrix<MT,SO,false,true>::cend( size_t i ) const
1012 {
1013  return matrix_.cend(i);
1014 }
1016 //*************************************************************************************************
1017 
1018 
1019 
1020 
1021 //=================================================================================================
1022 //
1023 // ASSIGNMENT OPERATORS
1024 //
1025 //=================================================================================================
1026 
1027 //*************************************************************************************************
1052 template< typename MT // Type of the adapted sparse matrix
1053  , bool SO > // Storage order of the adapted sparse matrix
1054 inline SymmetricMatrix<MT,SO,false,true>&
1055  SymmetricMatrix<MT,SO,false,true>::operator=( initializer_list< initializer_list<ElementType> > list )
1056 {
1057  const InitializerMatrix<ElementType> tmp( list, list.size() );
1058 
1059  if( !isSymmetric( tmp ) ) {
1060  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1061  }
1062 
1063  matrix_ = list;
1064 
1065  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1066  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1067 
1068  return *this;
1069 }
1071 //*************************************************************************************************
1072 
1073 
1074 //*************************************************************************************************
1084 template< typename MT // Type of the adapted sparse matrix
1085  , bool SO > // Storage order of the adapted sparse matrix
1086 inline SymmetricMatrix<MT,SO,false,true>&
1087  SymmetricMatrix<MT,SO,false,true>::operator=( const SymmetricMatrix& rhs )
1088 {
1089  matrix_ = rhs.matrix_;
1090 
1091  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1092  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1093 
1094  return *this;
1095 }
1097 //*************************************************************************************************
1098 
1099 
1100 //*************************************************************************************************
1107 template< typename MT // Type of the adapted sparse matrix
1108  , bool SO > // Storage order of the adapted sparse matrix
1109 inline SymmetricMatrix<MT,SO,false,true>&
1110  SymmetricMatrix<MT,SO,false,true>::operator=( SymmetricMatrix&& rhs ) noexcept
1111 {
1112  matrix_ = std::move( rhs.matrix_ );
1113 
1114  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1115  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1116 
1117  return *this;
1118 }
1120 //*************************************************************************************************
1121 
1122 
1123 //*************************************************************************************************
1136 template< typename MT // Type of the adapted sparse matrix
1137  , bool SO > // Storage order of the adapted sparse matrix
1138 template< typename MT2 > // Type of the right-hand side matrix
1139 inline auto SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1140  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1141 {
1142  if( !IsSymmetric_v<MT2> && !isSymmetric( ~rhs ) ) {
1143  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1144  }
1145 
1146  matrix_ = ~rhs;
1147 
1148  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1149  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1150 
1151  return *this;
1152 }
1154 //*************************************************************************************************
1155 
1156 
1157 //*************************************************************************************************
1170 template< typename MT // Type of the adapted sparse matrix
1171  , bool SO > // Storage order of the adapted sparse matrix
1172 template< typename MT2 > // Type of the right-hand side matrix
1173 inline auto SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1174  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1175 {
1176  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1177  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1178  }
1179 
1180  if( IsSymmetric_v<MT2> ) {
1181  matrix_ = ~rhs;
1182  }
1183  else {
1184  MT tmp( ~rhs );
1185 
1186  if( !isSymmetric( tmp ) ) {
1187  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1188  }
1189 
1190  matrix_ = std::move( tmp );
1191  }
1192 
1193  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1194  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1195 
1196  return *this;
1197 }
1199 //*************************************************************************************************
1200 
1201 
1202 //*************************************************************************************************
1215 template< typename MT // Type of the adapted sparse matrix
1216  , bool SO > // Storage order of the adapted sparse matrix
1217 template< typename MT2 > // Type of the right-hand side matrix
1218 inline auto SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,!SO>& rhs )
1219  -> SymmetricMatrix&
1220 {
1221  return this->operator=( trans( ~rhs ) );
1222 }
1224 //*************************************************************************************************
1225 
1226 
1227 //*************************************************************************************************
1240 template< typename MT // Type of the adapted sparse matrix
1241  , bool SO > // Storage order of the adapted sparse matrix
1242 template< typename MT2 > // Type of the right-hand side matrix
1243 inline auto SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1244  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1245 {
1246  if( !IsSymmetric_v<MT2> && !isSymmetric( ~rhs ) ) {
1247  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1248  }
1249 
1250  matrix_ += ~rhs;
1251 
1252  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1253  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1254 
1255  return *this;
1256 }
1258 //*************************************************************************************************
1259 
1260 
1261 //*************************************************************************************************
1274 template< typename MT // Type of the adapted sparse matrix
1275  , bool SO > // Storage order of the adapted sparse matrix
1276 template< typename MT2 > // Type of the right-hand side matrix
1277 inline auto SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1278  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1279 {
1280  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1281  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1282  }
1283 
1284  if( IsSymmetric_v<MT2> ) {
1285  matrix_ += ~rhs;
1286  }
1287  else {
1288  const ResultType_t<MT2> tmp( ~rhs );
1289 
1290  if( !isSymmetric( tmp ) ) {
1291  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1292  }
1293 
1294  matrix_ += tmp;
1295  }
1296 
1297  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1298  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1299 
1300  return *this;
1301 }
1303 //*************************************************************************************************
1304 
1305 
1306 //*************************************************************************************************
1320 template< typename MT // Type of the adapted sparse matrix
1321  , bool SO > // Storage order of the adapted sparse matrix
1322 template< typename MT2 > // Type of the right-hand side matrix
1323 inline auto SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,!SO>& rhs )
1324  -> SymmetricMatrix&
1325 {
1326  return this->operator+=( trans( ~rhs ) );
1327 }
1329 //*************************************************************************************************
1330 
1331 
1332 //*************************************************************************************************
1345 template< typename MT // Type of the adapted sparse matrix
1346  , bool SO > // Storage order of the adapted sparse matrix
1347 template< typename MT2 > // Type of the right-hand side matrix
1348 inline auto SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1349  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1350 {
1351  if( !IsSymmetric_v<MT2> && !isSymmetric( ~rhs ) ) {
1352  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1353  }
1354 
1355  matrix_ -= ~rhs;
1356 
1357  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1358  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1359 
1360  return *this;
1361 }
1363 //*************************************************************************************************
1364 
1365 
1366 //*************************************************************************************************
1379 template< typename MT // Type of the adapted sparse matrix
1380  , bool SO > // Storage order of the adapted sparse matrix
1381 template< typename MT2 > // Type of the right-hand side matrix
1382 inline auto SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1383  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1384 {
1385  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1386  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1387  }
1388 
1389  if( IsSymmetric_v<MT2> ) {
1390  matrix_ -= ~rhs;
1391  }
1392  else {
1393  const ResultType_t<MT2> tmp( ~rhs );
1394 
1395  if( !isSymmetric( tmp ) ) {
1396  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1397  }
1398 
1399  matrix_ -= tmp;
1400  }
1401 
1402  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1403  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1404 
1405  return *this;
1406 }
1408 //*************************************************************************************************
1409 
1410 
1411 //*************************************************************************************************
1425 template< typename MT // Type of the adapted sparse matrix
1426  , bool SO > // Storage order of the adapted sparse matrix
1427 template< typename MT2 > // Type of the right-hand side matrix
1428 inline auto SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,!SO>& rhs )
1429  -> SymmetricMatrix&
1430 {
1431  return this->operator-=( trans( ~rhs ) );
1432 }
1434 //*************************************************************************************************
1435 
1436 
1437 //*************************************************************************************************
1451 template< typename MT // Type of the adapted sparse matrix
1452  , bool SO > // Storage order of the adapted sparse matrix
1453 template< typename MT2 > // Type of the right-hand side matrix
1454 inline auto SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1455  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1456 {
1457  if( !IsSymmetric_v<MT2> && !isSymmetric( ~rhs ) ) {
1458  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1459  }
1460 
1461  matrix_ %= ~rhs;
1462 
1463  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1464  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1465 
1466  return *this;
1467 }
1469 //*************************************************************************************************
1470 
1471 
1472 //*************************************************************************************************
1486 template< typename MT // Type of the adapted sparse matrix
1487  , bool SO > // Storage order of the adapted sparse matrix
1488 template< typename MT2 > // Type of the right-hand side matrix
1489 inline auto SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1490  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1491 {
1492  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1493  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1494  }
1495 
1496  if( IsSymmetric_v<MT2> ) {
1497  matrix_ %= ~rhs;
1498  }
1499  else {
1500  const ResultType_t<MT2> tmp( ~rhs );
1501 
1502  if( !isSymmetric( tmp ) ) {
1503  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1504  }
1505 
1506  matrix_ %= tmp;
1507  }
1508 
1509  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1510  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1511 
1512  return *this;
1513 }
1515 //*************************************************************************************************
1516 
1517 
1518 //*************************************************************************************************
1532 template< typename MT // Type of the adapted sparse matrix
1533  , bool SO > // Storage order of the adapted sparse matrix
1534 template< typename MT2 > // Type of the right-hand side matrix
1535 inline auto SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,!SO>& rhs )
1536  -> SymmetricMatrix&
1537 {
1538  return this->operator%=( trans( ~rhs ) );
1539 }
1541 //*************************************************************************************************
1542 
1543 
1544 //*************************************************************************************************
1552 template< typename MT // Type of the adapted sparse matrix
1553  , bool SO > // Storage order of the adapted sparse matrix
1554 template< typename ST > // Data type of the right-hand side scalar
1556  -> EnableIf_t< IsNumeric_v<ST>, SymmetricMatrix& >
1557 {
1558  matrix_ *= rhs;
1559  return *this;
1560 }
1561 //*************************************************************************************************
1562 
1563 
1564 //*************************************************************************************************
1572 template< typename MT // Type of the adapted sparse matrix
1573  , bool SO > // Storage order of the adapted sparse matrix
1574 template< typename ST > // Data type of the right-hand side scalar
1576  -> EnableIf_t< IsNumeric_v<ST>, SymmetricMatrix& >
1577 {
1578  BLAZE_USER_ASSERT( !isZero( rhs ), "Division by zero detected" );
1579 
1580  matrix_ /= rhs;
1581  return *this;
1582 }
1584 //*************************************************************************************************
1585 
1586 
1587 
1588 
1589 //=================================================================================================
1590 //
1591 // UTILITY FUNCTIONS
1592 //
1593 //=================================================================================================
1594 
1595 //*************************************************************************************************
1601 template< typename MT // Type of the adapted sparse matrix
1602  , bool SO > // Storage order of the adapted sparse matrix
1603 inline size_t SymmetricMatrix<MT,SO,false,true>::rows() const noexcept
1604 {
1605  return matrix_.rows();
1606 }
1608 //*************************************************************************************************
1609 
1610 
1611 //*************************************************************************************************
1617 template< typename MT // Type of the adapted sparse matrix
1618  , bool SO > // Storage order of the adapted sparse matrix
1619 inline size_t SymmetricMatrix<MT,SO,false,true>::columns() const noexcept
1620 {
1621  return matrix_.columns();
1622 }
1624 //*************************************************************************************************
1625 
1626 
1627 //*************************************************************************************************
1633 template< typename MT // Type of the adapted sparse matrix
1634  , bool SO > // Storage order of the adapted sparse matrix
1635 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity() const noexcept
1636 {
1637  return matrix_.capacity();
1638 }
1640 //*************************************************************************************************
1641 
1642 
1643 //*************************************************************************************************
1654 template< typename MT // Type of the adapted sparse matrix
1655  , bool SO > // Storage order of the adapted sparse matrix
1656 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity( size_t i ) const noexcept
1657 {
1658  return matrix_.capacity(i);
1659 }
1661 //*************************************************************************************************
1662 
1663 
1664 //*************************************************************************************************
1670 template< typename MT // Type of the adapted sparse matrix
1671  , bool SO > // Storage order of the adapted sparse matrix
1672 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros() const
1673 {
1674  return matrix_.nonZeros();
1675 }
1677 //*************************************************************************************************
1678 
1679 
1680 //*************************************************************************************************
1692 template< typename MT // Type of the adapted sparse matrix
1693  , bool SO > // Storage order of the adapted sparse matrix
1694 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros( size_t i ) const
1695 {
1696  return matrix_.nonZeros(i);
1697 }
1699 //*************************************************************************************************
1700 
1701 
1702 //*************************************************************************************************
1708 template< typename MT // Type of the adapted sparse matrix
1709  , bool SO > // Storage order of the adapted sparse matrix
1711 {
1712  matrix_.reset();
1713 }
1715 //*************************************************************************************************
1716 
1717 
1718 //*************************************************************************************************
1754 template< typename MT // Type of the adapted sparse matrix
1755  , bool SO > // Storage order of the adapted sparse matrix
1756 inline void SymmetricMatrix<MT,SO,false,true>::reset( size_t i )
1757 {
1758  using blaze::erase;
1759 
1760  for( auto it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1761  {
1762  const size_t j( it->index() );
1763 
1764  if( i == j )
1765  continue;
1766 
1767  if( SO ) {
1768  const Iterator_t<MT> pos( matrix_.find( i, j ) );
1769  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1770  erase( matrix_, j, pos );
1771  }
1772  else {
1773  const Iterator_t<MT> pos( matrix_.find( j, i ) );
1774  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1775  erase( matrix_, j, pos );
1776  }
1777  }
1778 
1779  matrix_.reset( i );
1780 }
1782 //*************************************************************************************************
1783 
1784 
1785 //*************************************************************************************************
1793 template< typename MT // Type of the adapted sparse matrix
1794  , bool SO > // Storage order of the adapted sparse matrix
1796 {
1797  using blaze::clear;
1798 
1799  clear( matrix_ );
1800 }
1802 //*************************************************************************************************
1803 
1804 
1805 //*************************************************************************************************
1820 template< typename MT // Type of the adapted sparse matrix
1821  , bool SO > // Storage order of the adapted sparse matrix
1822 void SymmetricMatrix<MT,SO,false,true>::resize( size_t n, bool preserve )
1823 {
1825 
1826  UNUSED_PARAMETER( preserve );
1827 
1828  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1829 
1830  matrix_.resize( n, n, true );
1831 }
1833 //*************************************************************************************************
1834 
1835 
1836 //*************************************************************************************************
1847 template< typename MT // Type of the adapted sparse matrix
1848  , bool SO > // Storage order of the adapted sparse matrix
1849 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t nonzeros )
1850 {
1851  matrix_.reserve( nonzeros );
1852 }
1854 //*************************************************************************************************
1855 
1856 
1857 //*************************************************************************************************
1871 template< typename MT // Type of the adapted sparse matrix
1872  , bool SO > // Storage order of the adapted sparse matrix
1873 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t i, size_t nonzeros )
1874 {
1875  matrix_.reserve( i, nonzeros );
1876 }
1878 //*************************************************************************************************
1879 
1880 
1881 //*************************************************************************************************
1892 template< typename MT // Type of the adapted sparse matrix
1893  , bool SO > // Storage order of the adapted sparse matrix
1894 inline void SymmetricMatrix<MT,SO,false,true>::trim()
1895 {
1896  matrix_.trim();
1897 }
1899 //*************************************************************************************************
1900 
1901 
1902 //*************************************************************************************************
1914 template< typename MT // Type of the adapted sparse matrix
1915  , bool SO > // Storage order of the adapted sparse matrix
1916 inline void SymmetricMatrix<MT,SO,false,true>::trim( size_t i )
1917 {
1918  matrix_.trim( i );
1919 }
1921 //*************************************************************************************************
1922 
1923 
1924 //*************************************************************************************************
1934 template< typename MT // Type of the adapted sparse matrix
1935  , bool SO > // Storage order of the adapted sparse matrix
1937 {
1938  matrix_.shrinkToFit();
1939 }
1941 //*************************************************************************************************
1942 
1943 
1944 //*************************************************************************************************
1951 template< typename MT // Type of the adapted sparse matrix
1952  , bool SO > // Storage order of the adapted sparse matrix
1953 inline void SymmetricMatrix<MT,SO,false,true>::swap( SymmetricMatrix& m ) noexcept
1954 {
1955  using std::swap;
1956 
1957  swap( matrix_, m.matrix_ );
1958 }
1960 //*************************************************************************************************
1961 
1962 
1963 
1964 
1965 //=================================================================================================
1966 //
1967 // INSERTION FUNCTIONS
1968 //
1969 //=================================================================================================
1970 
1971 //*************************************************************************************************
1985 template< typename MT // Type of the adapted sparse matrix
1986  , bool SO > // Storage order of the adapted sparse matrix
1988  SymmetricMatrix<MT,SO,false,true>::set( size_t i, size_t j, const ElementType& value )
1989 {
1990  if( i != j )
1991  matrix_.set( j, i, value );
1992  return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
1993 }
1995 //*************************************************************************************************
1996 
1997 
1998 //*************************************************************************************************
2013 template< typename MT // Type of the adapted sparse matrix
2014  , bool SO > // Storage order of the adapted sparse matrix
2016  SymmetricMatrix<MT,SO,false,true>::insert( size_t i, size_t j, const ElementType& value )
2017 {
2018  if( i != j )
2019  matrix_.insert( j, i, value );
2020  return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
2021 }
2023 //*************************************************************************************************
2024 
2025 
2026 //*************************************************************************************************
2081 template< typename MT // Type of the adapted sparse matrix
2082  , bool SO > // Storage order of the adapted sparse matrix
2083 inline void SymmetricMatrix<MT,SO,false,true>::append( size_t i, size_t j, const ElementType& value, bool check )
2084 {
2085  matrix_.append( i, j, value, check );
2086  if( i != j && ( !check || !isDefault<strict>( value ) ) )
2087  matrix_.insert( j, i, value );
2088 }
2090 //*************************************************************************************************
2091 
2092 
2093 //*************************************************************************************************
2107 template< typename MT // Type of the adapted sparse matrix
2108  , bool SO > // Storage order of the adapted sparse matrix
2109 inline void SymmetricMatrix<MT,SO,false,true>::finalize( size_t i )
2110 {
2111  matrix_.trim( i );
2112 }
2114 //*************************************************************************************************
2115 
2116 
2117 
2118 
2119 //=================================================================================================
2120 //
2121 // ERASE FUNCTIONS
2122 //
2123 //=================================================================================================
2124 
2125 //*************************************************************************************************
2135 template< typename MT // Type of the adapted sparse matrix
2136  , bool SO > // Storage order of the adapted sparse matrix
2137 inline void SymmetricMatrix<MT,SO,false,true>::erase( size_t i, size_t j )
2138 {
2139  using blaze::erase;
2140 
2141  erase( matrix_, i, j );
2142  if( i != j )
2143  erase( matrix_, j, i );
2144 }
2146 //*************************************************************************************************
2147 
2148 
2149 //*************************************************************************************************
2161 template< typename MT // Type of the adapted sparse matrix
2162  , bool SO > // Storage order of the adapted sparse matrix
2164  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator pos )
2165 {
2166  using blaze::erase;
2167 
2168  const Iterator_t<MT> base( pos.base() );
2169 
2170  if( base == matrix_.end( i ) )
2171  return pos;
2172 
2173  const size_t j( base->index() );
2174 
2175  if( i == j ) {
2176  BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
2177  return Iterator( erase( matrix_, i, base ), matrix_, i );
2178  }
2179 
2180  if( SO ) {
2181  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2182  erase( matrix_, j, matrix_.find( i, j ) );
2183  return Iterator( erase( matrix_, i, base ), matrix_, i );
2184  }
2185  else {
2186  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2187  erase( matrix_, j, matrix_.find( j, i ) );
2188  return Iterator( erase(matrix_, i, base ), matrix_, i );
2189  }
2190 }
2192 //*************************************************************************************************
2193 
2194 
2195 //*************************************************************************************************
2209 template< typename MT // Type of the adapted sparse matrix
2210  , bool SO > // Storage order of the adapted sparse matrix
2212  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last )
2213 {
2214  using blaze::erase;
2215 
2216  for( auto it=first.base(); it!=last.base(); ++it )
2217  {
2218  const size_t j( it->index() );
2219 
2220  if( i == j )
2221  continue;
2222 
2223  if( SO ) {
2224  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2225  erase( matrix_, i, j );
2226  }
2227  else {
2228  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2229  erase( matrix_, j, i );
2230  }
2231  }
2232 
2233  return Iterator( erase( matrix_, i, first.base(), last.base() ), matrix_, i );
2234 }
2236 //*************************************************************************************************
2237 
2238 
2239 //*************************************************************************************************
2261 template< typename MT // Type of the adapted sparse matrix
2262  , bool SO > // Storage order of the adapted sparse matrix
2263 template< typename Pred > // Type of the unary predicate
2264 inline void SymmetricMatrix<MT,SO,false,true>::erase( Pred predicate )
2265 {
2266  using blaze::erase;
2267 
2268  erase( matrix_, predicate );
2269 
2270  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2271 }
2273 //*************************************************************************************************
2274 
2275 
2276 //*************************************************************************************************
2304 template< typename MT // Type of the adapted sparse matrix
2305  , bool SO > // Storage order of the adapted sparse matrix
2306 template< typename Pred > // Type of the unary predicate
2307 inline void
2308  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2309 {
2310  using blaze::erase;
2311 
2312  for( auto it=first; it!=last; ++it ) {
2313  const size_t j( it->index() );
2314  if( i != j && predicate( it->value() ) ) {
2315  if( SO )
2316  erase( matrix_, i, j );
2317  else
2318  erase( matrix_, j, i );
2319  }
2320  }
2321 
2322  erase( matrix_, i, first.base(), last.base(), predicate );
2323 
2324  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2325 }
2327 //*************************************************************************************************
2328 
2329 
2330 
2331 
2332 //=================================================================================================
2333 //
2334 // LOOKUP FUNCTIONS
2335 //
2336 //=================================================================================================
2337 
2338 //*************************************************************************************************
2354 template< typename MT // Type of the adapted sparse matrix
2355  , bool SO > // Storage order of the adapted sparse matrix
2357  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j )
2358 {
2359  return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2360 }
2362 //*************************************************************************************************
2363 
2364 
2365 //*************************************************************************************************
2381 template< typename MT // Type of the adapted sparse matrix
2382  , bool SO > // Storage order of the adapted sparse matrix
2384  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j ) const
2385 {
2386  return matrix_.find( i, j );
2387 }
2389 //*************************************************************************************************
2390 
2391 
2392 //*************************************************************************************************
2408 template< typename MT // Type of the adapted sparse matrix
2409  , bool SO > // Storage order of the adapted sparse matrix
2411  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j )
2412 {
2413  return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2414 }
2416 //*************************************************************************************************
2417 
2418 
2419 //*************************************************************************************************
2435 template< typename MT // Type of the adapted sparse matrix
2436  , bool SO > // Storage order of the adapted sparse matrix
2438  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j ) const
2439 {
2440  return matrix_.lowerBound( i, j );
2441 }
2443 //*************************************************************************************************
2444 
2445 
2446 //*************************************************************************************************
2462 template< typename MT // Type of the adapted sparse matrix
2463  , bool SO > // Storage order of the adapted sparse matrix
2465  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j )
2466 {
2467  return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2468 }
2470 //*************************************************************************************************
2471 
2472 
2473 //*************************************************************************************************
2489 template< typename MT // Type of the adapted sparse matrix
2490  , bool SO > // Storage order of the adapted sparse matrix
2492  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j ) const
2493 {
2494  return matrix_.upperBound( i, j );
2495 }
2497 //*************************************************************************************************
2498 
2499 
2500 
2501 
2502 //=================================================================================================
2503 //
2504 // NUMERIC FUNCTIONS
2505 //
2506 //=================================================================================================
2507 
2508 //*************************************************************************************************
2514 template< typename MT // Type of the adapted sparse matrix
2515  , bool SO > // Storage order of the adapted sparse matrix
2516 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::transpose()
2517 {
2518  return *this;
2519 }
2521 //*************************************************************************************************
2522 
2523 
2524 //*************************************************************************************************
2530 template< typename MT // Type of the adapted sparse matrix
2531  , bool SO > // Storage order of the adapted sparse matrix
2532 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::ctranspose()
2533 {
2534  if( !IsBuiltin_v<ElementType> )
2535  conjugate( matrix_ );
2536 
2537  return *this;
2538 }
2540 //*************************************************************************************************
2541 
2542 
2543 //*************************************************************************************************
2561 template< typename MT // Type of the adapted sparse matrix
2562  , bool SO > // Storage order of the adapted sparse matrix
2563 template< typename Other > // Data type of the scalar value
2564 inline SymmetricMatrix<MT,SO,false,true>&
2565  SymmetricMatrix<MT,SO,false,true>::scale( const Other& scalar )
2566 {
2567  matrix_.scale( scalar );
2568  return *this;
2569 }
2571 //*************************************************************************************************
2572 
2573 
2574 
2575 
2576 //=================================================================================================
2577 //
2578 // DEBUGGING FUNCTIONS
2579 //
2580 //=================================================================================================
2581 
2582 //*************************************************************************************************
2592 template< typename MT // Type of the adapted sparse matrix
2593  , bool SO > // Storage order of the adapted sparse matrix
2594 inline bool SymmetricMatrix<MT,SO,false,true>::isIntact() const noexcept
2595 {
2596  using blaze::isIntact;
2597 
2598  return ( isIntact( matrix_ ) && isSymmetric( matrix_ ) );
2599 }
2601 //*************************************************************************************************
2602 
2603 
2604 
2605 
2606 //=================================================================================================
2607 //
2608 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2609 //
2610 //=================================================================================================
2611 
2612 //*************************************************************************************************
2623 template< typename MT // Type of the adapted sparse matrix
2624  , bool SO > // Storage order of the adapted sparse matrix
2625 template< typename Other > // Data type of the foreign expression
2626 inline bool SymmetricMatrix<MT,SO,false,true>::canAlias( const Other* alias ) const noexcept
2627 {
2628  return matrix_.canAlias( alias );
2629 }
2631 //*************************************************************************************************
2632 
2633 
2634 //*************************************************************************************************
2645 template< typename MT // Type of the adapted sparse matrix
2646  , bool SO > // Storage order of the adapted sparse matrix
2647 template< typename Other > // Data type of the foreign expression
2648 inline bool SymmetricMatrix<MT,SO,false,true>::isAliased( const Other* alias ) const noexcept
2649 {
2650  return matrix_.isAliased( alias );
2651 }
2653 //*************************************************************************************************
2654 
2655 
2656 //*************************************************************************************************
2667 template< typename MT // Type of the adapted sparse matrix
2668  , bool SO > // Storage order of the adapted sparse matrix
2669 inline bool SymmetricMatrix<MT,SO,false,true>::canSMPAssign() const noexcept
2670 {
2671  return matrix_.canSMPAssign();
2672 }
2674 //*************************************************************************************************
2675 
2676 } // namespace blaze
2677 
2678 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
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
Header file for auxiliary alias declarations.
Constraint on the data type.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3078
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:354
Header file for the UNUSED_PARAMETER function template.
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
Header file for the isZero shim.
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3077
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
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
Constraint on the data type.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
void shrinkToFit(Matrix< MT, SO > &matrix)
Requesting the removal of unused capacity.
Definition: Matrix.h:799
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:5828
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3079
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3084
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3085
Header file for the extended initializer_list functionality.
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Constraint on the data type.
Header file for the NumericProxy class.
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
Header file for the implementation of the base template of the SymmetricMatrix.
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.
bool isZero(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 0.
Definition: DiagonalProxy.h:673
Header file for the implementation of a matrix representation of an initializer list.
Header file for the DisableIf class template.
Header file for the IsSymmetric type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3083
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the SymmetricElement class.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5907
Compile time assertion.
bool isIntact(const CompressedMatrix< Type, SO > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:5890
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
#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
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3080
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
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.
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
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
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:8908
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 all forward declarations for expression class templates.
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:611
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric_v< T >)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Header file for run time assertion macros.
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, a compilation error is created.
Definition: Reference.h:79
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:281
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
Header file for the SymmetricValue class.
Constraint on the data type.
Constraint on the data type.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:539
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
#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 &#39;res...
Definition: Resizable.h:61
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3082
#define BLAZE_CONSTRAINT_MUST_NOT_BE_EXPRESSION_TYPE(T)
Constraint on the data type.In case the given data type T is an expression (i.e. a type derived from ...
Definition: Expression.h:81
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:290
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type, a compilation error is created.
Definition: Hermitian.h:79
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
#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 Size type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:61
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
Header file for the clear shim.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825