SparseNumeric.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSENUMERIC_H_
36 #define _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSENUMERIC_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <vector>
49 #include <blaze/math/Aliases.h>
58 #include <blaze/math/Exception.h>
61 #include <blaze/math/shims/Clear.h>
70 #include <blaze/util/Assert.h>
76 #include <blaze/util/DisableIf.h>
77 #include <blaze/util/EnableIf.h>
81 #include <blaze/util/Types.h>
82 #include <blaze/util/Unused.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES WITH NUMERIC ELEMENT TYPE
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
101 template< typename MT // Type of the adapted sparse matrix
102  , bool SO > // Storage order of the adapted sparse matrix
103 class SymmetricMatrix<MT,SO,false,true>
104  : public SparseMatrix< SymmetricMatrix<MT,SO,false,true>, SO >
105 {
106  private:
107  //**Type definitions****************************************************************************
108  typedef OppositeType_<MT> OT;
109  typedef TransposeType_<MT> TT;
110  typedef ElementType_<MT> ET;
111  //**********************************************************************************************
112 
113  public:
114  //**Type definitions****************************************************************************
115  typedef SymmetricMatrix<MT,SO,false,true> This;
116  typedef SparseMatrix<This,SO> BaseType;
117  typedef This ResultType;
118  typedef SymmetricMatrix<OT,!SO,false,true> OppositeType;
119  typedef SymmetricMatrix<TT,!SO,false,true> TransposeType;
120  typedef ET ElementType;
121  typedef ReturnType_<MT> ReturnType;
122  typedef const This& CompositeType;
123  typedef NumericProxy<MT> Reference;
124  typedef ConstReference_<MT> ConstReference;
125  typedef ConstIterator_<MT> ConstIterator;
126  //**********************************************************************************************
127 
128  //**Rebind struct definition********************************************************************
131  template< typename ET > // Data type of the other matrix
132  struct Rebind {
134  typedef SymmetricMatrix< typename MT::template Rebind<ET>::Other > Other;
135  };
136  //**********************************************************************************************
137 
138  //**Iterator class definition*******************************************************************
141  class Iterator
142  {
143  public:
144  //**Type definitions*************************************************************************
145  typedef Iterator_<MT> IteratorType;
146 
147  typedef std::forward_iterator_tag IteratorCategory;
148  typedef SymmetricElement<MT> ValueType;
149  typedef ValueType PointerType;
150  typedef ValueType ReferenceType;
151  typedef ptrdiff_t DifferenceType;
152 
153  // STL iterator requirements
154  typedef IteratorCategory iterator_category;
155  typedef ValueType value_type;
156  typedef PointerType pointer;
157  typedef ReferenceType reference;
158  typedef DifferenceType difference_type;
159  //*******************************************************************************************
160 
161  //**Default constructor**********************************************************************
164  inline Iterator()
165  : pos_ () // Iterator to the current sparse symmetric matrix element
166  , matrix_( nullptr ) // The sparse matrix containing the iterator
167  , index_ ( 0UL ) // The row/column index of the iterator
168  {}
169  //*******************************************************************************************
170 
171  //**Constructor******************************************************************************
178  inline Iterator( IteratorType pos, MT& matrix, size_t index )
179  : pos_ ( pos ) // Iterator to the current sparse symmetric matrix element
180  , matrix_( &matrix ) // The sparse matrix containing the iterator
181  , index_ ( index ) // The row/column index of the iterator
182  {}
183  //*******************************************************************************************
184 
185  //**Prefix increment operator****************************************************************
190  inline Iterator& operator++() {
191  ++pos_;
192  return *this;
193  }
194  //*******************************************************************************************
195 
196  //**Postfix increment operator***************************************************************
201  inline const Iterator operator++( int ) {
202  const Iterator tmp( *this );
203  ++(*this);
204  return tmp;
205  }
206  //*******************************************************************************************
207 
208  //**Element access operator******************************************************************
213  inline ReferenceType operator*() const {
214  return ReferenceType( pos_, matrix_, index_ );
215  }
216  //*******************************************************************************************
217 
218  //**Element access operator******************************************************************
223  inline PointerType operator->() const {
224  return PointerType( pos_, matrix_, index_ );
225  }
226  //*******************************************************************************************
227 
228  //**Conversion operator**********************************************************************
233  inline operator ConstIterator() const {
234  return pos_;
235  }
236  //*******************************************************************************************
237 
238  //**Equality operator************************************************************************
244  inline bool operator==( const Iterator& rhs ) const {
245  return pos_ == rhs.pos_;
246  }
247  //*******************************************************************************************
248 
249  //**Inequality operator**********************************************************************
255  inline bool operator!=( const Iterator& rhs ) const {
256  return !( *this == rhs );
257  }
258  //*******************************************************************************************
259 
260  //**Subtraction operator*********************************************************************
266  inline DifferenceType operator-( const Iterator& rhs ) const {
267  return pos_ - rhs.pos_;
268  }
269  //*******************************************************************************************
270 
271  //**Base function****************************************************************************
276  inline IteratorType base() const {
277  return pos_;
278  }
279  //*******************************************************************************************
280 
281  private:
282  //**Member variables*************************************************************************
283  IteratorType pos_;
284  MT* matrix_;
285  size_t index_;
286  //*******************************************************************************************
287  };
288  //**********************************************************************************************
289 
290  //**Compilation flags***************************************************************************
292  enum : bool { smpAssignable = false };
293  //**********************************************************************************************
294 
295  //**Constructors********************************************************************************
298  explicit inline SymmetricMatrix();
299  explicit inline SymmetricMatrix( size_t n );
300  explicit inline SymmetricMatrix( size_t n, size_t nonzeros );
301  explicit inline SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros );
302 
303  inline SymmetricMatrix( const SymmetricMatrix& m );
304  inline SymmetricMatrix( SymmetricMatrix&& m ) noexcept;
305 
306  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
307  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
309  //**********************************************************************************************
310 
311  //**Destructor**********************************************************************************
312  // No explicitly declared destructor.
313  //**********************************************************************************************
314 
315  //**Data access functions***********************************************************************
318  inline Reference operator()( size_t i, size_t j );
319  inline ConstReference operator()( size_t i, size_t j ) const;
320  inline Reference at( size_t i, size_t j );
321  inline ConstReference at( size_t i, size_t j ) const;
322  inline Iterator begin ( size_t i );
323  inline ConstIterator begin ( size_t i ) const;
324  inline ConstIterator cbegin( size_t i ) const;
325  inline Iterator end ( size_t i );
326  inline ConstIterator end ( size_t i ) const;
327  inline ConstIterator cend ( size_t i ) const;
329  //**********************************************************************************************
330 
331  //**Assignment operators************************************************************************
334  inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
335  inline SymmetricMatrix& operator=( SymmetricMatrix&& rhs ) noexcept;
336 
337  template< typename MT2 >
338  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator=( const Matrix<MT2,SO>& rhs );
339 
340  template< typename MT2 >
341  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator=( const Matrix<MT2,SO>& rhs );
342 
343  template< typename MT2 >
344  inline SymmetricMatrix& operator=( const Matrix<MT2,!SO>& rhs );
345 
346  template< typename MT2 >
347  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator+=( const Matrix<MT2,SO>& rhs );
348 
349  template< typename MT2 >
350  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator+=( const Matrix<MT2,SO>& rhs );
351 
352  template< typename MT2 >
353  inline SymmetricMatrix& operator+=( const Matrix<MT2,!SO>& rhs );
354 
355  template< typename MT2 >
356  inline DisableIf_< IsComputation<MT2>, SymmetricMatrix& > operator-=( const Matrix<MT2,SO>& rhs );
357 
358  template< typename MT2 >
359  inline EnableIf_< IsComputation<MT2>, SymmetricMatrix& > operator-=( const Matrix<MT2,SO>& rhs );
360 
361  template< typename MT2 >
362  inline SymmetricMatrix& operator-=( const Matrix<MT2,!SO>& rhs );
363 
364  template< typename MT2, bool SO2 >
365  inline SymmetricMatrix& operator*=( const Matrix<MT2,SO2>& rhs );
366 
367  template< typename Other >
368  inline EnableIf_< IsNumeric<Other>, SymmetricMatrix >& operator*=( Other rhs );
369 
370  template< typename Other >
371  inline EnableIf_< IsNumeric<Other>, SymmetricMatrix >& operator/=( Other rhs );
373  //**********************************************************************************************
374 
375  //**Utility functions***************************************************************************
378  inline size_t rows() const noexcept;
379  inline size_t columns() const noexcept;
380  inline size_t capacity() const noexcept;
381  inline size_t capacity( size_t i ) const noexcept;
382  inline size_t nonZeros() const;
383  inline size_t nonZeros( size_t i ) const;
384  inline void reset();
385  inline void reset( size_t i );
386  inline void clear();
387  inline Iterator set( size_t i, size_t j, const ElementType& value );
388  inline Iterator insert( size_t i, size_t j, const ElementType& value );
389  inline void erase( size_t i, size_t j );
390  inline Iterator erase( size_t i, Iterator pos );
391  inline Iterator erase( size_t i, Iterator first, Iterator last );
392  inline void resize ( size_t n, bool preserve=true );
393  inline void reserve( size_t nonzeros );
394  inline void reserve( size_t i, size_t nonzeros );
395  inline void trim();
396  inline void trim( size_t i );
397  inline SymmetricMatrix& transpose();
398  inline SymmetricMatrix& ctranspose();
399  template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
400  template< typename Other > inline SymmetricMatrix& scaleDiagonal( Other scale );
401  inline void swap( SymmetricMatrix& m ) noexcept;
403  //**********************************************************************************************
404 
405  //**Lookup functions****************************************************************************
408  inline Iterator find ( size_t i, size_t j );
409  inline ConstIterator find ( size_t i, size_t j ) const;
410  inline Iterator lowerBound( size_t i, size_t j );
411  inline ConstIterator lowerBound( size_t i, size_t j ) const;
412  inline Iterator upperBound( size_t i, size_t j );
413  inline ConstIterator upperBound( size_t i, size_t j ) const;
415  //**********************************************************************************************
416 
417  //**Low-level utility functions*****************************************************************
420  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
421  inline void finalize( size_t i );
423  //**********************************************************************************************
424 
425  //**Debugging functions*************************************************************************
428  inline bool isIntact() const noexcept;
430  //**********************************************************************************************
431 
432  //**Expression template evaluation functions****************************************************
435  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
436  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
437 
438  inline bool canSMPAssign() const noexcept;
440  //**********************************************************************************************
441 
442  private:
443  //**Member variables****************************************************************************
446  MT matrix_;
447 
448  //**********************************************************************************************
449 
450  //**Friend declarations*************************************************************************
451  template< typename MT2, bool SO2, bool DF2, bool NF2 >
452  friend bool isDefault( const SymmetricMatrix<MT2,SO2,DF2,NF2>& m );
453  //**********************************************************************************************
454 
455  //**Compile time checks*************************************************************************
469  BLAZE_STATIC_ASSERT( Rows<MT>::value == Columns<MT>::value );
470  //**********************************************************************************************
471 };
473 //*************************************************************************************************
474 
475 
476 
477 
478 //=================================================================================================
479 //
480 // CONSTRUCTORS
481 //
482 //=================================================================================================
483 
484 //*************************************************************************************************
488 template< typename MT // Type of the adapted sparse matrix
489  , bool SO > // Storage order of the adapted sparse matrix
490 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix()
491  : matrix_() // The adapted sparse matrix
492 {
493  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
494 }
496 //*************************************************************************************************
497 
498 
499 //*************************************************************************************************
507 template< typename MT // Type of the adapted sparse matrix
508  , bool SO > // Storage order of the adapted sparse matrix
509 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n )
510  : matrix_( n, n ) // The adapted sparse matrix
511 {
513 
514  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
515 }
517 //*************************************************************************************************
518 
519 
520 //*************************************************************************************************
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( size_t n, size_t nonzeros )
532  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
533 {
535 
536  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
537 }
539 //*************************************************************************************************
540 
541 
542 //*************************************************************************************************
553 template< typename MT // Type of the adapted sparse matrix
554  , bool SO > // Storage order of the adapted sparse matrix
555 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
556  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
557 {
559 
560  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
561 }
563 //*************************************************************************************************
564 
565 
566 //*************************************************************************************************
572 template< typename MT // Type of the adapted sparse matrix
573  , bool SO > // Storage order of the adapted sparse matrix
574 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const SymmetricMatrix& m )
575  : matrix_( m.matrix_ ) // The adapted sparse matrix
576 {
577  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
578  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
579 }
581 //*************************************************************************************************
582 
583 
584 //*************************************************************************************************
590 template< typename MT // Type of the adapted sparse matrix
591  , bool SO > // Storage order of the adapted sparse matrix
592 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( SymmetricMatrix&& m ) noexcept
593  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
594 {
595  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
596  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
597 }
599 //*************************************************************************************************
600 
601 
602 //*************************************************************************************************
612 template< typename MT // Type of the adapted sparse matrix
613  , bool SO > // Storage order of the adapted sparse matrix
614 template< typename MT2 > // Type of the foreign matrix
615 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,SO>& m )
616  : matrix_( ~m ) // The adapted sparse matrix
617 {
618  if( !IsSymmetric<MT2>::value && !isSymmetric( matrix_ ) ) {
619  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
620  }
621 
622  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
623  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
624 }
626 //*************************************************************************************************
627 
628 
629 //*************************************************************************************************
639 template< typename MT // Type of the adapted sparse matrix
640  , bool SO > // Storage order of the adapted sparse matrix
641 template< typename MT2 > // Type of the foreign matrix
642 inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
643  : matrix_( trans( ~m ) ) // The adapted sparse matrix
644 {
645  if( !IsSymmetric<MT2>::value && !isSymmetric( matrix_ ) ) {
646  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
647  }
648 
649  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
650  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
651 }
653 //*************************************************************************************************
654 
655 
656 
657 
658 //=================================================================================================
659 //
660 // DATA ACCESS FUNCTIONS
661 //
662 //=================================================================================================
663 
664 //*************************************************************************************************
679 template< typename MT // Type of the adapted sparse matrix
680  , bool SO > // Storage order of the adapted sparse matrix
682  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j )
683 {
684  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
685  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
686 
687  return Reference( matrix_, i, j );
688 }
690 //*************************************************************************************************
691 
692 
693 //*************************************************************************************************
708 template< typename MT // Type of the adapted sparse matrix
709  , bool SO > // Storage order of the adapted sparse matrix
711  SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j ) const
712 {
713  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
714  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
715 
716  return matrix_(i,j);
717 }
719 //*************************************************************************************************
720 
721 
722 //*************************************************************************************************
738 template< typename MT // Type of the adapted dense matrix
739  , bool SO > // Storage order of the adapted dense matrix
741  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j )
742 {
743  if( i >= rows() ) {
744  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
745  }
746  if( j >= columns() ) {
747  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
748  }
749  return (*this)(i,j);
750 }
752 //*************************************************************************************************
753 
754 
755 //*************************************************************************************************
771 template< typename MT // Type of the adapted dense matrix
772  , bool SO > // Storage order of the adapted dense matrix
774  SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j ) const
775 {
776  if( i >= rows() ) {
777  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
778  }
779  if( j >= columns() ) {
780  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
781  }
782  return (*this)(i,j);
783 }
785 //*************************************************************************************************
786 
787 
788 //*************************************************************************************************
800 template< typename MT // Type of the adapted sparse matrix
801  , bool SO > // Storage order of the adapted sparse matrix
804 {
805  return Iterator( matrix_.begin(i), matrix_, i );
806 }
808 //*************************************************************************************************
809 
810 
811 //*************************************************************************************************
823 template< typename MT // Type of the adapted sparse matrix
824  , bool SO > // Storage order of the adapted sparse matrix
827 {
828  return matrix_.begin(i);
829 }
831 //*************************************************************************************************
832 
833 
834 //*************************************************************************************************
846 template< typename MT // Type of the adapted sparse matrix
847  , bool SO > // Storage order of the adapted sparse matrix
850 {
851  return matrix_.cbegin(i);
852 }
854 //*************************************************************************************************
855 
856 
857 //*************************************************************************************************
869 template< typename MT // Type of the adapted sparse matrix
870  , bool SO > // Storage order of the adapted sparse matrix
873 {
874  return Iterator( matrix_.end(i), matrix_, i );
875 }
877 //*************************************************************************************************
878 
879 
880 //*************************************************************************************************
892 template< typename MT // Type of the adapted sparse matrix
893  , bool SO > // Storage order of the adapted sparse matrix
896 {
897  return matrix_.end(i);
898 }
900 //*************************************************************************************************
901 
902 
903 //*************************************************************************************************
915 template< typename MT // Type of the adapted sparse matrix
916  , bool SO > // Storage order of the adapted sparse matrix
919 {
920  return matrix_.cend(i);
921 }
923 //*************************************************************************************************
924 
925 
926 
927 
928 //=================================================================================================
929 //
930 // ASSIGNMENT OPERATORS
931 //
932 //=================================================================================================
933 
934 //*************************************************************************************************
944 template< typename MT // Type of the adapted sparse matrix
945  , bool SO > // Storage order of the adapted sparse matrix
946 inline SymmetricMatrix<MT,SO,false,true>&
947  SymmetricMatrix<MT,SO,false,true>::operator=( const SymmetricMatrix& rhs )
948 {
949  matrix_ = rhs.matrix_;
950 
951  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
952  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
953 
954  return *this;
955 }
957 //*************************************************************************************************
958 
959 
960 //*************************************************************************************************
967 template< typename MT // Type of the adapted sparse matrix
968  , bool SO > // Storage order of the adapted sparse matrix
969 inline SymmetricMatrix<MT,SO,false,true>&
970  SymmetricMatrix<MT,SO,false,true>::operator=( SymmetricMatrix&& rhs ) noexcept
971 {
972  matrix_ = std::move( rhs.matrix_ );
973 
974  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
975  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
976 
977  return *this;
978 }
980 //*************************************************************************************************
981 
982 
983 //*************************************************************************************************
996 template< typename MT // Type of the adapted sparse matrix
997  , bool SO > // Storage order of the adapted sparse matrix
998 template< typename MT2 > // Type of the right-hand side matrix
999 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1000  SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1001 {
1002  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1003  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1004  }
1005 
1006  matrix_ = ~rhs;
1007 
1008  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1009  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1010 
1011  return *this;
1012 }
1014 //*************************************************************************************************
1015 
1016 
1017 //*************************************************************************************************
1030 template< typename MT // Type of the adapted sparse matrix
1031  , bool SO > // Storage order of the adapted sparse matrix
1032 template< typename MT2 > // Type of the right-hand side matrix
1033 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1034  SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1035 {
1036  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1037  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1038  }
1039 
1040  if( IsSymmetric<MT2>::value ) {
1041  matrix_ = ~rhs;
1042  }
1043  else {
1044  MT tmp( ~rhs );
1045 
1046  if( !isSymmetric( tmp ) ) {
1047  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1048  }
1049 
1050  matrix_ = std::move( tmp );
1051  }
1052 
1053  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1054  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1055 
1056  return *this;
1057 }
1059 //*************************************************************************************************
1060 
1061 
1062 //*************************************************************************************************
1075 template< typename MT // Type of the adapted sparse matrix
1076  , bool SO > // Storage order of the adapted sparse matrix
1077 template< typename MT2 > // Type of the right-hand side matrix
1078 inline SymmetricMatrix<MT,SO,false,true>&
1079  SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,!SO>& rhs )
1080 {
1081  return this->operator=( trans( ~rhs ) );
1082 }
1084 //*************************************************************************************************
1085 
1086 
1087 //*************************************************************************************************
1100 template< typename MT // Type of the adapted sparse matrix
1101  , bool SO > // Storage order of the adapted sparse matrix
1102 template< typename MT2 > // Type of the right-hand side matrix
1103 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1104  SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1105 {
1106  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1107  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1108  }
1109 
1110  matrix_ += ~rhs;
1111 
1112  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1113  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1114 
1115  return *this;
1116 }
1118 //*************************************************************************************************
1119 
1120 
1121 //*************************************************************************************************
1134 template< typename MT // Type of the adapted sparse matrix
1135  , bool SO > // Storage order of the adapted sparse matrix
1136 template< typename MT2 > // Type of the right-hand side matrix
1137 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1138  SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1139 {
1140  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1141  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1142  }
1143 
1144  if( IsSymmetric<MT2>::value ) {
1145  matrix_ += ~rhs;
1146  }
1147  else {
1148  const ResultType_<MT2> tmp( ~rhs );
1149 
1150  if( !isSymmetric( tmp ) ) {
1151  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1152  }
1153 
1154  matrix_ += tmp;
1155  }
1156 
1157  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1158  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1159 
1160  return *this;
1161 }
1163 //*************************************************************************************************
1164 
1165 
1166 //*************************************************************************************************
1180 template< typename MT // Type of the adapted sparse matrix
1181  , bool SO > // Storage order of the adapted sparse matrix
1182 template< typename MT2 > // Type of the right-hand side matrix
1183 inline SymmetricMatrix<MT,SO,false,true>&
1184  SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,!SO>& rhs )
1185 {
1186  return this->operator+=( trans( ~rhs ) );
1187 }
1189 //*************************************************************************************************
1190 
1191 
1192 //*************************************************************************************************
1205 template< typename MT // Type of the adapted sparse matrix
1206  , bool SO > // Storage order of the adapted sparse matrix
1207 template< typename MT2 > // Type of the right-hand side matrix
1208 inline DisableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1209  SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1210 {
1211  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1212  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1213  }
1214 
1215  matrix_ -= ~rhs;
1216 
1217  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1218  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1219 
1220  return *this;
1221 }
1223 //*************************************************************************************************
1224 
1225 
1226 //*************************************************************************************************
1239 template< typename MT // Type of the adapted sparse matrix
1240  , bool SO > // Storage order of the adapted sparse matrix
1241 template< typename MT2 > // Type of the right-hand side matrix
1242 inline EnableIf_< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,true>& >
1243  SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1244 {
1245  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1246  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1247  }
1248 
1249  if( IsSymmetric<MT2>::value ) {
1250  matrix_ -= ~rhs;
1251  }
1252  else {
1253  const ResultType_<MT2> tmp( ~rhs );
1254 
1255  if( !isSymmetric( tmp ) ) {
1256  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1257  }
1258 
1259  matrix_ -= tmp;
1260  }
1261 
1262  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1263  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1264 
1265  return *this;
1266 }
1268 //*************************************************************************************************
1269 
1270 
1271 //*************************************************************************************************
1285 template< typename MT // Type of the adapted sparse matrix
1286  , bool SO > // Storage order of the adapted sparse matrix
1287 template< typename MT2 > // Type of the right-hand side matrix
1288 inline SymmetricMatrix<MT,SO,false,true>&
1289  SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,!SO>& rhs )
1290 {
1291  return this->operator-=( trans( ~rhs ) );
1292 }
1294 //*************************************************************************************************
1295 
1296 
1297 //*************************************************************************************************
1309 template< typename MT // Type of the adapted sparse matrix
1310  , bool SO > // Storage order of the adapted sparse matrix
1311 template< typename MT2 // Type of the right-hand side matrix
1312  , bool SO2 > // Storage order of the right-hand side matrix
1313 inline SymmetricMatrix<MT,SO,false,true>&
1314  SymmetricMatrix<MT,SO,false,true>::operator*=( const Matrix<MT2,SO2>& rhs )
1315 {
1316  if( matrix_.rows() != (~rhs).columns() ) {
1317  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1318  }
1319 
1320  MT tmp( matrix_ * ~rhs );
1321 
1322  if( !isSymmetric( tmp ) ) {
1323  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1324  }
1325 
1326  matrix_ = std::move( tmp );
1327 
1328  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1329  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1330 
1331  return *this;
1332 }
1334 //*************************************************************************************************
1335 
1336 
1337 //*************************************************************************************************
1345 template< typename MT // Type of the adapted sparse matrix
1346  , bool SO > // Storage order of the adapted sparse matrix
1347 template< typename Other > // Data type of the right-hand side scalar
1348 inline EnableIf_< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,true> >&
1350 {
1351  matrix_ *= rhs;
1352  return *this;
1353 }
1354 //*************************************************************************************************
1355 
1356 
1357 //*************************************************************************************************
1365 template< typename MT // Type of the adapted sparse matrix
1366  , bool SO > // Storage order of the adapted sparse matrix
1367 template< typename Other > // Data type of the right-hand side scalar
1368 inline EnableIf_< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,true> >&
1370 {
1371  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1372 
1373  matrix_ /= rhs;
1374  return *this;
1375 }
1377 //*************************************************************************************************
1378 
1379 
1380 
1381 
1382 //=================================================================================================
1383 //
1384 // UTILITY FUNCTIONS
1385 //
1386 //=================================================================================================
1387 
1388 //*************************************************************************************************
1394 template< typename MT // Type of the adapted sparse matrix
1395  , bool SO > // Storage order of the adapted sparse matrix
1396 inline size_t SymmetricMatrix<MT,SO,false,true>::rows() const noexcept
1397 {
1398  return matrix_.rows();
1399 }
1401 //*************************************************************************************************
1402 
1403 
1404 //*************************************************************************************************
1410 template< typename MT // Type of the adapted sparse matrix
1411  , bool SO > // Storage order of the adapted sparse matrix
1412 inline size_t SymmetricMatrix<MT,SO,false,true>::columns() const noexcept
1413 {
1414  return matrix_.columns();
1415 }
1417 //*************************************************************************************************
1418 
1419 
1420 //*************************************************************************************************
1426 template< typename MT // Type of the adapted sparse matrix
1427  , bool SO > // Storage order of the adapted sparse matrix
1428 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity() const noexcept
1429 {
1430  return matrix_.capacity();
1431 }
1433 //*************************************************************************************************
1434 
1435 
1436 //*************************************************************************************************
1447 template< typename MT // Type of the adapted sparse matrix
1448  , bool SO > // Storage order of the adapted sparse matrix
1449 inline size_t SymmetricMatrix<MT,SO,false,true>::capacity( size_t i ) const noexcept
1450 {
1451  return matrix_.capacity(i);
1452 }
1454 //*************************************************************************************************
1455 
1456 
1457 //*************************************************************************************************
1463 template< typename MT // Type of the adapted sparse matrix
1464  , bool SO > // Storage order of the adapted sparse matrix
1465 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros() const
1466 {
1467  return matrix_.nonZeros();
1468 }
1470 //*************************************************************************************************
1471 
1472 
1473 //*************************************************************************************************
1485 template< typename MT // Type of the adapted sparse matrix
1486  , bool SO > // Storage order of the adapted sparse matrix
1487 inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros( size_t i ) const
1488 {
1489  return matrix_.nonZeros(i);
1490 }
1492 //*************************************************************************************************
1493 
1494 
1495 //*************************************************************************************************
1501 template< typename MT // Type of the adapted sparse matrix
1502  , bool SO > // Storage order of the adapted sparse matrix
1504 {
1505  matrix_.reset();
1506 }
1508 //*************************************************************************************************
1509 
1510 
1511 //*************************************************************************************************
1547 template< typename MT // Type of the adapted sparse matrix
1548  , bool SO > // Storage order of the adapted sparse matrix
1549 inline void SymmetricMatrix<MT,SO,false,true>::reset( size_t i )
1550 {
1551  for( Iterator_<MT> it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1552  {
1553  const size_t j( it->index() );
1554 
1555  if( i == j )
1556  continue;
1557 
1558  if( SO ) {
1559  const Iterator_<MT> pos( matrix_.find( i, j ) );
1560  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1561  matrix_.erase( j, pos );
1562  }
1563  else {
1564  const Iterator_<MT> pos( matrix_.find( j, i ) );
1565  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1566  matrix_.erase( j, pos );
1567  }
1568  }
1569 
1570  matrix_.reset( i );
1571 }
1573 //*************************************************************************************************
1574 
1575 
1576 //*************************************************************************************************
1584 template< typename MT // Type of the adapted sparse matrix
1585  , bool SO > // Storage order of the adapted sparse matrix
1587 {
1588  using blaze::clear;
1589 
1590  clear( matrix_ );
1591 }
1593 //*************************************************************************************************
1594 
1595 
1596 //*************************************************************************************************
1610 template< typename MT // Type of the adapted sparse matrix
1611  , bool SO > // Storage order of the adapted sparse matrix
1613  SymmetricMatrix<MT,SO,false,true>::set( size_t i, size_t j, const ElementType& value )
1614 {
1615  if( i != j )
1616  matrix_.set( j, i, value );
1617  return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
1618 }
1620 //*************************************************************************************************
1621 
1622 
1623 //*************************************************************************************************
1638 template< typename MT // Type of the adapted sparse matrix
1639  , bool SO > // Storage order of the adapted sparse matrix
1641  SymmetricMatrix<MT,SO,false,true>::insert( size_t i, size_t j, const ElementType& value )
1642 {
1643  if( i != j )
1644  matrix_.insert( j, i, value );
1645  return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
1646 }
1648 //*************************************************************************************************
1649 
1650 
1651 //*************************************************************************************************
1661 template< typename MT // Type of the adapted sparse matrix
1662  , bool SO > // Storage order of the adapted sparse matrix
1663 inline void SymmetricMatrix<MT,SO,false,true>::erase( size_t i, size_t j )
1664 {
1665  matrix_.erase( i, j );
1666  if( i != j )
1667  matrix_.erase( j, i );
1668 }
1670 //*************************************************************************************************
1671 
1672 
1673 //*************************************************************************************************
1685 template< typename MT // Type of the adapted sparse matrix
1686  , bool SO > // Storage order of the adapted sparse matrix
1688  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator pos )
1689 {
1690  const Iterator_<MT> base( pos.base() );
1691 
1692  if( base == matrix_.end( i ) )
1693  return pos;
1694 
1695  const size_t j( base->index() );
1696 
1697  if( i == j ) {
1698  BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
1699  return Iterator( matrix_.erase( i, base ), matrix_, i );
1700  }
1701 
1702  if( SO ) {
1703  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1704  matrix_.erase( j, matrix_.find( i, j ) );
1705  return Iterator( matrix_.erase( i, base ), matrix_, i );
1706  }
1707  else {
1708  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1709  matrix_.erase( j, matrix_.find( j, i ) );
1710  return Iterator( matrix_.erase( i, base ), matrix_, i );
1711  }
1712 }
1714 //*************************************************************************************************
1715 
1716 
1717 //*************************************************************************************************
1731 template< typename MT // Type of the adapted sparse matrix
1732  , bool SO > // Storage order of the adapted sparse matrix
1734  SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last )
1735 {
1736  for( Iterator_<MT> it=first.base(); it!=last.base(); ++it )
1737  {
1738  const size_t j( it->index() );
1739 
1740  if( i == j )
1741  continue;
1742 
1743  if( SO ) {
1744  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1745  matrix_.erase( i, j );
1746  }
1747  else {
1748  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1749  matrix_.erase( j, i );
1750  }
1751  }
1752 
1753  return Iterator( matrix_.erase( i, first.base(), last.base() ), matrix_, i );
1754 }
1756 //*************************************************************************************************
1757 
1758 
1759 //*************************************************************************************************
1774 template< typename MT // Type of the adapted sparse matrix
1775  , bool SO > // Storage order of the adapted sparse matrix
1776 void SymmetricMatrix<MT,SO,false,true>::resize( size_t n, bool preserve )
1777 {
1779 
1780  UNUSED_PARAMETER( preserve );
1781 
1782  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1783 
1784  matrix_.resize( n, n, true );
1785 }
1787 //*************************************************************************************************
1788 
1789 
1790 //*************************************************************************************************
1801 template< typename MT // Type of the adapted sparse matrix
1802  , bool SO > // Storage order of the adapted sparse matrix
1803 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t nonzeros )
1804 {
1805  matrix_.reserve( nonzeros );
1806 }
1808 //*************************************************************************************************
1809 
1810 
1811 //*************************************************************************************************
1825 template< typename MT // Type of the adapted sparse matrix
1826  , bool SO > // Storage order of the adapted sparse matrix
1827 inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t i, size_t nonzeros )
1828 {
1829  matrix_.reserve( i, nonzeros );
1830 }
1832 //*************************************************************************************************
1833 
1834 
1835 //*************************************************************************************************
1846 template< typename MT // Type of the adapted sparse matrix
1847  , bool SO > // Storage order of the adapted sparse matrix
1848 inline void SymmetricMatrix<MT,SO,false,true>::trim()
1849 {
1850  matrix_.trim();
1851 }
1853 //*************************************************************************************************
1854 
1855 
1856 //*************************************************************************************************
1868 template< typename MT // Type of the adapted sparse matrix
1869  , bool SO > // Storage order of the adapted sparse matrix
1870 inline void SymmetricMatrix<MT,SO,false,true>::trim( size_t i )
1871 {
1872  matrix_.trim( i );
1873 }
1875 //*************************************************************************************************
1876 
1877 
1878 //*************************************************************************************************
1884 template< typename MT // Type of the adapted sparse matrix
1885  , bool SO > // Storage order of the adapted sparse matrix
1886 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::transpose()
1887 {
1888  return *this;
1889 }
1891 //*************************************************************************************************
1892 
1893 
1894 //*************************************************************************************************
1900 template< typename MT // Type of the adapted sparse matrix
1901  , bool SO > // Storage order of the adapted sparse matrix
1902 inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::ctranspose()
1903 {
1904  if( !IsBuiltin<ElementType>::value )
1905  conjugate( matrix_ );
1906 
1907  return *this;
1908 }
1910 //*************************************************************************************************
1911 
1912 
1913 //*************************************************************************************************
1920 template< typename MT // Type of the adapted sparse matrix
1921  , bool SO > // Storage order of the adapted sparse matrix
1922 template< typename Other > // Data type of the scalar value
1923 inline SymmetricMatrix<MT,SO,false,true>&
1924  SymmetricMatrix<MT,SO,false,true>::scale( const Other& scalar )
1925 {
1926  matrix_.scale( scalar );
1927  return *this;
1928 }
1930 //*************************************************************************************************
1931 
1932 
1933 //*************************************************************************************************
1940 template< typename MT // Type of the adapted sparse matrix
1941  , bool SO > // Storage order of the adapted sparse matrix
1942 template< typename Other > // Data type of the scalar value
1943 inline SymmetricMatrix<MT,SO,false,true>&
1944  SymmetricMatrix<MT,SO,false,true>::scaleDiagonal( Other scalar )
1945 {
1946  matrix_.scaleDiagonal( scalar );
1947  return *this;
1948 }
1950 //*************************************************************************************************
1951 
1952 
1953 //*************************************************************************************************
1960 template< typename MT // Type of the adapted sparse matrix
1961  , bool SO > // Storage order of the adapted sparse matrix
1962 inline void SymmetricMatrix<MT,SO,false,true>::swap( SymmetricMatrix& m ) noexcept
1963 {
1964  using std::swap;
1965 
1966  swap( matrix_, m.matrix_ );
1967 }
1969 //*************************************************************************************************
1970 
1971 
1972 
1973 
1974 //=================================================================================================
1975 //
1976 // LOOKUP FUNCTIONS
1977 //
1978 //=================================================================================================
1979 
1980 //*************************************************************************************************
1996 template< typename MT // Type of the adapted sparse matrix
1997  , bool SO > // Storage order of the adapted sparse matrix
1999  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j )
2000 {
2001  return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2002 }
2004 //*************************************************************************************************
2005 
2006 
2007 //*************************************************************************************************
2023 template< typename MT // Type of the adapted sparse matrix
2024  , bool SO > // Storage order of the adapted sparse matrix
2026  SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j ) const
2027 {
2028  return matrix_.find( i, j );
2029 }
2031 //*************************************************************************************************
2032 
2033 
2034 //*************************************************************************************************
2050 template< typename MT // Type of the adapted sparse matrix
2051  , bool SO > // Storage order of the adapted sparse matrix
2053  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j )
2054 {
2055  return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2056 }
2058 //*************************************************************************************************
2059 
2060 
2061 //*************************************************************************************************
2077 template< typename MT // Type of the adapted sparse matrix
2078  , bool SO > // Storage order of the adapted sparse matrix
2080  SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j ) const
2081 {
2082  return matrix_.lowerBound( i, j );
2083 }
2085 //*************************************************************************************************
2086 
2087 
2088 //*************************************************************************************************
2104 template< typename MT // Type of the adapted sparse matrix
2105  , bool SO > // Storage order of the adapted sparse matrix
2107  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j )
2108 {
2109  return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2110 }
2112 //*************************************************************************************************
2113 
2114 
2115 //*************************************************************************************************
2131 template< typename MT // Type of the adapted sparse matrix
2132  , bool SO > // Storage order of the adapted sparse matrix
2134  SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j ) const
2135 {
2136  return matrix_.upperBound( i, j );
2137 }
2139 //*************************************************************************************************
2140 
2141 
2142 
2143 
2144 //=================================================================================================
2145 //
2146 // LOW-LEVEL UTILITY FUNCTIONS
2147 //
2148 //=================================================================================================
2149 
2150 //*************************************************************************************************
2205 template< typename MT // Type of the adapted sparse matrix
2206  , bool SO > // Storage order of the adapted sparse matrix
2207 inline void SymmetricMatrix<MT,SO,false,true>::append( size_t i, size_t j, const ElementType& value, bool check )
2208 {
2209  matrix_.append( i, j, value, check );
2210  if( i != j && ( !check || !isDefault( value ) ) )
2211  matrix_.insert( j, i, value );
2212 }
2214 //*************************************************************************************************
2215 
2216 
2217 //*************************************************************************************************
2231 template< typename MT // Type of the adapted sparse matrix
2232  , bool SO > // Storage order of the adapted sparse matrix
2233 inline void SymmetricMatrix<MT,SO,false,true>::finalize( size_t i )
2234 {
2235  matrix_.trim( i );
2236 }
2238 //*************************************************************************************************
2239 
2240 
2241 
2242 
2243 //=================================================================================================
2244 //
2245 // DEBUGGING FUNCTIONS
2246 //
2247 //=================================================================================================
2248 
2249 //*************************************************************************************************
2259 template< typename MT // Type of the adapted sparse matrix
2260  , bool SO > // Storage order of the adapted sparse matrix
2261 inline bool SymmetricMatrix<MT,SO,false,true>::isIntact() const noexcept
2262 {
2263  using blaze::isIntact;
2264 
2265  return ( isIntact( matrix_ ) && isSymmetric( matrix_ ) );
2266 }
2268 //*************************************************************************************************
2269 
2270 
2271 
2272 
2273 //=================================================================================================
2274 //
2275 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2276 //
2277 //=================================================================================================
2278 
2279 //*************************************************************************************************
2290 template< typename MT // Type of the adapted sparse matrix
2291  , bool SO > // Storage order of the adapted sparse matrix
2292 template< typename Other > // Data type of the foreign expression
2293 inline bool SymmetricMatrix<MT,SO,false,true>::canAlias( const Other* alias ) const noexcept
2294 {
2295  return matrix_.canAlias( alias );
2296 }
2298 //*************************************************************************************************
2299 
2300 
2301 //*************************************************************************************************
2312 template< typename MT // Type of the adapted sparse matrix
2313  , bool SO > // Storage order of the adapted sparse matrix
2314 template< typename Other > // Data type of the foreign expression
2315 inline bool SymmetricMatrix<MT,SO,false,true>::isAliased( const Other* alias ) const noexcept
2316 {
2317  return matrix_.isAliased( alias );
2318 }
2320 //*************************************************************************************************
2321 
2322 
2323 //*************************************************************************************************
2334 template< typename MT // Type of the adapted sparse matrix
2335  , bool SO > // Storage order of the adapted sparse matrix
2336 inline bool SymmetricMatrix<MT,SO,false,true>::canSMPAssign() const noexcept
2337 {
2338  return matrix_.canSMPAssign();
2339 }
2341 //*************************************************************************************************
2342 
2343 } // namespace blaze
2344 
2345 #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.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7800
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:346
Header file for basic type definitions.
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.In case the given data type T is not a dense or sparse matrix type and in...
Definition: StorageOrder.h:63
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
Constraint on the data type.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:689
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:188
Constraint on the data type.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2643
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:5077
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:590
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2636
#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:384
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:731
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
Constraint on the data type.
STL namespace.
Header file for the NumericProxy class.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2639
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:298
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:232
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
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 isDefault(const CompressedMatrix< Type, SO > &m)
Returns whether the given compressed matrix is in default state.
Definition: CompressedMatrix.h:5104
Header file for the DisableIf class template.
Header file for the IsSymmetric type trait.
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the SymmetricElement class.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5148
Compile time assertion.
bool isIntact(const CompressedMatrix< Type, SO > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:5131
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
#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
Header file for the Columns type trait.
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:330
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2640
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:538
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:254
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2641
Header file for all forward declarations for expression class templates.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
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
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2642
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:1285
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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2646
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:258
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
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2637
#define BLAZE_CONSTRAINT_MUST_BE_RESIZABLE(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
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:950
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
#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 operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2638
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
#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:1303
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:609
#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:564