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_<MT>;
111  using TT = TransposeType_<MT>;
112  using ET = ElementType_<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_<MT>;
124  using CompositeType = const This&;
125  using Reference = NumericProxy<MT>;
126  using ConstReference = ConstReference_<MT>;
127  using ConstIterator = ConstIterator_<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_<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  enum : 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**********************************************************************************
326  // No explicitly declared destructor.
327  //**********************************************************************************************
328 
329  //**Data access functions***********************************************************************
332  inline Reference operator()( size_t i, size_t j );
333  inline ConstReference operator()( size_t i, size_t j ) const;
334  inline Reference at( size_t i, size_t j );
335  inline ConstReference at( size_t i, size_t j ) const;
336  inline Iterator begin ( size_t i );
337  inline ConstIterator begin ( size_t i ) const;
338  inline ConstIterator cbegin( size_t i ) const;
339  inline Iterator end ( size_t i );
340  inline ConstIterator end ( size_t i ) const;
341  inline ConstIterator cend ( size_t i ) const;
343  //**********************************************************************************************
344 
345  //**Assignment operators************************************************************************
348  inline SymmetricMatrix& operator=( initializer_list< initializer_list<ElementType> > list );
349 
350  inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
351  inline SymmetricMatrix& operator=( SymmetricMatrix&& rhs ) noexcept;
352 
353  template< typename MT2 >
354  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator=( const Matrix<MT2,SO>& rhs );
355 
356  template< typename MT2 >
357  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator=( const Matrix<MT2,SO>& rhs );
358 
359  template< typename MT2 >
360  inline SymmetricMatrix& operator=( const Matrix<MT2,!SO>& rhs );
361 
362  template< typename MT2 >
363  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator+=( const Matrix<MT2,SO>& rhs );
364 
365  template< typename MT2 >
366  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator+=( const Matrix<MT2,SO>& rhs );
367 
368  template< typename MT2 >
369  inline SymmetricMatrix& operator+=( const Matrix<MT2,!SO>& rhs );
370 
371  template< typename MT2 >
372  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator-=( const Matrix<MT2,SO>& rhs );
373 
374  template< typename MT2 >
375  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator-=( const Matrix<MT2,SO>& rhs );
376 
377  template< typename MT2 >
378  inline SymmetricMatrix& operator-=( const Matrix<MT2,!SO>& rhs );
379 
380  template< typename MT2 >
381  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator%=( const Matrix<MT2,SO>& rhs );
382 
383  template< typename MT2 >
384  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator%=( const Matrix<MT2,SO>& rhs );
385 
386  template< typename MT2 >
387  inline SymmetricMatrix& operator%=( const Matrix<MT2,!SO>& rhs );
388 
389  template< typename ST >
390  inline EnableIf_< IsNumeric<ST>, SymmetricMatrix >& operator*=( ST rhs );
391 
392  template< typename ST >
393  inline EnableIf_< IsNumeric<ST>, SymmetricMatrix >& operator/=( ST rhs );
395  //**********************************************************************************************
396 
397  //**Utility functions***************************************************************************
400  inline size_t rows() const noexcept;
401  inline size_t columns() const noexcept;
402  inline size_t capacity() const noexcept;
403  inline size_t capacity( size_t i ) const noexcept;
404  inline size_t nonZeros() const;
405  inline size_t nonZeros( size_t i ) const;
406  inline void reset();
407  inline void reset( size_t i );
408  inline void clear();
409  inline void resize ( size_t n, bool preserve=true );
410  inline void reserve( size_t nonzeros );
411  inline void reserve( size_t i, size_t nonzeros );
412  inline void trim();
413  inline void trim( size_t i );
414  inline void shrinkToFit();
415  inline void swap( SymmetricMatrix& m ) noexcept;
417  //**********************************************************************************************
418 
419  //**Insertion functions*************************************************************************
422  inline Iterator set ( size_t i, size_t j, const ElementType& value );
423  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
424  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
425  inline void finalize( size_t i );
427  //**********************************************************************************************
428 
429  //**Erase functions*****************************************************************************
432  inline void erase( size_t i, size_t j );
433  inline Iterator erase( size_t i, Iterator pos );
434  inline Iterator erase( size_t i, Iterator first, Iterator last );
435 
436  template< typename Pred >
437  inline void erase( Pred predicate );
438 
439  template< typename Pred >
440  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
442  //**********************************************************************************************
443 
444  //**Lookup functions****************************************************************************
447  inline Iterator find ( size_t i, size_t j );
448  inline ConstIterator find ( size_t i, size_t j ) const;
449  inline Iterator lowerBound( size_t i, size_t j );
450  inline ConstIterator lowerBound( size_t i, size_t j ) const;
451  inline Iterator upperBound( size_t i, size_t j );
452  inline ConstIterator upperBound( size_t i, size_t j ) const;
454  //**********************************************************************************************
455 
456  //**Numeric functions***************************************************************************
459  inline SymmetricMatrix& transpose();
460  inline SymmetricMatrix& ctranspose();
461 
462  template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
464  //**********************************************************************************************
465 
466  //**Debugging functions*************************************************************************
469  inline bool isIntact() const noexcept;
471  //**********************************************************************************************
472 
473  //**Expression template evaluation functions****************************************************
476  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
477  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
478 
479  inline bool canSMPAssign() const noexcept;
481  //**********************************************************************************************
482 
483  private:
484  //**Member variables****************************************************************************
487  MT matrix_;
488 
489  //**********************************************************************************************
490 
491  //**Friend declarations*************************************************************************
492  template< bool RF, typename MT2, bool SO2, bool DF2, bool NF2 >
493  friend bool isDefault( const SymmetricMatrix<MT2,SO2,DF2,NF2>& m );
494  //**********************************************************************************************
495 
496  //**Compile time checks*************************************************************************
510  BLAZE_STATIC_ASSERT( ( Size<MT,0UL>::value == Size<MT,1UL>::value ) );
511  //**********************************************************************************************
512 };
514 //*************************************************************************************************
515 
516 
517 
518 
519 //=================================================================================================
520 //
521 // CONSTRUCTORS
522 //
523 //=================================================================================================
524 
525 //*************************************************************************************************
529 template< typename MT // Type of the adapted sparse matrix
530  , bool SO > // Storage order of the adapted sparse matrix
531 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix()
532  : matrix_() // The adapted sparse matrix
533 {
534  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
535 }
537 //*************************************************************************************************
538 
539 
540 //*************************************************************************************************
548 template< typename MT // Type of the adapted sparse matrix
549  , bool SO > // Storage order of the adapted sparse matrix
550 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n )
551  : matrix_( n, n ) // The adapted sparse matrix
552 {
554 
555  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
556 }
558 //*************************************************************************************************
559 
560 
561 //*************************************************************************************************
570 template< typename MT // Type of the adapted sparse matrix
571  , bool SO > // Storage order of the adapted sparse matrix
572 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, size_t nonzeros )
573  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
574 {
576 
577  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
578 }
580 //*************************************************************************************************
581 
582 
583 //*************************************************************************************************
594 template< typename MT // Type of the adapted sparse matrix
595  , bool SO > // Storage order of the adapted sparse matrix
596 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
597  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
598 {
600 
601  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
602 }
604 //*************************************************************************************************
605 
606 
607 //*************************************************************************************************
631 template< typename MT // Type of the adapted sparse matrix
632  , bool SO > // Storage order of the adapted sparse matrix
633 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( initializer_list< initializer_list<ElementType> > list )
634  : matrix_( list ) // The adapted sparse matrix
635 {
636  if( !isSymmetric( matrix_ ) ) {
637  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
638  }
639 
640  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
641 }
643 //*************************************************************************************************
644 
645 
646 //*************************************************************************************************
652 template< typename MT // Type of the adapted sparse matrix
653  , bool SO > // Storage order of the adapted sparse matrix
654 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const SymmetricMatrix& m )
655  : matrix_( m.matrix_ ) // The adapted sparse matrix
656 {
657  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
658  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
659 }
661 //*************************************************************************************************
662 
663 
664 //*************************************************************************************************
670 template< typename MT // Type of the adapted sparse matrix
671  , bool SO > // Storage order of the adapted sparse matrix
672 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( SymmetricMatrix&& m ) noexcept
673  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
674 {
675  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
676  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
677 }
679 //*************************************************************************************************
680 
681 
682 //*************************************************************************************************
692 template< typename MT // Type of the adapted sparse matrix
693  , bool SO > // Storage order of the adapted sparse matrix
694 template< typename MT2 > // Type of the foreign matrix
695 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,SO>& m )
696  : matrix_( ~m ) // The adapted sparse matrix
697 {
698  if( !IsSymmetric<MT2>::value && !isSymmetric( matrix_ ) ) {
699  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
700  }
701 
702  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
703  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
704 }
706 //*************************************************************************************************
707 
708 
709 //*************************************************************************************************
719 template< typename MT // Type of the adapted sparse matrix
720  , bool SO > // Storage order of the adapted sparse matrix
721 template< typename MT2 > // Type of the foreign matrix
722 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
723  : matrix_( trans( ~m ) ) // The adapted sparse matrix
724 {
725  if( !IsSymmetric<MT2>::value && !isSymmetric( matrix_ ) ) {
726  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
727  }
728 
729  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
730  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
731 }
733 //*************************************************************************************************
734 
735 
736 
737 
738 //=================================================================================================
739 //
740 // DATA ACCESS FUNCTIONS
741 //
742 //=================================================================================================
743 
744 //*************************************************************************************************
759 template< typename MT // Type of the adapted sparse matrix
760  , bool SO > // Storage order of the adapted sparse matrix
762  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j )
763 {
764  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
765  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
766 
767  return Reference( matrix_, i, j );
768 }
770 //*************************************************************************************************
771 
772 
773 //*************************************************************************************************
788 template< typename MT // Type of the adapted sparse matrix
789  , bool SO > // Storage order of the adapted sparse matrix
791  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j ) const
792 {
793  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
794  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
795 
796  return matrix_(i,j);
797 }
799 //*************************************************************************************************
800 
801 
802 //*************************************************************************************************
818 template< typename MT // Type of the adapted dense matrix
819  , bool SO > // Storage order of the adapted dense matrix
821  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j )
822 {
823  if( i >= rows() ) {
824  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
825  }
826  if( j >= columns() ) {
827  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
828  }
829  return (*this)(i,j);
830 }
832 //*************************************************************************************************
833 
834 
835 //*************************************************************************************************
851 template< typename MT // Type of the adapted dense matrix
852  , bool SO > // Storage order of the adapted dense matrix
854  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j ) const
855 {
856  if( i >= rows() ) {
857  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
858  }
859  if( j >= columns() ) {
860  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
861  }
862  return (*this)(i,j);
863 }
865 //*************************************************************************************************
866 
867 
868 //*************************************************************************************************
880 template< typename MT // Type of the adapted sparse matrix
881  , bool SO > // Storage order of the adapted sparse matrix
884 {
885  return Iterator( matrix_.begin(i), matrix_, i );
886 }
888 //*************************************************************************************************
889 
890 
891 //*************************************************************************************************
903 template< typename MT // Type of the adapted sparse matrix
904  , bool SO > // Storage order of the adapted sparse matrix
907 {
908  return matrix_.begin(i);
909 }
911 //*************************************************************************************************
912 
913 
914 //*************************************************************************************************
926 template< typename MT // Type of the adapted sparse matrix
927  , bool SO > // Storage order of the adapted sparse matrix
930 {
931  return matrix_.cbegin(i);
932 }
934 //*************************************************************************************************
935 
936 
937 //*************************************************************************************************
949 template< typename MT // Type of the adapted sparse matrix
950  , bool SO > // Storage order of the adapted sparse matrix
953 {
954  return Iterator( matrix_.end(i), matrix_, i );
955 }
957 //*************************************************************************************************
958 
959 
960 //*************************************************************************************************
972 template< typename MT // Type of the adapted sparse matrix
973  , bool SO > // Storage order of the adapted sparse matrix
976 {
977  return matrix_.end(i);
978 }
980 //*************************************************************************************************
981 
982 
983 //*************************************************************************************************
995 template< typename MT // Type of the adapted sparse matrix
996  , bool SO > // Storage order of the adapted sparse matrix
999 {
1000  return matrix_.cend(i);
1001 }
1003 //*************************************************************************************************
1004 
1005 
1006 
1007 
1008 //=================================================================================================
1009 //
1010 // ASSIGNMENT OPERATORS
1011 //
1012 //=================================================================================================
1013 
1014 //*************************************************************************************************
1039 template< typename MT // Type of the adapted sparse matrix
1040  , bool SO > // Storage order of the adapted sparse matrix
1041 inline SymmetricMatrix<MT,SO,false,true>&
1042  SymmetricMatrix<MT,SO,false,true>::operator=( initializer_list< initializer_list<ElementType> > list )
1043 {
1044  const InitializerMatrix<ElementType> tmp( list, list.size() );
1045 
1046  if( !isSymmetric( tmp ) ) {
1047  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1048  }
1049 
1050  matrix_ = list;
1051 
1052  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1053  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1054 
1055  return *this;
1056 }
1058 //*************************************************************************************************
1059 
1060 
1061 //*************************************************************************************************
1071 template< typename MT // Type of the adapted sparse matrix
1072  , bool SO > // Storage order of the adapted sparse matrix
1073 inline SymmetricMatrix<MT,SO,false,true>&
1074  SymmetricMatrix<MT,SO,false,true>::operator=( const SymmetricMatrix& rhs )
1075 {
1076  matrix_ = rhs.matrix_;
1077 
1078  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1079  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1080 
1081  return *this;
1082 }
1084 //*************************************************************************************************
1085 
1086 
1087 //*************************************************************************************************
1094 template< typename MT // Type of the adapted sparse matrix
1095  , bool SO > // Storage order of the adapted sparse matrix
1096 inline SymmetricMatrix<MT,SO,false,true>&
1097  SymmetricMatrix<MT,SO,false,true>::operator=( SymmetricMatrix&& rhs ) noexcept
1098 {
1099  matrix_ = std::move( rhs.matrix_ );
1100 
1101  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1102  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1103 
1104  return *this;
1105 }
1107 //*************************************************************************************************
1108 
1109 
1110 //*************************************************************************************************
1123 template< typename MT // Type of the adapted sparse matrix
1124  , bool SO > // Storage order of the adapted sparse matrix
1125 template< typename MT2 > // Type of the right-hand side matrix
1126 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1127  SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1128 {
1129  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1130  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1131  }
1132 
1133  matrix_ = ~rhs;
1134 
1135  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1136  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1137 
1138  return *this;
1139 }
1141 //*************************************************************************************************
1142 
1143 
1144 //*************************************************************************************************
1157 template< typename MT // Type of the adapted sparse matrix
1158  , bool SO > // Storage order of the adapted sparse matrix
1159 template< typename MT2 > // Type of the right-hand side matrix
1160 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1161  SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1162 {
1163  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1164  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1165  }
1166 
1167  if( IsSymmetric<MT2>::value ) {
1168  matrix_ = ~rhs;
1169  }
1170  else {
1171  MT tmp( ~rhs );
1172 
1173  if( !isSymmetric( tmp ) ) {
1174  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1175  }
1176 
1177  matrix_ = std::move( tmp );
1178  }
1179 
1180  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1181  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1182 
1183  return *this;
1184 }
1186 //*************************************************************************************************
1187 
1188 
1189 //*************************************************************************************************
1202 template< typename MT // Type of the adapted sparse matrix
1203  , bool SO > // Storage order of the adapted sparse matrix
1204 template< typename MT2 > // Type of the right-hand side matrix
1205 inline SymmetricMatrix<MT,SO,false,true>&
1206  SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,!SO>& rhs )
1207 {
1208  return this->operator=( trans( ~rhs ) );
1209 }
1211 //*************************************************************************************************
1212 
1213 
1214 //*************************************************************************************************
1227 template< typename MT // Type of the adapted sparse matrix
1228  , bool SO > // Storage order of the adapted sparse matrix
1229 template< typename MT2 > // Type of the right-hand side matrix
1230 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1231  SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1232 {
1233  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1234  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1235  }
1236 
1237  matrix_ += ~rhs;
1238 
1239  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1240  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1241 
1242  return *this;
1243 }
1245 //*************************************************************************************************
1246 
1247 
1248 //*************************************************************************************************
1261 template< typename MT // Type of the adapted sparse matrix
1262  , bool SO > // Storage order of the adapted sparse matrix
1263 template< typename MT2 > // Type of the right-hand side matrix
1264 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1265  SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1266 {
1267  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1268  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1269  }
1270 
1271  if( IsSymmetric<MT2>::value ) {
1272  matrix_ += ~rhs;
1273  }
1274  else {
1275  const ResultType_<MT2> tmp( ~rhs );
1276 
1277  if( !isSymmetric( tmp ) ) {
1278  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1279  }
1280 
1281  matrix_ += tmp;
1282  }
1283 
1284  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1285  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1286 
1287  return *this;
1288 }
1290 //*************************************************************************************************
1291 
1292 
1293 //*************************************************************************************************
1307 template< typename MT // Type of the adapted sparse matrix
1308  , bool SO > // Storage order of the adapted sparse matrix
1309 template< typename MT2 > // Type of the right-hand side matrix
1310 inline SymmetricMatrix<MT,SO,false,true>&
1311  SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,!SO>& rhs )
1312 {
1313  return this->operator+=( trans( ~rhs ) );
1314 }
1316 //*************************************************************************************************
1317 
1318 
1319 //*************************************************************************************************
1332 template< typename MT // Type of the adapted sparse matrix
1333  , bool SO > // Storage order of the adapted sparse matrix
1334 template< typename MT2 > // Type of the right-hand side matrix
1335 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1336  SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1337 {
1338  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1339  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1340  }
1341 
1342  matrix_ -= ~rhs;
1343 
1344  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1345  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1346 
1347  return *this;
1348 }
1350 //*************************************************************************************************
1351 
1352 
1353 //*************************************************************************************************
1366 template< typename MT // Type of the adapted sparse matrix
1367  , bool SO > // Storage order of the adapted sparse matrix
1368 template< typename MT2 > // Type of the right-hand side matrix
1369 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1370  SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1371 {
1372  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1373  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1374  }
1375 
1376  if( IsSymmetric<MT2>::value ) {
1377  matrix_ -= ~rhs;
1378  }
1379  else {
1380  const ResultType_<MT2> tmp( ~rhs );
1381 
1382  if( !isSymmetric( tmp ) ) {
1383  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1384  }
1385 
1386  matrix_ -= tmp;
1387  }
1388 
1389  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1390  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1391 
1392  return *this;
1393 }
1395 //*************************************************************************************************
1396 
1397 
1398 //*************************************************************************************************
1412 template< typename MT // Type of the adapted sparse matrix
1413  , bool SO > // Storage order of the adapted sparse matrix
1414 template< typename MT2 > // Type of the right-hand side matrix
1415 inline SymmetricMatrix<MT,SO,false,true>&
1416  SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,!SO>& rhs )
1417 {
1418  return this->operator-=( trans( ~rhs ) );
1419 }
1421 //*************************************************************************************************
1422 
1423 
1424 //*************************************************************************************************
1438 template< typename MT // Type of the adapted sparse matrix
1439  , bool SO > // Storage order of the adapted sparse matrix
1440 template< typename MT2 > // Type of the right-hand side matrix
1441 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1442  SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1443 {
1444  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1445  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1446  }
1447 
1448  matrix_ %= ~rhs;
1449 
1450  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1451  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1452 
1453  return *this;
1454 }
1456 //*************************************************************************************************
1457 
1458 
1459 //*************************************************************************************************
1473 template< typename MT // Type of the adapted sparse matrix
1474  , bool SO > // Storage order of the adapted sparse matrix
1475 template< typename MT2 > // Type of the right-hand side matrix
1476 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1477  SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1478 {
1479  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1480  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1481  }
1482 
1483  if( IsSymmetric<MT2>::value ) {
1484  matrix_ %= ~rhs;
1485  }
1486  else {
1487  const ResultType_<MT2> tmp( ~rhs );
1488 
1489  if( !isSymmetric( tmp ) ) {
1490  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1491  }
1492 
1493  matrix_ %= tmp;
1494  }
1495 
1496  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1497  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1498 
1499  return *this;
1500 }
1502 //*************************************************************************************************
1503 
1504 
1505 //*************************************************************************************************
1519 template< typename MT // Type of the adapted sparse matrix
1520  , bool SO > // Storage order of the adapted sparse matrix
1521 template< typename MT2 > // Type of the right-hand side matrix
1522 inline SymmetricMatrix<MT,SO,false,true>&
1523  SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,!SO>& rhs )
1524 {
1525  return this->operator%=( trans( ~rhs ) );
1526 }
1528 //*************************************************************************************************
1529 
1530 
1531 //*************************************************************************************************
1539 template< typename MT // Type of the adapted sparse matrix
1540  , bool SO > // Storage order of the adapted sparse matrix
1541 template< typename ST > // Data type of the right-hand side scalar
1542 inline EnableIf_< IsNumeric<ST>, SymmetricMatrix<MT,SO,false,true> >&
1544 {
1545  matrix_ *= rhs;
1546  return *this;
1547 }
1548 //*************************************************************************************************
1549 
1550 
1551 //*************************************************************************************************
1559 template< typename MT // Type of the adapted sparse matrix
1560  , bool SO > // Storage order of the adapted sparse matrix
1561 template< typename ST > // Data type of the right-hand side scalar
1562 inline EnableIf_< IsNumeric<ST>, SymmetricMatrix<MT,SO,false,true> >&
1564 {
1565  BLAZE_USER_ASSERT( !isZero( rhs ), "Division by zero detected" );
1566 
1567  matrix_ /= rhs;
1568  return *this;
1569 }
1571 //*************************************************************************************************
1572 
1573 
1574 
1575 
1576 //=================================================================================================
1577 //
1578 // UTILITY FUNCTIONS
1579 //
1580 //=================================================================================================
1581 
1582 //*************************************************************************************************
1588 template< typename MT // Type of the adapted sparse matrix
1589  , bool SO > // Storage order of the adapted sparse matrix
1590 inline size_t SymmetricMatrix<MT,SO,false,true>::rows() const noexcept
1591 {
1592  return matrix_.rows();
1593 }
1595 //*************************************************************************************************
1596 
1597 
1598 //*************************************************************************************************
1604 template< typename MT // Type of the adapted sparse matrix
1605  , bool SO > // Storage order of the adapted sparse matrix
1606 inline size_t SymmetricMatrix<MT,SO,false,true>::columns() const noexcept
1607 {
1608  return matrix_.columns();
1609 }
1611 //*************************************************************************************************
1612 
1613 
1614 //*************************************************************************************************
1620 template< typename MT // Type of the adapted sparse matrix
1621  , bool SO > // Storage order of the adapted sparse matrix
1622 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity() const noexcept
1623 {
1624  return matrix_.capacity();
1625 }
1627 //*************************************************************************************************
1628 
1629 
1630 //*************************************************************************************************
1641 template< typename MT // Type of the adapted sparse matrix
1642  , bool SO > // Storage order of the adapted sparse matrix
1643 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity( size_t i ) const noexcept
1644 {
1645  return matrix_.capacity(i);
1646 }
1648 //*************************************************************************************************
1649 
1650 
1651 //*************************************************************************************************
1657 template< typename MT // Type of the adapted sparse matrix
1658  , bool SO > // Storage order of the adapted sparse matrix
1659 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros() const
1660 {
1661  return matrix_.nonZeros();
1662 }
1664 //*************************************************************************************************
1665 
1666 
1667 //*************************************************************************************************
1679 template< typename MT // Type of the adapted sparse matrix
1680  , bool SO > // Storage order of the adapted sparse matrix
1681 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros( size_t i ) const
1682 {
1683  return matrix_.nonZeros(i);
1684 }
1686 //*************************************************************************************************
1687 
1688 
1689 //*************************************************************************************************
1695 template< typename MT // Type of the adapted sparse matrix
1696  , bool SO > // Storage order of the adapted sparse matrix
1698 {
1699  matrix_.reset();
1700 }
1702 //*************************************************************************************************
1703 
1704 
1705 //*************************************************************************************************
1741 template< typename MT // Type of the adapted sparse matrix
1742  , bool SO > // Storage order of the adapted sparse matrix
1743 inline void SymmetricMatrix<MT,SO,false,true>::reset( size_t i )
1744 {
1745  for( Iterator_<MT> it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1746  {
1747  const size_t j( it->index() );
1748 
1749  if( i == j )
1750  continue;
1751 
1752  if( SO ) {
1753  const Iterator_<MT> pos( matrix_.find( i, j ) );
1754  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1755  matrix_.erase( j, pos );
1756  }
1757  else {
1758  const Iterator_<MT> pos( matrix_.find( j, i ) );
1759  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1760  matrix_.erase( j, pos );
1761  }
1762  }
1763 
1764  matrix_.reset( i );
1765 }
1767 //*************************************************************************************************
1768 
1769 
1770 //*************************************************************************************************
1778 template< typename MT // Type of the adapted sparse matrix
1779  , bool SO > // Storage order of the adapted sparse matrix
1781 {
1782  using blaze::clear;
1783 
1784  clear( matrix_ );
1785 }
1787 //*************************************************************************************************
1788 
1789 
1790 //*************************************************************************************************
1805 template< typename MT // Type of the adapted sparse matrix
1806  , bool SO > // Storage order of the adapted sparse matrix
1807 void SymmetricMatrix<MT,SO,false,true>::resize( size_t n, bool preserve )
1808 {
1810 
1811  UNUSED_PARAMETER( preserve );
1812 
1813  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1814 
1815  matrix_.resize( n, n, true );
1816 }
1818 //*************************************************************************************************
1819 
1820 
1821 //*************************************************************************************************
1832 template< typename MT // Type of the adapted sparse matrix
1833  , bool SO > // Storage order of the adapted sparse matrix
1834 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t nonzeros )
1835 {
1836  matrix_.reserve( nonzeros );
1837 }
1839 //*************************************************************************************************
1840 
1841 
1842 //*************************************************************************************************
1856 template< typename MT // Type of the adapted sparse matrix
1857  , bool SO > // Storage order of the adapted sparse matrix
1858 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t i, size_t nonzeros )
1859 {
1860  matrix_.reserve( i, nonzeros );
1861 }
1863 //*************************************************************************************************
1864 
1865 
1866 //*************************************************************************************************
1877 template< typename MT // Type of the adapted sparse matrix
1878  , bool SO > // Storage order of the adapted sparse matrix
1879 inline void SymmetricMatrix<MT,SO,false,true>::trim()
1880 {
1881  matrix_.trim();
1882 }
1884 //*************************************************************************************************
1885 
1886 
1887 //*************************************************************************************************
1899 template< typename MT // Type of the adapted sparse matrix
1900  , bool SO > // Storage order of the adapted sparse matrix
1901 inline void SymmetricMatrix<MT,SO,false,true>::trim( size_t i )
1902 {
1903  matrix_.trim( i );
1904 }
1906 //*************************************************************************************************
1907 
1908 
1909 //*************************************************************************************************
1919 template< typename MT // Type of the adapted sparse matrix
1920  , bool SO > // Storage order of the adapted sparse matrix
1922 {
1923  matrix_.shrinkToFit();
1924 }
1926 //*************************************************************************************************
1927 
1928 
1929 //*************************************************************************************************
1936 template< typename MT // Type of the adapted sparse matrix
1937  , bool SO > // Storage order of the adapted sparse matrix
1938 inline void SymmetricMatrix<MT,SO,false,true>::swap( SymmetricMatrix& m ) noexcept
1939 {
1940  using std::swap;
1941 
1942  swap( matrix_, m.matrix_ );
1943 }
1945 //*************************************************************************************************
1946 
1947 
1948 
1949 
1950 //=================================================================================================
1951 //
1952 // INSERTION FUNCTIONS
1953 //
1954 //=================================================================================================
1955 
1956 //*************************************************************************************************
1970 template< typename MT // Type of the adapted sparse matrix
1971  , bool SO > // Storage order of the adapted sparse matrix
1973  SymmetricMatrix<MT,SO,false,true>::set( size_t i, size_t j, const ElementType& value )
1974 {
1975  if( i != j )
1976  matrix_.set( j, i, value );
1977  return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
1978 }
1980 //*************************************************************************************************
1981 
1982 
1983 //*************************************************************************************************
1998 template< typename MT // Type of the adapted sparse matrix
1999  , bool SO > // Storage order of the adapted sparse matrix
2001  SymmetricMatrix<MT,SO,false,true>::insert( size_t i, size_t j, const ElementType& value )
2002 {
2003  if( i != j )
2004  matrix_.insert( j, i, value );
2005  return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
2006 }
2008 //*************************************************************************************************
2009 
2010 
2011 //*************************************************************************************************
2066 template< typename MT // Type of the adapted sparse matrix
2067  , bool SO > // Storage order of the adapted sparse matrix
2068 inline void SymmetricMatrix<MT,SO,false,true>::append( size_t i, size_t j, const ElementType& value, bool check )
2069 {
2070  matrix_.append( i, j, value, check );
2071  if( i != j && ( !check || !isDefault<strict>( value ) ) )
2072  matrix_.insert( j, i, value );
2073 }
2075 //*************************************************************************************************
2076 
2077 
2078 //*************************************************************************************************
2092 template< typename MT // Type of the adapted sparse matrix
2093  , bool SO > // Storage order of the adapted sparse matrix
2094 inline void SymmetricMatrix<MT,SO,false,true>::finalize( size_t i )
2095 {
2096  matrix_.trim( i );
2097 }
2099 //*************************************************************************************************
2100 
2101 
2102 
2103 
2104 //=================================================================================================
2105 //
2106 // ERASE FUNCTIONS
2107 //
2108 //=================================================================================================
2109 
2110 //*************************************************************************************************
2120 template< typename MT // Type of the adapted sparse matrix
2121  , bool SO > // Storage order of the adapted sparse matrix
2122 inline void SymmetricMatrix<MT,SO,false,true>::erase( size_t i, size_t j )
2123 {
2124  matrix_.erase( i, j );
2125  if( i != j )
2126  matrix_.erase( j, i );
2127 }
2129 //*************************************************************************************************
2130 
2131 
2132 //*************************************************************************************************
2144 template< typename MT // Type of the adapted sparse matrix
2145  , bool SO > // Storage order of the adapted sparse matrix
2147  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator pos )
2148 {
2149  const Iterator_<MT> base( pos.base() );
2150 
2151  if( base == matrix_.end( i ) )
2152  return pos;
2153 
2154  const size_t j( base->index() );
2155 
2156  if( i == j ) {
2157  BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
2158  return Iterator( matrix_.erase( i, base ), matrix_, i );
2159  }
2160 
2161  if( SO ) {
2162  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2163  matrix_.erase( j, matrix_.find( i, j ) );
2164  return Iterator( matrix_.erase( i, base ), matrix_, i );
2165  }
2166  else {
2167  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2168  matrix_.erase( j, matrix_.find( j, i ) );
2169  return Iterator( matrix_.erase( i, base ), matrix_, i );
2170  }
2171 }
2173 //*************************************************************************************************
2174 
2175 
2176 //*************************************************************************************************
2190 template< typename MT // Type of the adapted sparse matrix
2191  , bool SO > // Storage order of the adapted sparse matrix
2193  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last )
2194 {
2195  for( Iterator_<MT> it=first.base(); it!=last.base(); ++it )
2196  {
2197  const size_t j( it->index() );
2198 
2199  if( i == j )
2200  continue;
2201 
2202  if( SO ) {
2203  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2204  matrix_.erase( i, j );
2205  }
2206  else {
2207  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2208  matrix_.erase( j, i );
2209  }
2210  }
2211 
2212  return Iterator( matrix_.erase( i, first.base(), last.base() ), matrix_, i );
2213 }
2215 //*************************************************************************************************
2216 
2217 
2218 //*************************************************************************************************
2240 template< typename MT // Type of the adapted sparse matrix
2241  , bool SO > // Storage order of the adapted sparse matrix
2242 template< typename Pred > // Type of the unary predicate
2243 inline void SymmetricMatrix<MT,SO,false,true>::erase( Pred predicate )
2244 {
2245  matrix_.erase( predicate );
2246 
2247  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2248 }
2250 //*************************************************************************************************
2251 
2252 
2253 //*************************************************************************************************
2281 template< typename MT // Type of the adapted sparse matrix
2282  , bool SO > // Storage order of the adapted sparse matrix
2283 template< typename Pred > // Type of the unary predicate
2284 inline void
2285  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2286 {
2287  for( Iterator it=first; it!=last; ++it ) {
2288  const size_t j( it->index() );
2289  if( i != j && predicate( it->value() ) ) {
2290  if( SO )
2291  matrix_.erase( i, j );
2292  else
2293  matrix_.erase( j, i );
2294  }
2295  }
2296 
2297  matrix_.erase( i, first.base(), last.base(), predicate );
2298 
2299  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2300 }
2302 //*************************************************************************************************
2303 
2304 
2305 
2306 
2307 //=================================================================================================
2308 //
2309 // LOOKUP FUNCTIONS
2310 //
2311 //=================================================================================================
2312 
2313 //*************************************************************************************************
2329 template< typename MT // Type of the adapted sparse matrix
2330  , bool SO > // Storage order of the adapted sparse matrix
2332  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j )
2333 {
2334  return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2335 }
2337 //*************************************************************************************************
2338 
2339 
2340 //*************************************************************************************************
2356 template< typename MT // Type of the adapted sparse matrix
2357  , bool SO > // Storage order of the adapted sparse matrix
2359  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j ) const
2360 {
2361  return matrix_.find( i, j );
2362 }
2364 //*************************************************************************************************
2365 
2366 
2367 //*************************************************************************************************
2383 template< typename MT // Type of the adapted sparse matrix
2384  , bool SO > // Storage order of the adapted sparse matrix
2386  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j )
2387 {
2388  return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2389 }
2391 //*************************************************************************************************
2392 
2393 
2394 //*************************************************************************************************
2410 template< typename MT // Type of the adapted sparse matrix
2411  , bool SO > // Storage order of the adapted sparse matrix
2413  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j ) const
2414 {
2415  return matrix_.lowerBound( i, j );
2416 }
2418 //*************************************************************************************************
2419 
2420 
2421 //*************************************************************************************************
2437 template< typename MT // Type of the adapted sparse matrix
2438  , bool SO > // Storage order of the adapted sparse matrix
2440  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j )
2441 {
2442  return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2443 }
2445 //*************************************************************************************************
2446 
2447 
2448 //*************************************************************************************************
2464 template< typename MT // Type of the adapted sparse matrix
2465  , bool SO > // Storage order of the adapted sparse matrix
2467  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j ) const
2468 {
2469  return matrix_.upperBound( i, j );
2470 }
2472 //*************************************************************************************************
2473 
2474 
2475 
2476 
2477 //=================================================================================================
2478 //
2479 // NUMERIC FUNCTIONS
2480 //
2481 //=================================================================================================
2482 
2483 //*************************************************************************************************
2489 template< typename MT // Type of the adapted sparse matrix
2490  , bool SO > // Storage order of the adapted sparse matrix
2491 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::transpose()
2492 {
2493  return *this;
2494 }
2496 //*************************************************************************************************
2497 
2498 
2499 //*************************************************************************************************
2505 template< typename MT // Type of the adapted sparse matrix
2506  , bool SO > // Storage order of the adapted sparse matrix
2507 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::ctranspose()
2508 {
2509  if( !IsBuiltin<ElementType>::value )
2510  conjugate( matrix_ );
2511 
2512  return *this;
2513 }
2515 //*************************************************************************************************
2516 
2517 
2518 //*************************************************************************************************
2536 template< typename MT // Type of the adapted sparse matrix
2537  , bool SO > // Storage order of the adapted sparse matrix
2538 template< typename Other > // Data type of the scalar value
2539 inline SymmetricMatrix<MT,SO,false,true>&
2540  SymmetricMatrix<MT,SO,false,true>::scale( const Other& scalar )
2541 {
2542  matrix_.scale( scalar );
2543  return *this;
2544 }
2546 //*************************************************************************************************
2547 
2548 
2549 
2550 
2551 //=================================================================================================
2552 //
2553 // DEBUGGING FUNCTIONS
2554 //
2555 //=================================================================================================
2556 
2557 //*************************************************************************************************
2567 template< typename MT // Type of the adapted sparse matrix
2568  , bool SO > // Storage order of the adapted sparse matrix
2569 inline bool SymmetricMatrix<MT,SO,false,true>::isIntact() const noexcept
2570 {
2571  using blaze::isIntact;
2572 
2573  return ( isIntact( matrix_ ) && isSymmetric( matrix_ ) );
2574 }
2576 //*************************************************************************************************
2577 
2578 
2579 
2580 
2581 //=================================================================================================
2582 //
2583 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2584 //
2585 //=================================================================================================
2586 
2587 //*************************************************************************************************
2598 template< typename MT // Type of the adapted sparse matrix
2599  , bool SO > // Storage order of the adapted sparse matrix
2600 template< typename Other > // Data type of the foreign expression
2601 inline bool SymmetricMatrix<MT,SO,false,true>::canAlias( const Other* alias ) const noexcept
2602 {
2603  return matrix_.canAlias( alias );
2604 }
2606 //*************************************************************************************************
2607 
2608 
2609 //*************************************************************************************************
2620 template< typename MT // Type of the adapted sparse matrix
2621  , bool SO > // Storage order of the adapted sparse matrix
2622 template< typename Other > // Data type of the foreign expression
2623 inline bool SymmetricMatrix<MT,SO,false,true>::isAliased( const Other* alias ) const noexcept
2624 {
2625  return matrix_.isAliased( alias );
2626 }
2628 //*************************************************************************************************
2629 
2630 
2631 //*************************************************************************************************
2642 template< typename MT // Type of the adapted sparse matrix
2643  , bool SO > // Storage order of the adapted sparse matrix
2644 inline bool SymmetricMatrix<MT,SO,false,true>::canSMPAssign() const noexcept
2645 {
2646  return matrix_.canSMPAssign();
2647 }
2649 //*************************************************************************************************
2650 
2651 } // namespace blaze
2652 
2653 #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:3077
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the UNUSED_PARAMETER function template.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:522
Header file for basic type definitions.
#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
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3076
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:364
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3074
Constraint on the data type.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
BLAZE_ALWAYS_INLINE void shrinkToFit(Matrix< MT, SO > &matrix)
Requesting the removal of unused capacity.
Definition: Matrix.h:775
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:5829
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3078
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:827
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3083
#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:560
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:733
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3084
Header file for the extended initializer_list functionality.
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:474
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:408
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:670
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:3082
Header file for the clear shim.
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:5908
Compile time assertion.
bool isIntact(const CompressedMatrix< Type, SO > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:5891
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3079
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
Header file for the isZero shim.
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:506
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:714
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:430
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:608
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:272
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:841
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:490
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
EnableIf_< IsNumeric< ST >, MT &> operator/=(DenseMatrix< MT, SO > &mat, ST scalar)
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:655
#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:3081
#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:254
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
#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
EnableIf_< IsNumeric< ST >, MT &> operator*=(DenseMatrix< MT, SO > &mat, ST scalar)
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:593
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:908
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
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:801