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>
58 #include <blaze/math/Exception.h>
61 #include <blaze/math/shims/Clear.h>
70 #include <blaze/util/Assert.h>
76 #include <blaze/util/DisableIf.h>
77 #include <blaze/util/EnableIf.h>
81 #include <blaze/util/Types.h>
82 #include <blaze/util/Unused.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES WITH NUMERIC ELEMENT TYPE
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
101 template< typename MT // Type of the adapted sparse matrix
102  , bool SO > // Storage order of the adapted sparse matrix
103 class SymmetricMatrix<MT,SO,false,true>
104  : public SparseMatrix< SymmetricMatrix<MT,SO,false,true>, SO >
105 {
106  private:
107  //**Type definitions****************************************************************************
108  using OT = OppositeType_<MT>;
109  using TT = TransposeType_<MT>;
110  using ET = ElementType_<MT>;
111  //**********************************************************************************************
112 
113  public:
114  //**Type definitions****************************************************************************
115  using This = SymmetricMatrix<MT,SO,false,true>;
116  using BaseType = SparseMatrix<This,SO>;
117  using ResultType = This;
118  using OppositeType = SymmetricMatrix<OT,!SO,false,true>;
119  using TransposeType = SymmetricMatrix<TT,!SO,false,true>;
120  using ElementType = ET;
121  using ReturnType = ReturnType_<MT>;
122  using CompositeType = const This&;
123  using Reference = NumericProxy<MT>;
124  using ConstReference = ConstReference_<MT>;
125  using ConstIterator = ConstIterator_<MT>;
126  //**********************************************************************************************
127 
128  //**Rebind struct definition********************************************************************
131  template< typename NewType > // Data type of the other matrix
132  struct Rebind {
134  using Other = SymmetricMatrix< typename MT::template Rebind<NewType>::Other >;
135  };
136  //**********************************************************************************************
137 
138  //**Resize struct definition********************************************************************
141  template< size_t NewM // Number of rows of the other matrix
142  , size_t NewN > // Number of columns of the other matrix
143  struct Resize {
145  using Other = SymmetricMatrix< typename MT::template Resize<NewM,NewN>::Other >;
146  };
147  //**********************************************************************************************
148 
149  //**Iterator class definition*******************************************************************
152  class Iterator
153  {
154  public:
155  //**Type definitions*************************************************************************
156  using IteratorType = Iterator_<MT>;
157 
158  using IteratorCategory = std::forward_iterator_tag;
159  using ValueType = SymmetricElement<MT>;
160  using PointerType = ValueType;
161  using ReferenceType = ValueType;
162  using DifferenceType = ptrdiff_t;
163 
164  // STL iterator requirements
165  using iterator_category = IteratorCategory;
166  using value_type = ValueType;
167  using pointer = PointerType;
168  using reference = ReferenceType;
169  using difference_type = DifferenceType;
170  //*******************************************************************************************
171 
172  //**Default constructor**********************************************************************
175  inline Iterator()
176  : pos_ () // Iterator to the current sparse symmetric matrix element
177  , matrix_( nullptr ) // The sparse matrix containing the iterator
178  , index_ ( 0UL ) // The row/column index of the iterator
179  {}
180  //*******************************************************************************************
181 
182  //**Constructor******************************************************************************
189  inline Iterator( IteratorType pos, MT& matrix, size_t index )
190  : pos_ ( pos ) // Iterator to the current sparse symmetric matrix element
191  , matrix_( &matrix ) // The sparse matrix containing the iterator
192  , index_ ( index ) // The row/column index of the iterator
193  {}
194  //*******************************************************************************************
195 
196  //**Prefix increment operator****************************************************************
201  inline Iterator& operator++() {
202  ++pos_;
203  return *this;
204  }
205  //*******************************************************************************************
206 
207  //**Postfix increment operator***************************************************************
212  inline const Iterator operator++( int ) {
213  const Iterator tmp( *this );
214  ++(*this);
215  return tmp;
216  }
217  //*******************************************************************************************
218 
219  //**Element access operator******************************************************************
224  inline ReferenceType operator*() const {
225  return ReferenceType( pos_, matrix_, index_ );
226  }
227  //*******************************************************************************************
228 
229  //**Element access operator******************************************************************
234  inline PointerType operator->() const {
235  return PointerType( pos_, matrix_, index_ );
236  }
237  //*******************************************************************************************
238 
239  //**Conversion operator**********************************************************************
244  inline operator ConstIterator() const {
245  return pos_;
246  }
247  //*******************************************************************************************
248 
249  //**Equality operator************************************************************************
255  inline bool operator==( const Iterator& rhs ) const {
256  return pos_ == rhs.pos_;
257  }
258  //*******************************************************************************************
259 
260  //**Inequality operator**********************************************************************
266  inline bool operator!=( const Iterator& rhs ) const {
267  return !( *this == rhs );
268  }
269  //*******************************************************************************************
270 
271  //**Subtraction operator*********************************************************************
277  inline DifferenceType operator-( const Iterator& rhs ) const {
278  return pos_ - rhs.pos_;
279  }
280  //*******************************************************************************************
281 
282  //**Base function****************************************************************************
287  inline IteratorType base() const {
288  return pos_;
289  }
290  //*******************************************************************************************
291 
292  private:
293  //**Member variables*************************************************************************
294  IteratorType pos_;
295  MT* matrix_;
296  size_t index_;
297  //*******************************************************************************************
298  };
299  //**********************************************************************************************
300 
301  //**Compilation flags***************************************************************************
303  enum : bool { smpAssignable = false };
304  //**********************************************************************************************
305 
306  //**Constructors********************************************************************************
309  explicit inline SymmetricMatrix();
310  explicit inline SymmetricMatrix( size_t n );
311  explicit inline SymmetricMatrix( size_t n, size_t nonzeros );
312  explicit inline SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros );
313 
314  inline SymmetricMatrix( const SymmetricMatrix& m );
315  inline SymmetricMatrix( SymmetricMatrix&& m ) noexcept;
316 
317  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
318  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
320  //**********************************************************************************************
321 
322  //**Destructor**********************************************************************************
323  // No explicitly declared destructor.
324  //**********************************************************************************************
325 
326  //**Data access functions***********************************************************************
329  inline Reference operator()( size_t i, size_t j );
330  inline ConstReference operator()( size_t i, size_t j ) const;
331  inline Reference at( size_t i, size_t j );
332  inline ConstReference at( size_t i, size_t j ) const;
333  inline Iterator begin ( size_t i );
334  inline ConstIterator begin ( size_t i ) const;
335  inline ConstIterator cbegin( size_t i ) const;
336  inline Iterator end ( size_t i );
337  inline ConstIterator end ( size_t i ) const;
338  inline ConstIterator cend ( size_t i ) const;
340  //**********************************************************************************************
341 
342  //**Assignment operators************************************************************************
345  inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
346  inline SymmetricMatrix& operator=( SymmetricMatrix&& rhs ) noexcept;
347 
348  template< typename MT2 >
349  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator=( const Matrix<MT2,SO>& rhs );
350 
351  template< typename MT2 >
352  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator=( const Matrix<MT2,SO>& rhs );
353 
354  template< typename MT2 >
355  inline SymmetricMatrix& operator=( const Matrix<MT2,!SO>& rhs );
356 
357  template< typename MT2 >
358  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator+=( const Matrix<MT2,SO>& rhs );
359 
360  template< typename MT2 >
361  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator+=( const Matrix<MT2,SO>& rhs );
362 
363  template< typename MT2 >
364  inline SymmetricMatrix& operator+=( const Matrix<MT2,!SO>& rhs );
365 
366  template< typename MT2 >
367  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator-=( const Matrix<MT2,SO>& rhs );
368 
369  template< typename MT2 >
370  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator-=( const Matrix<MT2,SO>& rhs );
371 
372  template< typename MT2 >
373  inline SymmetricMatrix& operator-=( const Matrix<MT2,!SO>& rhs );
374 
375  template< typename MT2 >
376  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator%=( const Matrix<MT2,SO>& rhs );
377 
378  template< typename MT2 >
379  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator%=( const Matrix<MT2,SO>& rhs );
380 
381  template< typename MT2 >
382  inline SymmetricMatrix& operator%=( const Matrix<MT2,!SO>& rhs );
383 
384  template< typename MT2, bool SO2 >
385  inline SymmetricMatrix& operator*=( const Matrix<MT2,SO2>& rhs );
386 
387  template< typename Other >
388  inline EnableIf_< IsNumeric<Other>, SymmetricMatrix >& operator*=( Other rhs );
389 
390  template< typename Other >
391  inline EnableIf_< IsNumeric<Other>, SymmetricMatrix >& operator/=( Other rhs );
393  //**********************************************************************************************
394 
395  //**Utility functions***************************************************************************
398  inline size_t rows() const noexcept;
399  inline size_t columns() const noexcept;
400  inline size_t capacity() const noexcept;
401  inline size_t capacity( size_t i ) const noexcept;
402  inline size_t nonZeros() const;
403  inline size_t nonZeros( size_t i ) const;
404  inline void reset();
405  inline void reset( size_t i );
406  inline void clear();
407  inline void resize ( size_t n, bool preserve=true );
408  inline void reserve( size_t nonzeros );
409  inline void reserve( size_t i, size_t nonzeros );
410  inline void trim();
411  inline void trim( size_t i );
412  inline void shrinkToFit();
413  inline void swap( SymmetricMatrix& m ) noexcept;
415  //**********************************************************************************************
416 
417  //**Insertion functions*************************************************************************
420  inline Iterator set ( size_t i, size_t j, const ElementType& value );
421  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
422  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
423  inline void finalize( size_t i );
425  //**********************************************************************************************
426 
427  //**Erase functions*****************************************************************************
430  inline void erase( size_t i, size_t j );
431  inline Iterator erase( size_t i, Iterator pos );
432  inline Iterator erase( size_t i, Iterator first, Iterator last );
433 
434  template< typename Pred >
435  inline void erase( Pred predicate );
436 
437  template< typename Pred >
438  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
440  //**********************************************************************************************
441 
442  //**Lookup functions****************************************************************************
445  inline Iterator find ( size_t i, size_t j );
446  inline ConstIterator find ( size_t i, size_t j ) const;
447  inline Iterator lowerBound( size_t i, size_t j );
448  inline ConstIterator lowerBound( size_t i, size_t j ) const;
449  inline Iterator upperBound( size_t i, size_t j );
450  inline ConstIterator upperBound( size_t i, size_t j ) const;
452  //**********************************************************************************************
453 
454  //**Numeric functions***************************************************************************
457  inline SymmetricMatrix& transpose();
458  inline SymmetricMatrix& ctranspose();
459 
460  template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
461  template< typename Other > inline SymmetricMatrix& scaleDiagonal( const Other& scale );
463  //**********************************************************************************************
464 
465  //**Debugging functions*************************************************************************
468  inline bool isIntact() const noexcept;
470  //**********************************************************************************************
471 
472  //**Expression template evaluation functions****************************************************
475  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
476  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
477 
478  inline bool canSMPAssign() const noexcept;
480  //**********************************************************************************************
481 
482  private:
483  //**Member variables****************************************************************************
486  MT matrix_;
487 
488  //**********************************************************************************************
489 
490  //**Friend declarations*************************************************************************
491  template< bool RF, typename MT2, bool SO2, bool DF2, bool NF2 >
492  friend bool isDefault( const SymmetricMatrix<MT2,SO2,DF2,NF2>& m );
493  //**********************************************************************************************
494 
495  //**Compile time checks*************************************************************************
509  BLAZE_STATIC_ASSERT( Rows<MT>::value == Columns<MT>::value );
510  //**********************************************************************************************
511 };
513 //*************************************************************************************************
514 
515 
516 
517 
518 //=================================================================================================
519 //
520 // CONSTRUCTORS
521 //
522 //=================================================================================================
523 
524 //*************************************************************************************************
528 template< typename MT // Type of the adapted sparse matrix
529  , bool SO > // Storage order of the adapted sparse matrix
530 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix()
531  : matrix_() // The adapted sparse matrix
532 {
533  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
534 }
536 //*************************************************************************************************
537 
538 
539 //*************************************************************************************************
547 template< typename MT // Type of the adapted sparse matrix
548  , bool SO > // Storage order of the adapted sparse matrix
549 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n )
550  : matrix_( n, n ) // The adapted sparse matrix
551 {
553 
554  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
555 }
557 //*************************************************************************************************
558 
559 
560 //*************************************************************************************************
569 template< typename MT // Type of the adapted sparse matrix
570  , bool SO > // Storage order of the adapted sparse matrix
571 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, size_t nonzeros )
572  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
573 {
575 
576  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
577 }
579 //*************************************************************************************************
580 
581 
582 //*************************************************************************************************
593 template< typename MT // Type of the adapted sparse matrix
594  , bool SO > // Storage order of the adapted sparse matrix
595 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
596  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
597 {
599 
600  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
601 }
603 //*************************************************************************************************
604 
605 
606 //*************************************************************************************************
612 template< typename MT // Type of the adapted sparse matrix
613  , bool SO > // Storage order of the adapted sparse matrix
614 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const SymmetricMatrix& m )
615  : matrix_( m.matrix_ ) // The adapted sparse matrix
616 {
617  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
618  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
619 }
621 //*************************************************************************************************
622 
623 
624 //*************************************************************************************************
630 template< typename MT // Type of the adapted sparse matrix
631  , bool SO > // Storage order of the adapted sparse matrix
632 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( SymmetricMatrix&& m ) noexcept
633  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
634 {
635  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
636  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
637 }
639 //*************************************************************************************************
640 
641 
642 //*************************************************************************************************
652 template< typename MT // Type of the adapted sparse matrix
653  , bool SO > // Storage order of the adapted sparse matrix
654 template< typename MT2 > // Type of the foreign matrix
655 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,SO>& m )
656  : matrix_( ~m ) // The adapted sparse matrix
657 {
658  if( !IsSymmetric<MT2>::value && !isSymmetric( matrix_ ) ) {
659  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
660  }
661 
662  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
663  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
664 }
666 //*************************************************************************************************
667 
668 
669 //*************************************************************************************************
679 template< typename MT // Type of the adapted sparse matrix
680  , bool SO > // Storage order of the adapted sparse matrix
681 template< typename MT2 > // Type of the foreign matrix
682 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
683  : matrix_( trans( ~m ) ) // The adapted sparse matrix
684 {
685  if( !IsSymmetric<MT2>::value && !isSymmetric( matrix_ ) ) {
686  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
687  }
688 
689  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
690  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
691 }
693 //*************************************************************************************************
694 
695 
696 
697 
698 //=================================================================================================
699 //
700 // DATA ACCESS FUNCTIONS
701 //
702 //=================================================================================================
703 
704 //*************************************************************************************************
719 template< typename MT // Type of the adapted sparse matrix
720  , bool SO > // Storage order of the adapted sparse matrix
722  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j )
723 {
724  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
725  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
726 
727  return Reference( matrix_, i, j );
728 }
730 //*************************************************************************************************
731 
732 
733 //*************************************************************************************************
748 template< typename MT // Type of the adapted sparse matrix
749  , bool SO > // Storage order of the adapted sparse matrix
751  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j ) const
752 {
753  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
754  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
755 
756  return matrix_(i,j);
757 }
759 //*************************************************************************************************
760 
761 
762 //*************************************************************************************************
778 template< typename MT // Type of the adapted dense matrix
779  , bool SO > // Storage order of the adapted dense matrix
781  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j )
782 {
783  if( i >= rows() ) {
784  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
785  }
786  if( j >= columns() ) {
787  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
788  }
789  return (*this)(i,j);
790 }
792 //*************************************************************************************************
793 
794 
795 //*************************************************************************************************
811 template< typename MT // Type of the adapted dense matrix
812  , bool SO > // Storage order of the adapted dense matrix
814  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j ) const
815 {
816  if( i >= rows() ) {
817  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
818  }
819  if( j >= columns() ) {
820  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
821  }
822  return (*this)(i,j);
823 }
825 //*************************************************************************************************
826 
827 
828 //*************************************************************************************************
840 template< typename MT // Type of the adapted sparse matrix
841  , bool SO > // Storage order of the adapted sparse matrix
844 {
845  return Iterator( matrix_.begin(i), matrix_, i );
846 }
848 //*************************************************************************************************
849 
850 
851 //*************************************************************************************************
863 template< typename MT // Type of the adapted sparse matrix
864  , bool SO > // Storage order of the adapted sparse matrix
867 {
868  return matrix_.begin(i);
869 }
871 //*************************************************************************************************
872 
873 
874 //*************************************************************************************************
886 template< typename MT // Type of the adapted sparse matrix
887  , bool SO > // Storage order of the adapted sparse matrix
890 {
891  return matrix_.cbegin(i);
892 }
894 //*************************************************************************************************
895 
896 
897 //*************************************************************************************************
909 template< typename MT // Type of the adapted sparse matrix
910  , bool SO > // Storage order of the adapted sparse matrix
913 {
914  return Iterator( matrix_.end(i), matrix_, i );
915 }
917 //*************************************************************************************************
918 
919 
920 //*************************************************************************************************
932 template< typename MT // Type of the adapted sparse matrix
933  , bool SO > // Storage order of the adapted sparse matrix
936 {
937  return matrix_.end(i);
938 }
940 //*************************************************************************************************
941 
942 
943 //*************************************************************************************************
955 template< typename MT // Type of the adapted sparse matrix
956  , bool SO > // Storage order of the adapted sparse matrix
959 {
960  return matrix_.cend(i);
961 }
963 //*************************************************************************************************
964 
965 
966 
967 
968 //=================================================================================================
969 //
970 // ASSIGNMENT OPERATORS
971 //
972 //=================================================================================================
973 
974 //*************************************************************************************************
984 template< typename MT // Type of the adapted sparse matrix
985  , bool SO > // Storage order of the adapted sparse matrix
986 inline SymmetricMatrix<MT,SO,false,true>&
987  SymmetricMatrix<MT,SO,false,true>::operator=( const SymmetricMatrix& rhs )
988 {
989  matrix_ = rhs.matrix_;
990 
991  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
992  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
993 
994  return *this;
995 }
997 //*************************************************************************************************
998 
999 
1000 //*************************************************************************************************
1007 template< typename MT // Type of the adapted sparse matrix
1008  , bool SO > // Storage order of the adapted sparse matrix
1009 inline SymmetricMatrix<MT,SO,false,true>&
1010  SymmetricMatrix<MT,SO,false,true>::operator=( SymmetricMatrix&& rhs ) noexcept
1011 {
1012  matrix_ = std::move( rhs.matrix_ );
1013 
1014  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1015  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1016 
1017  return *this;
1018 }
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1036 template< typename MT // Type of the adapted sparse matrix
1037  , bool SO > // Storage order of the adapted sparse matrix
1038 template< typename MT2 > // Type of the right-hand side matrix
1039 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1040  SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1041 {
1042  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1043  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1044  }
1045 
1046  matrix_ = ~rhs;
1047 
1048  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1049  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1050 
1051  return *this;
1052 }
1054 //*************************************************************************************************
1055 
1056 
1057 //*************************************************************************************************
1070 template< typename MT // Type of the adapted sparse matrix
1071  , bool SO > // Storage order of the adapted sparse matrix
1072 template< typename MT2 > // Type of the right-hand side matrix
1073 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1074  SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1075 {
1076  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1077  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1078  }
1079 
1080  if( IsSymmetric<MT2>::value ) {
1081  matrix_ = ~rhs;
1082  }
1083  else {
1084  MT tmp( ~rhs );
1085 
1086  if( !isSymmetric( tmp ) ) {
1087  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1088  }
1089 
1090  matrix_ = std::move( tmp );
1091  }
1092 
1093  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1094  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1095 
1096  return *this;
1097 }
1099 //*************************************************************************************************
1100 
1101 
1102 //*************************************************************************************************
1115 template< typename MT // Type of the adapted sparse matrix
1116  , bool SO > // Storage order of the adapted sparse matrix
1117 template< typename MT2 > // Type of the right-hand side matrix
1118 inline SymmetricMatrix<MT,SO,false,true>&
1119  SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,!SO>& rhs )
1120 {
1121  return this->operator=( trans( ~rhs ) );
1122 }
1124 //*************************************************************************************************
1125 
1126 
1127 //*************************************************************************************************
1140 template< typename MT // Type of the adapted sparse matrix
1141  , bool SO > // Storage order of the adapted sparse matrix
1142 template< typename MT2 > // Type of the right-hand side matrix
1143 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1144  SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1145 {
1146  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1147  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1148  }
1149 
1150  matrix_ += ~rhs;
1151 
1152  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1153  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1154 
1155  return *this;
1156 }
1158 //*************************************************************************************************
1159 
1160 
1161 //*************************************************************************************************
1174 template< typename MT // Type of the adapted sparse matrix
1175  , bool SO > // Storage order of the adapted sparse matrix
1176 template< typename MT2 > // Type of the right-hand side matrix
1177 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1178  SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1179 {
1180  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1181  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1182  }
1183 
1184  if( IsSymmetric<MT2>::value ) {
1185  matrix_ += ~rhs;
1186  }
1187  else {
1188  const ResultType_<MT2> tmp( ~rhs );
1189 
1190  if( !isSymmetric( tmp ) ) {
1191  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1192  }
1193 
1194  matrix_ += tmp;
1195  }
1196 
1197  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1198  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1199 
1200  return *this;
1201 }
1203 //*************************************************************************************************
1204 
1205 
1206 //*************************************************************************************************
1220 template< typename MT // Type of the adapted sparse matrix
1221  , bool SO > // Storage order of the adapted sparse matrix
1222 template< typename MT2 > // Type of the right-hand side matrix
1223 inline SymmetricMatrix<MT,SO,false,true>&
1224  SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,!SO>& rhs )
1225 {
1226  return this->operator+=( trans( ~rhs ) );
1227 }
1229 //*************************************************************************************************
1230 
1231 
1232 //*************************************************************************************************
1245 template< typename MT // Type of the adapted sparse matrix
1246  , bool SO > // Storage order of the adapted sparse matrix
1247 template< typename MT2 > // Type of the right-hand side matrix
1248 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1249  SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1250 {
1251  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1252  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1253  }
1254 
1255  matrix_ -= ~rhs;
1256 
1257  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1258  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1259 
1260  return *this;
1261 }
1263 //*************************************************************************************************
1264 
1265 
1266 //*************************************************************************************************
1279 template< typename MT // Type of the adapted sparse matrix
1280  , bool SO > // Storage order of the adapted sparse matrix
1281 template< typename MT2 > // Type of the right-hand side matrix
1282 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1283  SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1284 {
1285  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1286  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1287  }
1288 
1289  if( IsSymmetric<MT2>::value ) {
1290  matrix_ -= ~rhs;
1291  }
1292  else {
1293  const ResultType_<MT2> tmp( ~rhs );
1294 
1295  if( !isSymmetric( tmp ) ) {
1296  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1297  }
1298 
1299  matrix_ -= tmp;
1300  }
1301 
1302  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1303  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1304 
1305  return *this;
1306 }
1308 //*************************************************************************************************
1309 
1310 
1311 //*************************************************************************************************
1325 template< typename MT // Type of the adapted sparse matrix
1326  , bool SO > // Storage order of the adapted sparse matrix
1327 template< typename MT2 > // Type of the right-hand side matrix
1328 inline SymmetricMatrix<MT,SO,false,true>&
1329  SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,!SO>& rhs )
1330 {
1331  return this->operator-=( trans( ~rhs ) );
1332 }
1334 //*************************************************************************************************
1335 
1336 
1337 //*************************************************************************************************
1351 template< typename MT // Type of the adapted sparse matrix
1352  , bool SO > // Storage order of the adapted sparse matrix
1353 template< typename MT2 > // Type of the right-hand side matrix
1354 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1355  SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1356 {
1357  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1358  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1359  }
1360 
1361  matrix_ %= ~rhs;
1362 
1363  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1364  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1365 
1366  return *this;
1367 }
1369 //*************************************************************************************************
1370 
1371 
1372 //*************************************************************************************************
1386 template< typename MT // Type of the adapted sparse matrix
1387  , bool SO > // Storage order of the adapted sparse matrix
1388 template< typename MT2 > // Type of the right-hand side matrix
1389 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1390  SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1391 {
1392  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1393  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1394  }
1395 
1396  if( IsSymmetric<MT2>::value ) {
1397  matrix_ %= ~rhs;
1398  }
1399  else {
1400  const ResultType_<MT2> tmp( ~rhs );
1401 
1402  if( !isSymmetric( tmp ) ) {
1403  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1404  }
1405 
1406  matrix_ %= tmp;
1407  }
1408 
1409  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1410  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1411 
1412  return *this;
1413 }
1415 //*************************************************************************************************
1416 
1417 
1418 //*************************************************************************************************
1432 template< typename MT // Type of the adapted sparse matrix
1433  , bool SO > // Storage order of the adapted sparse matrix
1434 template< typename MT2 > // Type of the right-hand side matrix
1435 inline SymmetricMatrix<MT,SO,false,true>&
1436  SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,!SO>& rhs )
1437 {
1438  return this->operator%=( trans( ~rhs ) );
1439 }
1441 //*************************************************************************************************
1442 
1443 
1444 //*************************************************************************************************
1456 template< typename MT // Type of the adapted sparse matrix
1457  , bool SO > // Storage order of the adapted sparse matrix
1458 template< typename MT2 // Type of the right-hand side matrix
1459  , bool SO2 > // Storage order of the right-hand side matrix
1460 inline SymmetricMatrix<MT,SO,false,true>&
1461  SymmetricMatrix<MT,SO,false,true>::operator*=( const Matrix<MT2,SO2>& rhs )
1462 {
1463  if( matrix_.rows() != (~rhs).columns() ) {
1464  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1465  }
1466 
1467  MT tmp( matrix_ * ~rhs );
1468 
1469  if( !isSymmetric( tmp ) ) {
1470  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1471  }
1472 
1473  matrix_ = std::move( tmp );
1474 
1475  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1476  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1477 
1478  return *this;
1479 }
1481 //*************************************************************************************************
1482 
1483 
1484 //*************************************************************************************************
1492 template< typename MT // Type of the adapted sparse matrix
1493  , bool SO > // Storage order of the adapted sparse matrix
1494 template< typename Other > // Data type of the right-hand side scalar
1495 inline EnableIf_< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,true> >&
1497 {
1498  matrix_ *= rhs;
1499  return *this;
1500 }
1501 //*************************************************************************************************
1502 
1503 
1504 //*************************************************************************************************
1512 template< typename MT // Type of the adapted sparse matrix
1513  , bool SO > // Storage order of the adapted sparse matrix
1514 template< typename Other > // Data type of the right-hand side scalar
1515 inline EnableIf_< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,true> >&
1517 {
1518  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1519 
1520  matrix_ /= rhs;
1521  return *this;
1522 }
1524 //*************************************************************************************************
1525 
1526 
1527 
1528 
1529 //=================================================================================================
1530 //
1531 // UTILITY FUNCTIONS
1532 //
1533 //=================================================================================================
1534 
1535 //*************************************************************************************************
1541 template< typename MT // Type of the adapted sparse matrix
1542  , bool SO > // Storage order of the adapted sparse matrix
1543 inline size_t SymmetricMatrix<MT,SO,false,true>::rows() const noexcept
1544 {
1545  return matrix_.rows();
1546 }
1548 //*************************************************************************************************
1549 
1550 
1551 //*************************************************************************************************
1557 template< typename MT // Type of the adapted sparse matrix
1558  , bool SO > // Storage order of the adapted sparse matrix
1559 inline size_t SymmetricMatrix<MT,SO,false,true>::columns() const noexcept
1560 {
1561  return matrix_.columns();
1562 }
1564 //*************************************************************************************************
1565 
1566 
1567 //*************************************************************************************************
1573 template< typename MT // Type of the adapted sparse matrix
1574  , bool SO > // Storage order of the adapted sparse matrix
1575 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity() const noexcept
1576 {
1577  return matrix_.capacity();
1578 }
1580 //*************************************************************************************************
1581 
1582 
1583 //*************************************************************************************************
1594 template< typename MT // Type of the adapted sparse matrix
1595  , bool SO > // Storage order of the adapted sparse matrix
1596 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity( size_t i ) const noexcept
1597 {
1598  return matrix_.capacity(i);
1599 }
1601 //*************************************************************************************************
1602 
1603 
1604 //*************************************************************************************************
1610 template< typename MT // Type of the adapted sparse matrix
1611  , bool SO > // Storage order of the adapted sparse matrix
1612 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros() const
1613 {
1614  return matrix_.nonZeros();
1615 }
1617 //*************************************************************************************************
1618 
1619 
1620 //*************************************************************************************************
1632 template< typename MT // Type of the adapted sparse matrix
1633  , bool SO > // Storage order of the adapted sparse matrix
1634 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros( size_t i ) const
1635 {
1636  return matrix_.nonZeros(i);
1637 }
1639 //*************************************************************************************************
1640 
1641 
1642 //*************************************************************************************************
1648 template< typename MT // Type of the adapted sparse matrix
1649  , bool SO > // Storage order of the adapted sparse matrix
1651 {
1652  matrix_.reset();
1653 }
1655 //*************************************************************************************************
1656 
1657 
1658 //*************************************************************************************************
1694 template< typename MT // Type of the adapted sparse matrix
1695  , bool SO > // Storage order of the adapted sparse matrix
1696 inline void SymmetricMatrix<MT,SO,false,true>::reset( size_t i )
1697 {
1698  for( Iterator_<MT> it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1699  {
1700  const size_t j( it->index() );
1701 
1702  if( i == j )
1703  continue;
1704 
1705  if( SO ) {
1706  const Iterator_<MT> pos( matrix_.find( i, j ) );
1707  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1708  matrix_.erase( j, pos );
1709  }
1710  else {
1711  const Iterator_<MT> pos( matrix_.find( j, i ) );
1712  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1713  matrix_.erase( j, pos );
1714  }
1715  }
1716 
1717  matrix_.reset( i );
1718 }
1720 //*************************************************************************************************
1721 
1722 
1723 //*************************************************************************************************
1731 template< typename MT // Type of the adapted sparse matrix
1732  , bool SO > // Storage order of the adapted sparse matrix
1734 {
1735  using blaze::clear;
1736 
1737  clear( matrix_ );
1738 }
1740 //*************************************************************************************************
1741 
1742 
1743 //*************************************************************************************************
1758 template< typename MT // Type of the adapted sparse matrix
1759  , bool SO > // Storage order of the adapted sparse matrix
1760 void SymmetricMatrix<MT,SO,false,true>::resize( size_t n, bool preserve )
1761 {
1763 
1764  UNUSED_PARAMETER( preserve );
1765 
1766  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1767 
1768  matrix_.resize( n, n, true );
1769 }
1771 //*************************************************************************************************
1772 
1773 
1774 //*************************************************************************************************
1785 template< typename MT // Type of the adapted sparse matrix
1786  , bool SO > // Storage order of the adapted sparse matrix
1787 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t nonzeros )
1788 {
1789  matrix_.reserve( nonzeros );
1790 }
1792 //*************************************************************************************************
1793 
1794 
1795 //*************************************************************************************************
1809 template< typename MT // Type of the adapted sparse matrix
1810  , bool SO > // Storage order of the adapted sparse matrix
1811 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t i, size_t nonzeros )
1812 {
1813  matrix_.reserve( i, nonzeros );
1814 }
1816 //*************************************************************************************************
1817 
1818 
1819 //*************************************************************************************************
1830 template< typename MT // Type of the adapted sparse matrix
1831  , bool SO > // Storage order of the adapted sparse matrix
1832 inline void SymmetricMatrix<MT,SO,false,true>::trim()
1833 {
1834  matrix_.trim();
1835 }
1837 //*************************************************************************************************
1838 
1839 
1840 //*************************************************************************************************
1852 template< typename MT // Type of the adapted sparse matrix
1853  , bool SO > // Storage order of the adapted sparse matrix
1854 inline void SymmetricMatrix<MT,SO,false,true>::trim( size_t i )
1855 {
1856  matrix_.trim( i );
1857 }
1859 //*************************************************************************************************
1860 
1861 
1862 //*************************************************************************************************
1872 template< typename MT // Type of the adapted sparse matrix
1873  , bool SO > // Storage order of the adapted sparse matrix
1875 {
1876  matrix_.shrinkToFit();
1877 }
1879 //*************************************************************************************************
1880 
1881 
1882 //*************************************************************************************************
1889 template< typename MT // Type of the adapted sparse matrix
1890  , bool SO > // Storage order of the adapted sparse matrix
1891 inline void SymmetricMatrix<MT,SO,false,true>::swap( SymmetricMatrix& m ) noexcept
1892 {
1893  using std::swap;
1894 
1895  swap( matrix_, m.matrix_ );
1896 }
1898 //*************************************************************************************************
1899 
1900 
1901 
1902 
1903 //=================================================================================================
1904 //
1905 // INSERTION FUNCTIONS
1906 //
1907 //=================================================================================================
1908 
1909 //*************************************************************************************************
1923 template< typename MT // Type of the adapted sparse matrix
1924  , bool SO > // Storage order of the adapted sparse matrix
1926  SymmetricMatrix<MT,SO,false,true>::set( size_t i, size_t j, const ElementType& value )
1927 {
1928  if( i != j )
1929  matrix_.set( j, i, value );
1930  return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
1931 }
1933 //*************************************************************************************************
1934 
1935 
1936 //*************************************************************************************************
1951 template< typename MT // Type of the adapted sparse matrix
1952  , bool SO > // Storage order of the adapted sparse matrix
1954  SymmetricMatrix<MT,SO,false,true>::insert( size_t i, size_t j, const ElementType& value )
1955 {
1956  if( i != j )
1957  matrix_.insert( j, i, value );
1958  return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
1959 }
1961 //*************************************************************************************************
1962 
1963 
1964 //*************************************************************************************************
2019 template< typename MT // Type of the adapted sparse matrix
2020  , bool SO > // Storage order of the adapted sparse matrix
2021 inline void SymmetricMatrix<MT,SO,false,true>::append( size_t i, size_t j, const ElementType& value, bool check )
2022 {
2023  matrix_.append( i, j, value, check );
2024  if( i != j && ( !check || !isDefault<strict>( value ) ) )
2025  matrix_.insert( j, i, value );
2026 }
2028 //*************************************************************************************************
2029 
2030 
2031 //*************************************************************************************************
2045 template< typename MT // Type of the adapted sparse matrix
2046  , bool SO > // Storage order of the adapted sparse matrix
2047 inline void SymmetricMatrix<MT,SO,false,true>::finalize( size_t i )
2048 {
2049  matrix_.trim( i );
2050 }
2052 //*************************************************************************************************
2053 
2054 
2055 
2056 
2057 //=================================================================================================
2058 //
2059 // ERASE FUNCTIONS
2060 //
2061 //=================================================================================================
2062 
2063 //*************************************************************************************************
2073 template< typename MT // Type of the adapted sparse matrix
2074  , bool SO > // Storage order of the adapted sparse matrix
2075 inline void SymmetricMatrix<MT,SO,false,true>::erase( size_t i, size_t j )
2076 {
2077  matrix_.erase( i, j );
2078  if( i != j )
2079  matrix_.erase( j, i );
2080 }
2082 //*************************************************************************************************
2083 
2084 
2085 //*************************************************************************************************
2097 template< typename MT // Type of the adapted sparse matrix
2098  , bool SO > // Storage order of the adapted sparse matrix
2100  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator pos )
2101 {
2102  const Iterator_<MT> base( pos.base() );
2103 
2104  if( base == matrix_.end( i ) )
2105  return pos;
2106 
2107  const size_t j( base->index() );
2108 
2109  if( i == j ) {
2110  BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
2111  return Iterator( matrix_.erase( i, base ), matrix_, i );
2112  }
2113 
2114  if( SO ) {
2115  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2116  matrix_.erase( j, matrix_.find( i, j ) );
2117  return Iterator( matrix_.erase( i, base ), matrix_, i );
2118  }
2119  else {
2120  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2121  matrix_.erase( j, matrix_.find( j, i ) );
2122  return Iterator( matrix_.erase( i, base ), matrix_, i );
2123  }
2124 }
2126 //*************************************************************************************************
2127 
2128 
2129 //*************************************************************************************************
2143 template< typename MT // Type of the adapted sparse matrix
2144  , bool SO > // Storage order of the adapted sparse matrix
2146  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last )
2147 {
2148  for( Iterator_<MT> it=first.base(); it!=last.base(); ++it )
2149  {
2150  const size_t j( it->index() );
2151 
2152  if( i == j )
2153  continue;
2154 
2155  if( SO ) {
2156  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2157  matrix_.erase( i, j );
2158  }
2159  else {
2160  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2161  matrix_.erase( j, i );
2162  }
2163  }
2164 
2165  return Iterator( matrix_.erase( i, first.base(), last.base() ), matrix_, i );
2166 }
2168 //*************************************************************************************************
2169 
2170 
2171 //*************************************************************************************************
2193 template< typename MT // Type of the adapted sparse matrix
2194  , bool SO > // Storage order of the adapted sparse matrix
2195 template< typename Pred > // Type of the unary predicate
2196 inline void SymmetricMatrix<MT,SO,false,true>::erase( Pred predicate )
2197 {
2198  matrix_.erase( predicate );
2199 
2200  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2201 }
2203 //*************************************************************************************************
2204 
2205 
2206 //*************************************************************************************************
2234 template< typename MT // Type of the adapted sparse matrix
2235  , bool SO > // Storage order of the adapted sparse matrix
2236 template< typename Pred > // Type of the unary predicate
2237 inline void
2238  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2239 {
2240  for( Iterator it=first; it!=last; ++it ) {
2241  const size_t j( it->index() );
2242  if( i != j && predicate( it->value() ) ) {
2243  if( SO )
2244  matrix_.erase( i, j );
2245  else
2246  matrix_.erase( j, i );
2247  }
2248  }
2249 
2250  matrix_.erase( i, first.base(), last.base(), predicate );
2251 
2252  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2253 }
2255 //*************************************************************************************************
2256 
2257 
2258 
2259 
2260 //=================================================================================================
2261 //
2262 // LOOKUP FUNCTIONS
2263 //
2264 //=================================================================================================
2265 
2266 //*************************************************************************************************
2282 template< typename MT // Type of the adapted sparse matrix
2283  , bool SO > // Storage order of the adapted sparse matrix
2285  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j )
2286 {
2287  return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2288 }
2290 //*************************************************************************************************
2291 
2292 
2293 //*************************************************************************************************
2309 template< typename MT // Type of the adapted sparse matrix
2310  , bool SO > // Storage order of the adapted sparse matrix
2312  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j ) const
2313 {
2314  return matrix_.find( i, j );
2315 }
2317 //*************************************************************************************************
2318 
2319 
2320 //*************************************************************************************************
2336 template< typename MT // Type of the adapted sparse matrix
2337  , bool SO > // Storage order of the adapted sparse matrix
2339  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j )
2340 {
2341  return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2342 }
2344 //*************************************************************************************************
2345 
2346 
2347 //*************************************************************************************************
2363 template< typename MT // Type of the adapted sparse matrix
2364  , bool SO > // Storage order of the adapted sparse matrix
2366  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j ) const
2367 {
2368  return matrix_.lowerBound( i, j );
2369 }
2371 //*************************************************************************************************
2372 
2373 
2374 //*************************************************************************************************
2390 template< typename MT // Type of the adapted sparse matrix
2391  , bool SO > // Storage order of the adapted sparse matrix
2393  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j )
2394 {
2395  return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2396 }
2398 //*************************************************************************************************
2399 
2400 
2401 //*************************************************************************************************
2417 template< typename MT // Type of the adapted sparse matrix
2418  , bool SO > // Storage order of the adapted sparse matrix
2420  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j ) const
2421 {
2422  return matrix_.upperBound( i, j );
2423 }
2425 //*************************************************************************************************
2426 
2427 
2428 
2429 
2430 //=================================================================================================
2431 //
2432 // NUMERIC FUNCTIONS
2433 //
2434 //=================================================================================================
2435 
2436 //*************************************************************************************************
2442 template< typename MT // Type of the adapted sparse matrix
2443  , bool SO > // Storage order of the adapted sparse matrix
2444 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::transpose()
2445 {
2446  return *this;
2447 }
2449 //*************************************************************************************************
2450 
2451 
2452 //*************************************************************************************************
2458 template< typename MT // Type of the adapted sparse matrix
2459  , bool SO > // Storage order of the adapted sparse matrix
2460 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::ctranspose()
2461 {
2462  if( !IsBuiltin<ElementType>::value )
2463  conjugate( matrix_ );
2464 
2465  return *this;
2466 }
2468 //*************************************************************************************************
2469 
2470 
2471 //*************************************************************************************************
2489 template< typename MT // Type of the adapted sparse matrix
2490  , bool SO > // Storage order of the adapted sparse matrix
2491 template< typename Other > // Data type of the scalar value
2492 inline SymmetricMatrix<MT,SO,false,true>&
2493  SymmetricMatrix<MT,SO,false,true>::scale( const Other& scalar )
2494 {
2495  matrix_.scale( scalar );
2496  return *this;
2497 }
2499 //*************************************************************************************************
2500 
2501 
2502 //*************************************************************************************************
2512 template< typename MT // Type of the adapted sparse matrix
2513  , bool SO > // Storage order of the adapted sparse matrix
2514 template< typename Other > // Data type of the scalar value
2515 inline SymmetricMatrix<MT,SO,false,true>&
2516  SymmetricMatrix<MT,SO,false,true>::scaleDiagonal( const Other& scalar )
2517 {
2518  matrix_.scaleDiagonal( scalar );
2519  return *this;
2520 }
2522 //*************************************************************************************************
2523 
2524 
2525 
2526 
2527 //=================================================================================================
2528 //
2529 // DEBUGGING FUNCTIONS
2530 //
2531 //=================================================================================================
2532 
2533 //*************************************************************************************************
2543 template< typename MT // Type of the adapted sparse matrix
2544  , bool SO > // Storage order of the adapted sparse matrix
2545 inline bool SymmetricMatrix<MT,SO,false,true>::isIntact() const noexcept
2546 {
2547  using blaze::isIntact;
2548 
2549  return ( isIntact( matrix_ ) && isSymmetric( matrix_ ) );
2550 }
2552 //*************************************************************************************************
2553 
2554 
2555 
2556 
2557 //=================================================================================================
2558 //
2559 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2560 //
2561 //=================================================================================================
2562 
2563 //*************************************************************************************************
2574 template< typename MT // Type of the adapted sparse matrix
2575  , bool SO > // Storage order of the adapted sparse matrix
2576 template< typename Other > // Data type of the foreign expression
2577 inline bool SymmetricMatrix<MT,SO,false,true>::canAlias( const Other* alias ) const noexcept
2578 {
2579  return matrix_.canAlias( alias );
2580 }
2582 //*************************************************************************************************
2583 
2584 
2585 //*************************************************************************************************
2596 template< typename MT // Type of the adapted sparse matrix
2597  , bool SO > // Storage order of the adapted sparse matrix
2598 template< typename Other > // Data type of the foreign expression
2599 inline bool SymmetricMatrix<MT,SO,false,true>::isAliased( const Other* alias ) const noexcept
2600 {
2601  return matrix_.isAliased( alias );
2602 }
2604 //*************************************************************************************************
2605 
2606 
2607 //*************************************************************************************************
2618 template< typename MT // Type of the adapted sparse matrix
2619  , bool SO > // Storage order of the adapted sparse matrix
2620 inline bool SymmetricMatrix<MT,SO,false,true>::canSMPAssign() const noexcept
2621 {
2622  return matrix_.canSMPAssign();
2623 }
2625 //*************************************************************************************************
2626 
2627 } // namespace blaze
2628 
2629 #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:3079
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:356
Header file for basic type definitions.
#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
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1411
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3078
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:198
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
Constraint on the data type.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
BLAZE_ALWAYS_INLINE void shrinkToFit(Matrix< MT, SO > &matrix)
Requesting the removal of unused capacity.
Definition: Matrix.h:609
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:5845
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3080
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:661
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3085
#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
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:394
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:731
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3086
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1393
Constraint on the data type.
Header file for the NumericProxy class.
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:308
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:242
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.
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:3084
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
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:5924
Compile time assertion.
bool isIntact(const CompressedMatrix< Type, SO > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:5907
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3077
#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:3081
#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
Header file for the Columns type trait.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Constraint on the data type.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:340
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
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:548
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:264
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
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:580
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
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:270
Header file for the SymmetricValue class.
Constraint on the data type.
Constraint on the data type.
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric< T >::value)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:700
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:324
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:790
#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:3083
#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
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
#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
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
#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
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:742
#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
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:635