Blaze  3.6
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>
61 #include <blaze/math/Exception.h>
65 #include <blaze/math/shims/Clear.h>
74 #include <blaze/util/Assert.h>
80 #include <blaze/util/DisableIf.h>
81 #include <blaze/util/EnableIf.h>
82 #include <blaze/util/MaybeUnused.h>
86 #include <blaze/util/Types.h>
87 
88 
89 namespace blaze {
90 
91 //=================================================================================================
92 //
93 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES WITH NUMERIC ELEMENT TYPE
94 //
95 //=================================================================================================
96 
97 //*************************************************************************************************
105 template< typename MT // Type of the adapted sparse matrix
106  , bool SO > // Storage order of the adapted sparse matrix
107 class SymmetricMatrix<MT,SO,false,true>
108  : public SparseMatrix< SymmetricMatrix<MT,SO,false,true>, SO >
109 {
110  private:
111  //**Type definitions****************************************************************************
112  using OT = OppositeType_t<MT>;
113  using TT = TransposeType_t<MT>;
114  using ET = ElementType_t<MT>;
115  //**********************************************************************************************
116 
117  public:
118  //**Type definitions****************************************************************************
119  using This = SymmetricMatrix<MT,SO,false,true>;
120  using BaseType = SparseMatrix<This,SO>;
121  using ResultType = This;
122  using OppositeType = SymmetricMatrix<OT,!SO,false,true>;
123  using TransposeType = SymmetricMatrix<TT,!SO,false,true>;
124  using ElementType = ET;
125  using ReturnType = ReturnType_t<MT>;
126  using CompositeType = const This&;
127  using Reference = NumericProxy<MT>;
128  using ConstReference = ConstReference_t<MT>;
129  using ConstIterator = ConstIterator_t<MT>;
130  //**********************************************************************************************
131 
132  //**Rebind struct definition********************************************************************
135  template< typename NewType > // Data type of the other matrix
136  struct Rebind {
138  using Other = SymmetricMatrix< typename MT::template Rebind<NewType>::Other >;
139  };
140  //**********************************************************************************************
141 
142  //**Resize struct definition********************************************************************
145  template< size_t NewM // Number of rows of the other matrix
146  , size_t NewN > // Number of columns of the other matrix
147  struct Resize {
149  using Other = SymmetricMatrix< typename MT::template Resize<NewM,NewN>::Other >;
150  };
151  //**********************************************************************************************
152 
153  //**Iterator class definition*******************************************************************
156  class Iterator
157  {
158  public:
159  //**Type definitions*************************************************************************
160  using IteratorType = Iterator_t<MT>;
161 
162  using IteratorCategory = std::forward_iterator_tag;
163  using ValueType = SymmetricElement<MT>;
164  using PointerType = ValueType;
165  using ReferenceType = ValueType;
166  using DifferenceType = ptrdiff_t;
167 
168  // STL iterator requirements
169  using iterator_category = IteratorCategory;
170  using value_type = ValueType;
171  using pointer = PointerType;
172  using reference = ReferenceType;
173  using difference_type = DifferenceType;
174  //*******************************************************************************************
175 
176  //**Default constructor**********************************************************************
179  inline Iterator()
180  : pos_ () // Iterator to the current sparse symmetric matrix element
181  , matrix_( nullptr ) // The sparse matrix containing the iterator
182  , index_ ( 0UL ) // The row/column index of the iterator
183  {}
184  //*******************************************************************************************
185 
186  //**Constructor******************************************************************************
193  inline Iterator( IteratorType pos, MT& matrix, size_t index )
194  : pos_ ( pos ) // Iterator to the current sparse symmetric matrix element
195  , matrix_( &matrix ) // The sparse matrix containing the iterator
196  , index_ ( index ) // The row/column index of the iterator
197  {}
198  //*******************************************************************************************
199 
200  //**Prefix increment operator****************************************************************
205  inline Iterator& operator++() {
206  ++pos_;
207  return *this;
208  }
209  //*******************************************************************************************
210 
211  //**Postfix increment operator***************************************************************
216  inline const Iterator operator++( int ) {
217  const Iterator tmp( *this );
218  ++(*this);
219  return tmp;
220  }
221  //*******************************************************************************************
222 
223  //**Element access operator******************************************************************
228  inline ReferenceType operator*() const {
229  return ReferenceType( pos_, matrix_, index_ );
230  }
231  //*******************************************************************************************
232 
233  //**Element access operator******************************************************************
238  inline PointerType operator->() const {
239  return PointerType( pos_, matrix_, index_ );
240  }
241  //*******************************************************************************************
242 
243  //**Conversion operator**********************************************************************
248  inline operator ConstIterator() const {
249  return pos_;
250  }
251  //*******************************************************************************************
252 
253  //**Equality operator************************************************************************
259  inline bool operator==( const Iterator& rhs ) const {
260  return pos_ == rhs.pos_;
261  }
262  //*******************************************************************************************
263 
264  //**Inequality operator**********************************************************************
270  inline bool operator!=( const Iterator& rhs ) const {
271  return !( *this == rhs );
272  }
273  //*******************************************************************************************
274 
275  //**Subtraction operator*********************************************************************
281  inline DifferenceType operator-( const Iterator& rhs ) const {
282  return pos_ - rhs.pos_;
283  }
284  //*******************************************************************************************
285 
286  //**Base function****************************************************************************
291  inline IteratorType base() const {
292  return pos_;
293  }
294  //*******************************************************************************************
295 
296  private:
297  //**Member variables*************************************************************************
298  IteratorType pos_;
299  MT* matrix_;
300  size_t index_;
301  //*******************************************************************************************
302  };
303  //**********************************************************************************************
304 
305  //**Compilation flags***************************************************************************
307  static constexpr bool smpAssignable = false;
308  //**********************************************************************************************
309 
310  //**Constructors********************************************************************************
313  explicit inline SymmetricMatrix();
314  explicit inline SymmetricMatrix( size_t n );
315  explicit inline SymmetricMatrix( size_t n, size_t nonzeros );
316  explicit inline SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros );
317  inline SymmetricMatrix( initializer_list< initializer_list<ElementType> > list );
318 
319  inline SymmetricMatrix( const SymmetricMatrix& m );
320  inline SymmetricMatrix( SymmetricMatrix&& m ) noexcept;
321 
322  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
323  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
325  //**********************************************************************************************
326 
327  //**Destructor**********************************************************************************
330  ~SymmetricMatrix() = default;
332  //**********************************************************************************************
333 
334  //**Data access functions***********************************************************************
337  inline Reference operator()( size_t i, size_t j );
338  inline ConstReference operator()( size_t i, size_t j ) const;
339  inline Reference at( size_t i, size_t j );
340  inline ConstReference at( size_t i, size_t j ) const;
341  inline Iterator begin ( size_t i );
342  inline ConstIterator begin ( size_t i ) const;
343  inline ConstIterator cbegin( size_t i ) const;
344  inline Iterator end ( size_t i );
345  inline ConstIterator end ( size_t i ) const;
346  inline ConstIterator cend ( size_t i ) const;
348  //**********************************************************************************************
349 
350  //**Assignment operators************************************************************************
353  inline SymmetricMatrix& operator=( initializer_list< initializer_list<ElementType> > list );
354 
355  inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
356  inline SymmetricMatrix& operator=( SymmetricMatrix&& rhs ) noexcept;
357 
358  template< typename MT2 >
359  inline auto operator=( const Matrix<MT2,SO>& rhs )
360  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
361 
362  template< typename MT2 >
363  inline auto operator=( const Matrix<MT2,SO>& rhs )
364  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
365 
366  template< typename MT2 >
367  inline auto operator=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
368 
369  template< typename MT2 >
370  inline auto operator+=( const Matrix<MT2,SO>& rhs )
371  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
372 
373  template< typename MT2 >
374  inline auto operator+=( const Matrix<MT2,SO>& rhs )
375  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
376 
377  template< typename MT2 >
378  inline auto operator+=( const Matrix<MT2,!SO>& rhs )
379  -> SymmetricMatrix&;
380 
381  template< typename MT2 >
382  inline auto operator-=( const Matrix<MT2,SO>& rhs )
383  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
384 
385  template< typename MT2 >
386  inline auto operator-=( const Matrix<MT2,SO>& rhs )
387  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
388 
389  template< typename MT2 >
390  inline auto operator-=( const Matrix<MT2,!SO>& rhs )
391  -> SymmetricMatrix&;
392 
393  template< typename MT2 >
394  inline auto operator%=( const Matrix<MT2,SO>& rhs )
395  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
396 
397  template< typename MT2 >
398  inline auto operator%=( const Matrix<MT2,SO>& rhs )
399  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
400 
401  template< typename MT2 >
402  inline auto operator%=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
403 
404  template< typename ST >
405  inline auto operator*=( ST rhs ) -> EnableIf_t< IsNumeric_v<ST>, SymmetricMatrix& >;
406 
407  template< typename ST >
408  inline auto operator/=( ST rhs ) -> EnableIf_t< IsNumeric_v<ST>, SymmetricMatrix& >;
410  //**********************************************************************************************
411 
412  //**Utility functions***************************************************************************
415  inline size_t rows() const noexcept;
416  inline size_t columns() const noexcept;
417  inline size_t capacity() const noexcept;
418  inline size_t capacity( size_t i ) const noexcept;
419  inline size_t nonZeros() const;
420  inline size_t nonZeros( size_t i ) const;
421  inline void reset();
422  inline void reset( size_t i );
423  inline void clear();
424  inline void resize ( size_t n, bool preserve=true );
425  inline void reserve( size_t nonzeros );
426  inline void reserve( size_t i, size_t nonzeros );
427  inline void trim();
428  inline void trim( size_t i );
429  inline void shrinkToFit();
430  inline void swap( SymmetricMatrix& m ) noexcept;
432  //**********************************************************************************************
433 
434  //**Insertion functions*************************************************************************
437  inline Iterator set ( size_t i, size_t j, const ElementType& value );
438  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
439  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
440  inline void finalize( size_t i );
442  //**********************************************************************************************
443 
444  //**Erase functions*****************************************************************************
447  inline void erase( size_t i, size_t j );
448  inline Iterator erase( size_t i, Iterator pos );
449  inline Iterator erase( size_t i, Iterator first, Iterator last );
450 
451  template< typename Pred >
452  inline void erase( Pred predicate );
453 
454  template< typename Pred >
455  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
457  //**********************************************************************************************
458 
459  //**Lookup functions****************************************************************************
462  inline Iterator find ( size_t i, size_t j );
463  inline ConstIterator find ( size_t i, size_t j ) const;
464  inline Iterator lowerBound( size_t i, size_t j );
465  inline ConstIterator lowerBound( size_t i, size_t j ) const;
466  inline Iterator upperBound( size_t i, size_t j );
467  inline ConstIterator upperBound( size_t i, size_t j ) const;
469  //**********************************************************************************************
470 
471  //**Numeric functions***************************************************************************
474  inline SymmetricMatrix& transpose();
475  inline SymmetricMatrix& ctranspose();
476 
477  template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
479  //**********************************************************************************************
480 
481  //**Debugging functions*************************************************************************
484  inline bool isIntact() const noexcept;
486  //**********************************************************************************************
487 
488  //**Expression template evaluation functions****************************************************
491  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
492  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
493 
494  inline bool canSMPAssign() const noexcept;
496  //**********************************************************************************************
497 
498  private:
499  //**Member variables****************************************************************************
502  MT matrix_;
503 
504  //**********************************************************************************************
505 
506  //**Friend declarations*************************************************************************
507  template< bool RF, typename MT2, bool SO2, bool DF2, bool NF2 >
508  friend bool isDefault( const SymmetricMatrix<MT2,SO2,DF2,NF2>& m );
509  //**********************************************************************************************
510 
511  //**Compile time checks*************************************************************************
527  BLAZE_STATIC_ASSERT( ( Size_v<MT,0UL> == Size_v<MT,1UL> ) );
528  //**********************************************************************************************
529 };
531 //*************************************************************************************************
532 
533 
534 
535 
536 //=================================================================================================
537 //
538 // CONSTRUCTORS
539 //
540 //=================================================================================================
541 
542 //*************************************************************************************************
546 template< typename MT // Type of the adapted sparse matrix
547  , bool SO > // Storage order of the adapted sparse matrix
548 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix()
549  : matrix_() // The adapted sparse matrix
550 {
551  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
552 }
554 //*************************************************************************************************
555 
556 
557 //*************************************************************************************************
565 template< typename MT // Type of the adapted sparse matrix
566  , bool SO > // Storage order of the adapted sparse matrix
567 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n )
568  : matrix_( n, n ) // The adapted sparse matrix
569 {
571 
572  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
573 }
575 //*************************************************************************************************
576 
577 
578 //*************************************************************************************************
587 template< typename MT // Type of the adapted sparse matrix
588  , bool SO > // Storage order of the adapted sparse matrix
589 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, size_t nonzeros )
590  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
591 {
593 
594  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
595 }
597 //*************************************************************************************************
598 
599 
600 //*************************************************************************************************
611 template< typename MT // Type of the adapted sparse matrix
612  , bool SO > // Storage order of the adapted sparse matrix
613 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
614  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
615 {
617 
618  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
619 }
621 //*************************************************************************************************
622 
623 
624 //*************************************************************************************************
648 template< typename MT // Type of the adapted sparse matrix
649  , bool SO > // Storage order of the adapted sparse matrix
650 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( initializer_list< initializer_list<ElementType> > list )
651  : matrix_( list ) // The adapted sparse matrix
652 {
653  if( !isSymmetric( matrix_ ) ) {
654  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
655  }
656 
657  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
658 }
660 //*************************************************************************************************
661 
662 
663 //*************************************************************************************************
669 template< typename MT // Type of the adapted sparse matrix
670  , bool SO > // Storage order of the adapted sparse matrix
671 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const SymmetricMatrix& m )
672  : matrix_( m.matrix_ ) // The adapted sparse matrix
673 {
674  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
675  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
676 }
678 //*************************************************************************************************
679 
680 
681 //*************************************************************************************************
687 template< typename MT // Type of the adapted sparse matrix
688  , bool SO > // Storage order of the adapted sparse matrix
689 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( SymmetricMatrix&& m ) noexcept
690  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
691 {
692  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
693  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
694 }
696 //*************************************************************************************************
697 
698 
699 //*************************************************************************************************
709 template< typename MT // Type of the adapted sparse matrix
710  , bool SO > // Storage order of the adapted sparse matrix
711 template< typename MT2 > // Type of the foreign matrix
712 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,SO>& m )
713  : matrix_( ~m ) // The adapted sparse matrix
714 {
715  if( !IsSymmetric_v<MT2> && !isSymmetric( matrix_ ) ) {
716  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
717  }
718 
719  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
720  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
721 }
723 //*************************************************************************************************
724 
725 
726 //*************************************************************************************************
736 template< typename MT // Type of the adapted sparse matrix
737  , bool SO > // Storage order of the adapted sparse matrix
738 template< typename MT2 > // Type of the foreign matrix
739 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
740  : matrix_( trans( ~m ) ) // The adapted sparse matrix
741 {
742  if( !IsSymmetric_v<MT2> && !isSymmetric( matrix_ ) ) {
743  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
744  }
745 
746  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
747  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
748 }
750 //*************************************************************************************************
751 
752 
753 
754 
755 //=================================================================================================
756 //
757 // DATA ACCESS FUNCTIONS
758 //
759 //=================================================================================================
760 
761 //*************************************************************************************************
776 template< typename MT // Type of the adapted sparse matrix
777  , bool SO > // Storage order of the adapted sparse matrix
778 inline typename SymmetricMatrix<MT,SO,false,true>::Reference
779  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j )
780 {
781  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
782  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
783 
784  return Reference( matrix_, i, j );
785 }
787 //*************************************************************************************************
788 
789 
790 //*************************************************************************************************
805 template< typename MT // Type of the adapted sparse matrix
806  , bool SO > // Storage order of the adapted sparse matrix
807 inline typename SymmetricMatrix<MT,SO,false,true>::ConstReference
808  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j ) const
809 {
810  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
811  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
812 
813  return matrix_(i,j);
814 }
816 //*************************************************************************************************
817 
818 
819 //*************************************************************************************************
835 template< typename MT // Type of the adapted dense matrix
836  , bool SO > // Storage order of the adapted dense matrix
837 inline typename SymmetricMatrix<MT,SO,false,true>::Reference
838  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j )
839 {
840  if( i >= rows() ) {
841  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
842  }
843  if( j >= columns() ) {
844  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
845  }
846  return (*this)(i,j);
847 }
849 //*************************************************************************************************
850 
851 
852 //*************************************************************************************************
868 template< typename MT // Type of the adapted dense matrix
869  , bool SO > // Storage order of the adapted dense matrix
870 inline typename SymmetricMatrix<MT,SO,false,true>::ConstReference
871  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j ) const
872 {
873  if( i >= rows() ) {
874  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
875  }
876  if( j >= columns() ) {
877  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
878  }
879  return (*this)(i,j);
880 }
882 //*************************************************************************************************
883 
884 
885 //*************************************************************************************************
897 template< typename MT // Type of the adapted sparse matrix
898  , bool SO > // Storage order of the adapted sparse matrix
899 inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
901 {
902  return Iterator( matrix_.begin(i), matrix_, i );
903 }
905 //*************************************************************************************************
906 
907 
908 //*************************************************************************************************
920 template< typename MT // Type of the adapted sparse matrix
921  , bool SO > // Storage order of the adapted sparse matrix
922 inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
924 {
925  return matrix_.begin(i);
926 }
928 //*************************************************************************************************
929 
930 
931 //*************************************************************************************************
943 template< typename MT // Type of the adapted sparse matrix
944  , bool SO > // Storage order of the adapted sparse matrix
945 inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
947 {
948  return matrix_.cbegin(i);
949 }
951 //*************************************************************************************************
952 
953 
954 //*************************************************************************************************
966 template< typename MT // Type of the adapted sparse matrix
967  , bool SO > // Storage order of the adapted sparse matrix
968 inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
970 {
971  return Iterator( matrix_.end(i), matrix_, i );
972 }
974 //*************************************************************************************************
975 
976 
977 //*************************************************************************************************
989 template< typename MT // Type of the adapted sparse matrix
990  , bool SO > // Storage order of the adapted sparse matrix
991 inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
993 {
994  return matrix_.end(i);
995 }
997 //*************************************************************************************************
998 
999 
1000 //*************************************************************************************************
1012 template< typename MT // Type of the adapted sparse matrix
1013  , bool SO > // Storage order of the adapted sparse matrix
1014 inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
1015  SymmetricMatrix<MT,SO,false,true>::cend( size_t i ) const
1016 {
1017  return matrix_.cend(i);
1018 }
1020 //*************************************************************************************************
1021 
1022 
1023 
1024 
1025 //=================================================================================================
1026 //
1027 // ASSIGNMENT OPERATORS
1028 //
1029 //=================================================================================================
1030 
1031 //*************************************************************************************************
1056 template< typename MT // Type of the adapted sparse matrix
1057  , bool SO > // Storage order of the adapted sparse matrix
1058 inline SymmetricMatrix<MT,SO,false,true>&
1059  SymmetricMatrix<MT,SO,false,true>::operator=( initializer_list< initializer_list<ElementType> > list )
1060 {
1061  const InitializerMatrix<ElementType> tmp( list, list.size() );
1062 
1063  if( !isSymmetric( tmp ) ) {
1064  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1065  }
1066 
1067  matrix_ = list;
1068 
1069  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1070  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1071 
1072  return *this;
1073 }
1075 //*************************************************************************************************
1076 
1077 
1078 //*************************************************************************************************
1088 template< typename MT // Type of the adapted sparse matrix
1089  , bool SO > // Storage order of the adapted sparse matrix
1090 inline SymmetricMatrix<MT,SO,false,true>&
1091  SymmetricMatrix<MT,SO,false,true>::operator=( const SymmetricMatrix& rhs )
1092 {
1093  matrix_ = rhs.matrix_;
1094 
1095  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1096  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1097 
1098  return *this;
1099 }
1101 //*************************************************************************************************
1102 
1103 
1104 //*************************************************************************************************
1111 template< typename MT // Type of the adapted sparse matrix
1112  , bool SO > // Storage order of the adapted sparse matrix
1113 inline SymmetricMatrix<MT,SO,false,true>&
1114  SymmetricMatrix<MT,SO,false,true>::operator=( SymmetricMatrix&& rhs ) noexcept
1115 {
1116  matrix_ = std::move( rhs.matrix_ );
1117 
1118  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1119  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1120 
1121  return *this;
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 auto SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1144  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1145 {
1146  if( !IsSymmetric_v<MT2> && !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 auto SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1178  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1179 {
1180  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1181  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1182  }
1183 
1184  if( IsSymmetric_v<MT2> ) {
1185  matrix_ = ~rhs;
1186  }
1187  else {
1188  MT tmp( ~rhs );
1189 
1190  if( !isSymmetric( tmp ) ) {
1191  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1192  }
1193 
1194  matrix_ = std::move( 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 //*************************************************************************************************
1219 template< typename MT // Type of the adapted sparse matrix
1220  , bool SO > // Storage order of the adapted sparse matrix
1221 template< typename MT2 > // Type of the right-hand side matrix
1222 inline auto SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,!SO>& rhs )
1223  -> SymmetricMatrix&
1224 {
1225  return this->operator=( trans( ~rhs ) );
1226 }
1228 //*************************************************************************************************
1229 
1230 
1231 //*************************************************************************************************
1244 template< typename MT // Type of the adapted sparse matrix
1245  , bool SO > // Storage order of the adapted sparse matrix
1246 template< typename MT2 > // Type of the right-hand side matrix
1247 inline auto SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1248  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1249 {
1250  if( !IsSymmetric_v<MT2> && !isSymmetric( ~rhs ) ) {
1251  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1252  }
1253 
1254  matrix_ += ~rhs;
1255 
1256  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1257  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1258 
1259  return *this;
1260 }
1262 //*************************************************************************************************
1263 
1264 
1265 //*************************************************************************************************
1278 template< typename MT // Type of the adapted sparse matrix
1279  , bool SO > // Storage order of the adapted sparse matrix
1280 template< typename MT2 > // Type of the right-hand side matrix
1281 inline auto SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1282  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1283 {
1284  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1285  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1286  }
1287 
1288  if( IsSymmetric_v<MT2> ) {
1289  matrix_ += ~rhs;
1290  }
1291  else {
1292  const ResultType_t<MT2> tmp( ~rhs );
1293 
1294  if( !isSymmetric( tmp ) ) {
1295  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1296  }
1297 
1298  matrix_ += tmp;
1299  }
1300 
1301  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1302  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1303 
1304  return *this;
1305 }
1307 //*************************************************************************************************
1308 
1309 
1310 //*************************************************************************************************
1324 template< typename MT // Type of the adapted sparse matrix
1325  , bool SO > // Storage order of the adapted sparse matrix
1326 template< typename MT2 > // Type of the right-hand side matrix
1327 inline auto SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,!SO>& rhs )
1328  -> SymmetricMatrix&
1329 {
1330  return this->operator+=( trans( ~rhs ) );
1331 }
1333 //*************************************************************************************************
1334 
1335 
1336 //*************************************************************************************************
1349 template< typename MT // Type of the adapted sparse matrix
1350  , bool SO > // Storage order of the adapted sparse matrix
1351 template< typename MT2 > // Type of the right-hand side matrix
1352 inline auto SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1353  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1354 {
1355  if( !IsSymmetric_v<MT2> && !isSymmetric( ~rhs ) ) {
1356  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1357  }
1358 
1359  matrix_ -= ~rhs;
1360 
1361  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1362  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1363 
1364  return *this;
1365 }
1367 //*************************************************************************************************
1368 
1369 
1370 //*************************************************************************************************
1383 template< typename MT // Type of the adapted sparse matrix
1384  , bool SO > // Storage order of the adapted sparse matrix
1385 template< typename MT2 > // Type of the right-hand side matrix
1386 inline auto SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1387  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1388 {
1389  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1390  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1391  }
1392 
1393  if( IsSymmetric_v<MT2> ) {
1394  matrix_ -= ~rhs;
1395  }
1396  else {
1397  const ResultType_t<MT2> tmp( ~rhs );
1398 
1399  if( !isSymmetric( tmp ) ) {
1400  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1401  }
1402 
1403  matrix_ -= tmp;
1404  }
1405 
1406  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1407  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1408 
1409  return *this;
1410 }
1412 //*************************************************************************************************
1413 
1414 
1415 //*************************************************************************************************
1429 template< typename MT // Type of the adapted sparse matrix
1430  , bool SO > // Storage order of the adapted sparse matrix
1431 template< typename MT2 > // Type of the right-hand side matrix
1432 inline auto SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,!SO>& rhs )
1433  -> SymmetricMatrix&
1434 {
1435  return this->operator-=( trans( ~rhs ) );
1436 }
1438 //*************************************************************************************************
1439 
1440 
1441 //*************************************************************************************************
1455 template< typename MT // Type of the adapted sparse matrix
1456  , bool SO > // Storage order of the adapted sparse matrix
1457 template< typename MT2 > // Type of the right-hand side matrix
1458 inline auto SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1459  -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1460 {
1461  if( !IsSymmetric_v<MT2> && !isSymmetric( ~rhs ) ) {
1462  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1463  }
1464 
1465  matrix_ %= ~rhs;
1466 
1467  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1468  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1469 
1470  return *this;
1471 }
1473 //*************************************************************************************************
1474 
1475 
1476 //*************************************************************************************************
1490 template< typename MT // Type of the adapted sparse matrix
1491  , bool SO > // Storage order of the adapted sparse matrix
1492 template< typename MT2 > // Type of the right-hand side matrix
1493 inline auto SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1494  -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1495 {
1496  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1497  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1498  }
1499 
1500  if( IsSymmetric_v<MT2> ) {
1501  matrix_ %= ~rhs;
1502  }
1503  else {
1504  const ResultType_t<MT2> tmp( ~rhs );
1505 
1506  if( !isSymmetric( tmp ) ) {
1507  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1508  }
1509 
1510  matrix_ %= tmp;
1511  }
1512 
1513  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1514  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1515 
1516  return *this;
1517 }
1519 //*************************************************************************************************
1520 
1521 
1522 //*************************************************************************************************
1536 template< typename MT // Type of the adapted sparse matrix
1537  , bool SO > // Storage order of the adapted sparse matrix
1538 template< typename MT2 > // Type of the right-hand side matrix
1539 inline auto SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,!SO>& rhs )
1540  -> SymmetricMatrix&
1541 {
1542  return this->operator%=( trans( ~rhs ) );
1543 }
1545 //*************************************************************************************************
1546 
1547 
1548 //*************************************************************************************************
1556 template< typename MT // Type of the adapted sparse matrix
1557  , bool SO > // Storage order of the adapted sparse matrix
1558 template< typename ST > // Data type of the right-hand side scalar
1560  -> EnableIf_t< IsNumeric_v<ST>, SymmetricMatrix& >
1561 {
1562  matrix_ *= rhs;
1563  return *this;
1564 }
1565 //*************************************************************************************************
1566 
1567 
1568 //*************************************************************************************************
1576 template< typename MT // Type of the adapted sparse matrix
1577  , bool SO > // Storage order of the adapted sparse matrix
1578 template< typename ST > // Data type of the right-hand side scalar
1580  -> EnableIf_t< IsNumeric_v<ST>, SymmetricMatrix& >
1581 {
1582  BLAZE_USER_ASSERT( !isZero( rhs ), "Division by zero detected" );
1583 
1584  matrix_ /= rhs;
1585  return *this;
1586 }
1588 //*************************************************************************************************
1589 
1590 
1591 
1592 
1593 //=================================================================================================
1594 //
1595 // UTILITY FUNCTIONS
1596 //
1597 //=================================================================================================
1598 
1599 //*************************************************************************************************
1605 template< typename MT // Type of the adapted sparse matrix
1606  , bool SO > // Storage order of the adapted sparse matrix
1607 inline size_t SymmetricMatrix<MT,SO,false,true>::rows() const noexcept
1608 {
1609  return matrix_.rows();
1610 }
1612 //*************************************************************************************************
1613 
1614 
1615 //*************************************************************************************************
1621 template< typename MT // Type of the adapted sparse matrix
1622  , bool SO > // Storage order of the adapted sparse matrix
1623 inline size_t SymmetricMatrix<MT,SO,false,true>::columns() const noexcept
1624 {
1625  return matrix_.columns();
1626 }
1628 //*************************************************************************************************
1629 
1630 
1631 //*************************************************************************************************
1637 template< typename MT // Type of the adapted sparse matrix
1638  , bool SO > // Storage order of the adapted sparse matrix
1639 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity() const noexcept
1640 {
1641  return matrix_.capacity();
1642 }
1644 //*************************************************************************************************
1645 
1646 
1647 //*************************************************************************************************
1658 template< typename MT // Type of the adapted sparse matrix
1659  , bool SO > // Storage order of the adapted sparse matrix
1660 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity( size_t i ) const noexcept
1661 {
1662  return matrix_.capacity(i);
1663 }
1665 //*************************************************************************************************
1666 
1667 
1668 //*************************************************************************************************
1674 template< typename MT // Type of the adapted sparse matrix
1675  , bool SO > // Storage order of the adapted sparse matrix
1676 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros() const
1677 {
1678  return matrix_.nonZeros();
1679 }
1681 //*************************************************************************************************
1682 
1683 
1684 //*************************************************************************************************
1696 template< typename MT // Type of the adapted sparse matrix
1697  , bool SO > // Storage order of the adapted sparse matrix
1698 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros( size_t i ) const
1699 {
1700  return matrix_.nonZeros(i);
1701 }
1703 //*************************************************************************************************
1704 
1705 
1706 //*************************************************************************************************
1712 template< typename MT // Type of the adapted sparse matrix
1713  , bool SO > // Storage order of the adapted sparse matrix
1715 {
1716  matrix_.reset();
1717 }
1719 //*************************************************************************************************
1720 
1721 
1722 //*************************************************************************************************
1758 template< typename MT // Type of the adapted sparse matrix
1759  , bool SO > // Storage order of the adapted sparse matrix
1760 inline void SymmetricMatrix<MT,SO,false,true>::reset( size_t i )
1761 {
1762  using blaze::erase;
1763 
1764  for( auto it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1765  {
1766  const size_t j( it->index() );
1767 
1768  if( i == j )
1769  continue;
1770 
1771  if( SO ) {
1772  const Iterator_t<MT> pos( matrix_.find( i, j ) );
1773  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1774  erase( matrix_, j, pos );
1775  }
1776  else {
1777  const Iterator_t<MT> pos( matrix_.find( j, i ) );
1778  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1779  erase( matrix_, j, pos );
1780  }
1781  }
1782 
1783  matrix_.reset( i );
1784 }
1786 //*************************************************************************************************
1787 
1788 
1789 //*************************************************************************************************
1797 template< typename MT // Type of the adapted sparse matrix
1798  , bool SO > // Storage order of the adapted sparse matrix
1800 {
1801  using blaze::clear;
1802 
1803  clear( matrix_ );
1804 }
1806 //*************************************************************************************************
1807 
1808 
1809 //*************************************************************************************************
1824 template< typename MT // Type of the adapted sparse matrix
1825  , bool SO > // Storage order of the adapted sparse matrix
1826 void SymmetricMatrix<MT,SO,false,true>::resize( size_t n, bool preserve )
1827 {
1829 
1830  MAYBE_UNUSED( preserve );
1831 
1832  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1833 
1834  matrix_.resize( n, n, true );
1835 }
1837 //*************************************************************************************************
1838 
1839 
1840 //*************************************************************************************************
1851 template< typename MT // Type of the adapted sparse matrix
1852  , bool SO > // Storage order of the adapted sparse matrix
1853 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t nonzeros )
1854 {
1855  matrix_.reserve( nonzeros );
1856 }
1858 //*************************************************************************************************
1859 
1860 
1861 //*************************************************************************************************
1875 template< typename MT // Type of the adapted sparse matrix
1876  , bool SO > // Storage order of the adapted sparse matrix
1877 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t i, size_t nonzeros )
1878 {
1879  matrix_.reserve( i, nonzeros );
1880 }
1882 //*************************************************************************************************
1883 
1884 
1885 //*************************************************************************************************
1896 template< typename MT // Type of the adapted sparse matrix
1897  , bool SO > // Storage order of the adapted sparse matrix
1898 inline void SymmetricMatrix<MT,SO,false,true>::trim()
1899 {
1900  matrix_.trim();
1901 }
1903 //*************************************************************************************************
1904 
1905 
1906 //*************************************************************************************************
1918 template< typename MT // Type of the adapted sparse matrix
1919  , bool SO > // Storage order of the adapted sparse matrix
1920 inline void SymmetricMatrix<MT,SO,false,true>::trim( size_t i )
1921 {
1922  matrix_.trim( i );
1923 }
1925 //*************************************************************************************************
1926 
1927 
1928 //*************************************************************************************************
1938 template< typename MT // Type of the adapted sparse matrix
1939  , bool SO > // Storage order of the adapted sparse matrix
1941 {
1942  matrix_.shrinkToFit();
1943 }
1945 //*************************************************************************************************
1946 
1947 
1948 //*************************************************************************************************
1955 template< typename MT // Type of the adapted sparse matrix
1956  , bool SO > // Storage order of the adapted sparse matrix
1957 inline void SymmetricMatrix<MT,SO,false,true>::swap( SymmetricMatrix& m ) noexcept
1958 {
1959  using std::swap;
1960 
1961  swap( matrix_, m.matrix_ );
1962 }
1964 //*************************************************************************************************
1965 
1966 
1967 
1968 
1969 //=================================================================================================
1970 //
1971 // INSERTION FUNCTIONS
1972 //
1973 //=================================================================================================
1974 
1975 //*************************************************************************************************
1989 template< typename MT // Type of the adapted sparse matrix
1990  , bool SO > // Storage order of the adapted sparse matrix
1991 inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
1992  SymmetricMatrix<MT,SO,false,true>::set( size_t i, size_t j, const ElementType& value )
1993 {
1994  if( i != j )
1995  matrix_.set( j, i, value );
1996  return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
1997 }
1999 //*************************************************************************************************
2000 
2001 
2002 //*************************************************************************************************
2017 template< typename MT // Type of the adapted sparse matrix
2018  , bool SO > // Storage order of the adapted sparse matrix
2019 inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2020  SymmetricMatrix<MT,SO,false,true>::insert( size_t i, size_t j, const ElementType& value )
2021 {
2022  if( i != j )
2023  matrix_.insert( j, i, value );
2024  return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
2025 }
2027 //*************************************************************************************************
2028 
2029 
2030 //*************************************************************************************************
2085 template< typename MT // Type of the adapted sparse matrix
2086  , bool SO > // Storage order of the adapted sparse matrix
2087 inline void SymmetricMatrix<MT,SO,false,true>::append( size_t i, size_t j, const ElementType& value, bool check )
2088 {
2089  matrix_.append( i, j, value, check );
2090  if( i != j && ( !check || !isDefault<strict>( value ) ) )
2091  matrix_.insert( j, i, value );
2092 }
2094 //*************************************************************************************************
2095 
2096 
2097 //*************************************************************************************************
2111 template< typename MT // Type of the adapted sparse matrix
2112  , bool SO > // Storage order of the adapted sparse matrix
2113 inline void SymmetricMatrix<MT,SO,false,true>::finalize( size_t i )
2114 {
2115  matrix_.trim( i );
2116 }
2118 //*************************************************************************************************
2119 
2120 
2121 
2122 
2123 //=================================================================================================
2124 //
2125 // ERASE FUNCTIONS
2126 //
2127 //=================================================================================================
2128 
2129 //*************************************************************************************************
2139 template< typename MT // Type of the adapted sparse matrix
2140  , bool SO > // Storage order of the adapted sparse matrix
2141 inline void SymmetricMatrix<MT,SO,false,true>::erase( size_t i, size_t j )
2142 {
2143  using blaze::erase;
2144 
2145  erase( matrix_, i, j );
2146  if( i != j )
2147  erase( matrix_, j, i );
2148 }
2150 //*************************************************************************************************
2151 
2152 
2153 //*************************************************************************************************
2165 template< typename MT // Type of the adapted sparse matrix
2166  , bool SO > // Storage order of the adapted sparse matrix
2167 inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2168  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator pos )
2169 {
2170  using blaze::erase;
2171 
2172  const Iterator_t<MT> base( pos.base() );
2173 
2174  if( base == matrix_.end( i ) )
2175  return pos;
2176 
2177  const size_t j( base->index() );
2178 
2179  if( i == j ) {
2180  BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
2181  return Iterator( erase( matrix_, i, base ), matrix_, i );
2182  }
2183 
2184  if( SO ) {
2185  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2186  erase( matrix_, j, matrix_.find( i, j ) );
2187  return Iterator( erase( matrix_, i, base ), matrix_, i );
2188  }
2189  else {
2190  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2191  erase( matrix_, j, matrix_.find( j, i ) );
2192  return Iterator( erase(matrix_, i, base ), matrix_, i );
2193  }
2194 }
2196 //*************************************************************************************************
2197 
2198 
2199 //*************************************************************************************************
2213 template< typename MT // Type of the adapted sparse matrix
2214  , bool SO > // Storage order of the adapted sparse matrix
2215 inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2216  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last )
2217 {
2218  using blaze::erase;
2219 
2220  for( auto it=first.base(); it!=last.base(); ++it )
2221  {
2222  const size_t j( it->index() );
2223 
2224  if( i == j )
2225  continue;
2226 
2227  if( SO ) {
2228  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2229  erase( matrix_, i, j );
2230  }
2231  else {
2232  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2233  erase( matrix_, j, i );
2234  }
2235  }
2236 
2237  return Iterator( erase( matrix_, i, first.base(), last.base() ), matrix_, i );
2238 }
2240 //*************************************************************************************************
2241 
2242 
2243 //*************************************************************************************************
2265 template< typename MT // Type of the adapted sparse matrix
2266  , bool SO > // Storage order of the adapted sparse matrix
2267 template< typename Pred > // Type of the unary predicate
2268 inline void SymmetricMatrix<MT,SO,false,true>::erase( Pred predicate )
2269 {
2270  using blaze::erase;
2271 
2272  erase( matrix_, predicate );
2273 
2274  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2275 }
2277 //*************************************************************************************************
2278 
2279 
2280 //*************************************************************************************************
2308 template< typename MT // Type of the adapted sparse matrix
2309  , bool SO > // Storage order of the adapted sparse matrix
2310 template< typename Pred > // Type of the unary predicate
2311 inline void
2312  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2313 {
2314  using blaze::erase;
2315 
2316  for( auto it=first; it!=last; ++it ) {
2317  const size_t j( it->index() );
2318  if( i != j && predicate( it->value() ) ) {
2319  if( SO )
2320  erase( matrix_, i, j );
2321  else
2322  erase( matrix_, j, i );
2323  }
2324  }
2325 
2326  erase( matrix_, i, first.base(), last.base(), predicate );
2327 
2328  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2329 }
2331 //*************************************************************************************************
2332 
2333 
2334 
2335 
2336 //=================================================================================================
2337 //
2338 // LOOKUP FUNCTIONS
2339 //
2340 //=================================================================================================
2341 
2342 //*************************************************************************************************
2358 template< typename MT // Type of the adapted sparse matrix
2359  , bool SO > // Storage order of the adapted sparse matrix
2360 inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2361  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j )
2362 {
2363  return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2364 }
2366 //*************************************************************************************************
2367 
2368 
2369 //*************************************************************************************************
2385 template< typename MT // Type of the adapted sparse matrix
2386  , bool SO > // Storage order of the adapted sparse matrix
2387 inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
2388  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j ) const
2389 {
2390  return matrix_.find( i, j );
2391 }
2393 //*************************************************************************************************
2394 
2395 
2396 //*************************************************************************************************
2412 template< typename MT // Type of the adapted sparse matrix
2413  , bool SO > // Storage order of the adapted sparse matrix
2414 inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2415  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j )
2416 {
2417  return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2418 }
2420 //*************************************************************************************************
2421 
2422 
2423 //*************************************************************************************************
2439 template< typename MT // Type of the adapted sparse matrix
2440  , bool SO > // Storage order of the adapted sparse matrix
2441 inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
2442  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j ) const
2443 {
2444  return matrix_.lowerBound( i, j );
2445 }
2447 //*************************************************************************************************
2448 
2449 
2450 //*************************************************************************************************
2466 template< typename MT // Type of the adapted sparse matrix
2467  , bool SO > // Storage order of the adapted sparse matrix
2468 inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2469  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j )
2470 {
2471  return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2472 }
2474 //*************************************************************************************************
2475 
2476 
2477 //*************************************************************************************************
2493 template< typename MT // Type of the adapted sparse matrix
2494  , bool SO > // Storage order of the adapted sparse matrix
2495 inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
2496  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j ) const
2497 {
2498  return matrix_.upperBound( i, j );
2499 }
2501 //*************************************************************************************************
2502 
2503 
2504 
2505 
2506 //=================================================================================================
2507 //
2508 // NUMERIC FUNCTIONS
2509 //
2510 //=================================================================================================
2511 
2512 //*************************************************************************************************
2518 template< typename MT // Type of the adapted sparse matrix
2519  , bool SO > // Storage order of the adapted sparse matrix
2520 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::transpose()
2521 {
2522  return *this;
2523 }
2525 //*************************************************************************************************
2526 
2527 
2528 //*************************************************************************************************
2534 template< typename MT // Type of the adapted sparse matrix
2535  , bool SO > // Storage order of the adapted sparse matrix
2536 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::ctranspose()
2537 {
2538  if( !IsBuiltin_v<ElementType> )
2539  conjugate( matrix_ );
2540 
2541  return *this;
2542 }
2544 //*************************************************************************************************
2545 
2546 
2547 //*************************************************************************************************
2565 template< typename MT // Type of the adapted sparse matrix
2566  , bool SO > // Storage order of the adapted sparse matrix
2567 template< typename Other > // Data type of the scalar value
2568 inline SymmetricMatrix<MT,SO,false,true>&
2569  SymmetricMatrix<MT,SO,false,true>::scale( const Other& scalar )
2570 {
2571  matrix_.scale( scalar );
2572  return *this;
2573 }
2575 //*************************************************************************************************
2576 
2577 
2578 
2579 
2580 //=================================================================================================
2581 //
2582 // DEBUGGING FUNCTIONS
2583 //
2584 //=================================================================================================
2585 
2586 //*************************************************************************************************
2596 template< typename MT // Type of the adapted sparse matrix
2597  , bool SO > // Storage order of the adapted sparse matrix
2598 inline bool SymmetricMatrix<MT,SO,false,true>::isIntact() const noexcept
2599 {
2600  using blaze::isIntact;
2601 
2602  return ( isIntact( matrix_ ) && isSymmetric( matrix_ ) );
2603 }
2605 //*************************************************************************************************
2606 
2607 
2608 
2609 
2610 //=================================================================================================
2611 //
2612 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2613 //
2614 //=================================================================================================
2615 
2616 //*************************************************************************************************
2627 template< typename MT // Type of the adapted sparse matrix
2628  , bool SO > // Storage order of the adapted sparse matrix
2629 template< typename Other > // Data type of the foreign expression
2630 inline bool SymmetricMatrix<MT,SO,false,true>::canAlias( const Other* alias ) const noexcept
2631 {
2632  return matrix_.canAlias( alias );
2633 }
2635 //*************************************************************************************************
2636 
2637 
2638 //*************************************************************************************************
2649 template< typename MT // Type of the adapted sparse matrix
2650  , bool SO > // Storage order of the adapted sparse matrix
2651 template< typename Other > // Data type of the foreign expression
2652 inline bool SymmetricMatrix<MT,SO,false,true>::isAliased( const Other* alias ) const noexcept
2653 {
2654  return matrix_.isAliased( alias );
2655 }
2657 //*************************************************************************************************
2658 
2659 
2660 //*************************************************************************************************
2671 template< typename MT // Type of the adapted sparse matrix
2672  , bool SO > // Storage order of the adapted sparse matrix
2673 inline bool SymmetricMatrix<MT,SO,false,true>::canSMPAssign() const noexcept
2674 {
2675  return matrix_.canSMPAssign();
2676 }
2678 //*************************************************************************************************
2679 
2680 } // namespace blaze
2681 
2682 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSFORMATION_TYPE(T)
Constraint on the data type.In case the given data type T is a transformation expression (i....
Definition: Transformation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type,...
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
constexpr ptrdiff_t Size_v
Auxiliary variable template for the Size type trait.The Size_v variable template provides a convenien...
Definition: Size.h:176
Constraint on the data type.
Constraint on the data type.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:750
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.In case the given data type T is not a dense or sparse matrix type and in...
Definition: StorageOrder.h:63
Header file for the isZero shim.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i....
Definition: Computation.h:81
Constraint on the data type.
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
void shrinkToFit(Matrix< MT, SO > &matrix)
Requesting the removal of unused capacity.
Definition: Matrix.h:799
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
Header file for the MAYBE_UNUSED function template.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type,...
Definition: Volatile.h:79
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
Header file for the extended initializer_list functionality.
Constraint on the data type.
Header file for the NumericProxy class.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:482
MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:416
Header file for the implementation of the base template of the SymmetricMatrix.
Constraint on the data type.
Constraint on the data type.
Header file for the SparseMatrix base class.
Header file for utility functions for sparse matrices.
Header file for the IsSquare type trait.
Constraint on the data type.
bool isZero(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 0.
Definition: DiagonalProxy.h:677
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.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the SymmetricElement class.
Compile time assertion.
decltype(auto) operator *(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9091
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
Constraint on the data type.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UPPER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a upper triangular matrix type,...
Definition: Upper.h:81
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:738
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:615
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:558
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type,...
Definition: Symmetric.h:79
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric_v< T >)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Header file for run time assertion macros.
Constraint on the data type.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_LOWER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower triangular matrix type,...
Definition: Lower.h:81
Header file for all forward declarations for expression class templates.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type,...
Definition: Reference.h:79
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:282
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:75
Header file for the SymmetricValue class.
Constraint on the data type.
Constraint on the data type.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:1328
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VIEW_TYPE(T)
Constraint on the data type.In case the given data type T is a view type (i.e. a subvector,...
Definition: View.h:81
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
#define BLAZE_CONSTRAINT_MUST_BE_RESIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not resizable, i.e. does not have a 'res...
Definition: Resizable.h:61
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
auto operator *=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:494
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type,...
Definition: Hermitian.h:79
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:951
Constraint on the data type.
Header file for the Size type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type,...
Definition: SparseMatrix.h:61
Header file for the clear shim.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825