Sparse.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_ADAPTORS_HERMITIANMATRIX_SPARSE_H_
36 #define _BLAZE_MATH_ADAPTORS_HERMITIANMATRIX_SPARSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <utility>
45 #include <vector>
49 #include <blaze/math/Aliases.h>
58 #include <blaze/math/Exception.h>
61 #include <blaze/math/shims/Clear.h>
72 #include <blaze/util/Assert.h>
78 #include <blaze/util/DisableIf.h>
79 #include <blaze/util/EnableIf.h>
81 #include <blaze/util/TrueType.h>
82 #include <blaze/util/Types.h>
86 #include <blaze/util/Unused.h>
87 
88 
89 namespace blaze {
90 
91 //=================================================================================================
92 //
93 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES
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 HermitianMatrix<MT,SO,false>
108  : public SparseMatrix< HermitianMatrix<MT,SO,false>, SO >
109 {
110  private:
111  //**Type definitions****************************************************************************
112  typedef OppositeType_<MT> OT;
113  typedef TransposeType_<MT> TT;
114  typedef ElementType_<MT> ET;
115  //**********************************************************************************************
116 
117  public:
118  //**Type definitions****************************************************************************
119  typedef HermitianMatrix<MT,SO,false> This;
120  typedef SparseMatrix<This,SO> BaseType;
121  typedef This ResultType;
122  typedef HermitianMatrix<OT,!SO,false> OppositeType;
123  typedef HermitianMatrix<TT,!SO,false> TransposeType;
124  typedef ET ElementType;
125  typedef ReturnType_<MT> ReturnType;
126  typedef const This& CompositeType;
127  typedef HermitianProxy<MT> Reference;
128  typedef ConstReference_<MT> ConstReference;
129  typedef ConstIterator_<MT> ConstIterator;
130  //**********************************************************************************************
131 
132  //**Rebind struct definition********************************************************************
135  template< typename ET > // Data type of the other matrix
136  struct Rebind {
138  typedef HermitianMatrix< typename MT::template Rebind<ET>::Other > Other;
139  };
140  //**********************************************************************************************
141 
142  //**Iterator class definition*******************************************************************
145  class Iterator
146  {
147  public:
148  //**Type definitions*************************************************************************
149  typedef Iterator_<MT> IteratorType;
150 
151  typedef std::forward_iterator_tag IteratorCategory;
152  typedef HermitianElement<MT> ValueType;
153  typedef ValueType PointerType;
154  typedef ValueType ReferenceType;
155  typedef ptrdiff_t DifferenceType;
156 
157  // STL iterator requirements
158  typedef IteratorCategory iterator_category;
159  typedef ValueType value_type;
160  typedef PointerType pointer;
161  typedef ReferenceType reference;
162  typedef DifferenceType difference_type;
163  //*******************************************************************************************
164 
165  //**Default constructor**********************************************************************
168  inline Iterator()
169  : pos_ () // Iterator to the current sparse Hermitian matrix element
170  , matrix_( nullptr ) // The sparse matrix containing the iterator
171  , index_ ( 0UL ) // The row/column index of the iterator
172  {}
173  //*******************************************************************************************
174 
175  //**Constructor******************************************************************************
182  inline Iterator( IteratorType pos, MT& matrix, size_t index )
183  : pos_ ( pos ) // Iterator to the current sparse Hermitian matrix element
184  , matrix_( &matrix ) // The sparse matrix containing the iterator
185  , index_ ( index ) // The row/column index of the iterator
186  {}
187  //*******************************************************************************************
188 
189  //**Prefix increment operator****************************************************************
194  inline Iterator& operator++() {
195  ++pos_;
196  return *this;
197  }
198  //*******************************************************************************************
199 
200  //**Postfix increment operator***************************************************************
205  inline const Iterator operator++( int ) {
206  const Iterator tmp( *this );
207  ++(*this);
208  return tmp;
209  }
210  //*******************************************************************************************
211 
212  //**Element access operator******************************************************************
217  inline ReferenceType operator*() const {
218  return ReferenceType( pos_, matrix_, index_ );
219  }
220  //*******************************************************************************************
221 
222  //**Element access operator******************************************************************
227  inline PointerType operator->() const {
228  return PointerType( pos_, matrix_, index_ );
229  }
230  //*******************************************************************************************
231 
232  //**Conversion operator**********************************************************************
237  inline operator ConstIterator() const {
238  return pos_;
239  }
240  //*******************************************************************************************
241 
242  //**Equality operator************************************************************************
248  inline bool operator==( const Iterator& rhs ) const {
249  return pos_ == rhs.pos_;
250  }
251  //*******************************************************************************************
252 
253  //**Inequality operator**********************************************************************
259  inline bool operator!=( const Iterator& rhs ) const {
260  return !( *this == rhs );
261  }
262  //*******************************************************************************************
263 
264  //**Subtraction operator*********************************************************************
270  inline DifferenceType operator-( const Iterator& rhs ) const {
271  return pos_ - rhs.pos_;
272  }
273  //*******************************************************************************************
274 
275  //**Base function****************************************************************************
280  inline IteratorType base() const {
281  return pos_;
282  }
283  //*******************************************************************************************
284 
285  private:
286  //**Member variables*************************************************************************
287  IteratorType pos_;
288  MT* matrix_;
289  size_t index_;
290  //*******************************************************************************************
291  };
292  //**********************************************************************************************
293 
294  //**Compilation flags***************************************************************************
296  enum : bool { smpAssignable = false };
297  //**********************************************************************************************
298 
299  //**Constructors********************************************************************************
302  explicit inline HermitianMatrix();
303  explicit inline HermitianMatrix( size_t n );
304  explicit inline HermitianMatrix( size_t n, size_t nonzeros );
305  explicit inline HermitianMatrix( size_t n, const std::vector<size_t>& nonzeros );
306 
307  inline HermitianMatrix( const HermitianMatrix& m );
308  inline HermitianMatrix( HermitianMatrix&& m ) noexcept;
309 
310  template< typename MT2, bool SO2 >
311  inline HermitianMatrix( const Matrix<MT2,SO2>& m );
313  //**********************************************************************************************
314 
315  //**Destructor**********************************************************************************
316  // No explicitly declared destructor.
317  //**********************************************************************************************
318 
319  //**Data access functions***********************************************************************
322  inline Reference operator()( size_t i, size_t j );
323  inline ConstReference operator()( size_t i, size_t j ) const;
324  inline Reference at( size_t i, size_t j );
325  inline ConstReference at( size_t i, size_t j ) const;
326  inline Iterator begin ( size_t i );
327  inline ConstIterator begin ( size_t i ) const;
328  inline ConstIterator cbegin( size_t i ) const;
329  inline Iterator end ( size_t i );
330  inline ConstIterator end ( size_t i ) const;
331  inline ConstIterator cend ( size_t i ) const;
333  //**********************************************************************************************
334 
335  //**Assignment operators************************************************************************
338  inline HermitianMatrix& operator=( const HermitianMatrix& rhs );
339  inline HermitianMatrix& operator=( HermitianMatrix&& rhs ) noexcept;
340 
341  template< typename MT2, bool SO2 >
342  inline DisableIf_< IsComputation<MT2>, HermitianMatrix& > operator=( const Matrix<MT2,SO2>& rhs );
343 
344  template< typename MT2, bool SO2 >
345  inline EnableIf_< IsComputation<MT2>, HermitianMatrix& > operator=( const Matrix<MT2,SO2>& rhs );
346 
347  template< typename MT2 >
348  inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix& >
349  operator=( const Matrix<MT2,!SO>& rhs );
350 
351  template< typename MT2, bool SO2 >
352  inline DisableIf_< IsComputation<MT2>, HermitianMatrix& > operator+=( const Matrix<MT2,SO2>& rhs );
353 
354  template< typename MT2, bool SO2 >
355  inline EnableIf_< IsComputation<MT2>, HermitianMatrix& > operator+=( const Matrix<MT2,SO2>& rhs );
356 
357  template< typename MT2 >
358  inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix& >
359  operator+=( const Matrix<MT2,!SO>& rhs );
360 
361  template< typename MT2, bool SO2 >
362  inline DisableIf_< IsComputation<MT2>, HermitianMatrix& > operator-=( const Matrix<MT2,SO2>& rhs );
363 
364  template< typename MT2, bool SO2 >
365  inline EnableIf_< IsComputation<MT2>, HermitianMatrix& > operator-=( const Matrix<MT2,SO2>& rhs );
366 
367  template< typename MT2 >
368  inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix& >
369  operator-=( const Matrix<MT2,!SO>& rhs );
370 
371  template< typename MT2, bool SO2 >
372  inline HermitianMatrix& operator*=( const Matrix<MT2,SO2>& rhs );
373 
374  template< typename Other >
375  inline EnableIf_< IsNumeric<Other>, HermitianMatrix >& operator*=( Other rhs );
376 
377  template< typename Other >
378  inline EnableIf_< IsNumeric<Other>, HermitianMatrix >& operator/=( Other rhs );
380  //**********************************************************************************************
381 
382  //**Utility functions***************************************************************************
385  inline size_t rows() const noexcept;
386  inline size_t columns() const noexcept;
387  inline size_t capacity() const noexcept;
388  inline size_t capacity( size_t i ) const noexcept;
389  inline size_t nonZeros() const;
390  inline size_t nonZeros( size_t i ) const;
391  inline void reset();
392  inline void reset( size_t i );
393  inline void clear();
394  inline Iterator set( size_t i, size_t j, const ElementType& value );
395  inline Iterator insert( size_t i, size_t j, const ElementType& value );
396  inline void erase( size_t i, size_t j );
397  inline Iterator erase( size_t i, Iterator pos );
398  inline Iterator erase( size_t i, Iterator first, Iterator last );
399  inline void resize ( size_t n, bool preserve=true );
400  inline void reserve( size_t nonzeros );
401  inline void reserve( size_t i, size_t nonzeros );
402  inline void trim();
403  inline void trim( size_t i );
404  inline HermitianMatrix& transpose();
405  inline HermitianMatrix& ctranspose();
406  template< typename Other > inline HermitianMatrix& scale( const Other& scalar );
407  template< typename Other > inline HermitianMatrix& scaleDiagonal( Other scale );
408  inline void swap( HermitianMatrix& m ) noexcept;
410  //**********************************************************************************************
411 
412  //**Lookup functions****************************************************************************
415  inline Iterator find ( size_t i, size_t j );
416  inline ConstIterator find ( size_t i, size_t j ) const;
417  inline Iterator lowerBound( size_t i, size_t j );
418  inline ConstIterator lowerBound( size_t i, size_t j ) const;
419  inline Iterator upperBound( size_t i, size_t j );
420  inline ConstIterator upperBound( size_t i, size_t j ) const;
422  //**********************************************************************************************
423 
424  //**Low-level utility functions*****************************************************************
427  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
428  inline void finalize( size_t i );
430  //**********************************************************************************************
431 
432  //**Debugging functions*************************************************************************
435  inline bool isIntact() const noexcept;
437  //**********************************************************************************************
438 
439  //**Expression template evaluation functions****************************************************
442  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
443  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
444 
445  inline bool canSMPAssign() const noexcept;
447  //**********************************************************************************************
448 
449  private:
450  //**Construction functions**********************************************************************
453  template< typename MT2, bool SO2, typename T >
454  inline const MT2& construct( const Matrix<MT2,SO2>& m, T );
455 
456  template< typename MT2 >
457  inline TransExprTrait_<MT2> construct( const Matrix<MT2,!SO>& m, TrueType );
459  //**********************************************************************************************
460 
461  //**Member variables****************************************************************************
464  MT matrix_;
465 
466  //**********************************************************************************************
467 
468  //**Friend declarations*************************************************************************
469  template< typename MT2, bool SO2, bool DF2 >
470  friend bool isDefault( const HermitianMatrix<MT2,SO2,DF2>& m );
471  //**********************************************************************************************
472 
473  //**Compile time checks*************************************************************************
487  BLAZE_STATIC_ASSERT( Rows<MT>::value == Columns<MT>::value );
488  //**********************************************************************************************
489 };
491 //*************************************************************************************************
492 
493 
494 
495 
496 //=================================================================================================
497 //
498 // CONSTRUCTORS
499 //
500 //=================================================================================================
501 
502 //*************************************************************************************************
506 template< typename MT // Type of the adapted sparse matrix
507  , bool SO > // Storage order of the adapted sparse matrix
508 inline HermitianMatrix<MT,SO,false>::HermitianMatrix()
509  : matrix_() // The adapted sparse matrix
510 {
511  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
512 }
514 //*************************************************************************************************
515 
516 
517 //*************************************************************************************************
525 template< typename MT // Type of the adapted sparse matrix
526  , bool SO > // Storage order of the adapted sparse matrix
527 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n )
528  : matrix_( n, n ) // The adapted sparse matrix
529 {
531 
532  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
533 }
535 //*************************************************************************************************
536 
537 
538 //*************************************************************************************************
547 template< typename MT // Type of the adapted sparse matrix
548  , bool SO > // Storage order of the adapted sparse matrix
549 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n, size_t nonzeros )
550  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
551 {
553 
554  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
555 }
557 //*************************************************************************************************
558 
559 
560 //*************************************************************************************************
571 template< typename MT // Type of the adapted sparse matrix
572  , bool SO > // Storage order of the adapted sparse matrix
573 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n, const std::vector<size_t>& nonzeros )
574  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
575 {
577 
578  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix 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 HermitianMatrix<MT,SO,false>::HermitianMatrix( const HermitianMatrix& m )
593  : matrix_( m.matrix_ ) // The adapted sparse matrix
594 {
595  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
596  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
597 }
599 //*************************************************************************************************
600 
601 
602 //*************************************************************************************************
608 template< typename MT // Type of the adapted sparse matrix
609  , bool SO > // Storage order of the adapted sparse matrix
610 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( HermitianMatrix&& m ) noexcept
611  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
612 {
613  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
614  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
615 }
617 //*************************************************************************************************
618 
619 
620 //*************************************************************************************************
630 template< typename MT // Type of the adapted sparse matrix
631  , bool SO > // Storage order of the adapted sparse matrix
632 template< typename MT2 // Type of the foreign matrix
633  , bool SO2 > // Storage order of the foreign matrix
634 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( const Matrix<MT2,SO2>& m )
635  : matrix_( construct( m, typename IsBuiltin< ElementType_<MT2> >::Type() ) ) // The adapted sparse matrix
636 {
637  if( !IsHermitian<MT2>::value && !isHermitian( matrix_ ) ) {
638  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of Hermitian matrix" );
639  }
640 }
642 //*************************************************************************************************
643 
644 
645 
646 
647 //=================================================================================================
648 //
649 // DATA ACCESS FUNCTIONS
650 //
651 //=================================================================================================
652 
653 //*************************************************************************************************
669 template< typename MT // Type of the adapted sparse matrix
670  , bool SO > // Storage order of the adapted sparse matrix
672  HermitianMatrix<MT,SO,false>::operator()( size_t i, size_t j )
673 {
674  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
675  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
676 
677  return Reference( matrix_, i, j );
678 }
680 //*************************************************************************************************
681 
682 
683 //*************************************************************************************************
699 template< typename MT // Type of the adapted sparse matrix
700  , bool SO > // Storage order of the adapted sparse matrix
702  HermitianMatrix<MT,SO,false>::operator()( size_t i, size_t j ) const
703 {
704  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
705  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
706 
707  return matrix_(i,j);
708 }
710 //*************************************************************************************************
711 
712 
713 //*************************************************************************************************
730 template< typename MT // Type of the adapted sparse matrix
731  , bool SO > // Storage order of the adapted sparse matrix
733  HermitianMatrix<MT,SO,false>::at( size_t i, size_t j )
734 {
735  if( i >= rows() ) {
736  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
737  }
738  if( j >= columns() ) {
739  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
740  }
741  return (*this)(i,j);
742 }
744 //*************************************************************************************************
745 
746 
747 //*************************************************************************************************
764 template< typename MT // Type of the adapted sparse matrix
765  , bool SO > // Storage order of the adapted sparse matrix
767  HermitianMatrix<MT,SO,false>::at( size_t i, size_t j ) const
768 {
769  if( i >= rows() ) {
770  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
771  }
772  if( j >= columns() ) {
773  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
774  }
775  return (*this)(i,j);
776 }
778 //*************************************************************************************************
779 
780 
781 //*************************************************************************************************
793 template< typename MT // Type of the adapted sparse matrix
794  , bool SO > // Storage order of the adapted sparse matrix
797 {
798  return Iterator( matrix_.begin(i), matrix_, i );
799 }
801 //*************************************************************************************************
802 
803 
804 //*************************************************************************************************
816 template< typename MT // Type of the adapted sparse matrix
817  , bool SO > // Storage order of the adapted sparse matrix
819  HermitianMatrix<MT,SO,false>::begin( size_t i ) const
820 {
821  return matrix_.begin(i);
822 }
824 //*************************************************************************************************
825 
826 
827 //*************************************************************************************************
839 template< typename MT // Type of the adapted sparse matrix
840  , bool SO > // Storage order of the adapted sparse matrix
842  HermitianMatrix<MT,SO,false>::cbegin( size_t i ) const
843 {
844  return matrix_.cbegin(i);
845 }
847 //*************************************************************************************************
848 
849 
850 //*************************************************************************************************
862 template< typename MT // Type of the adapted sparse matrix
863  , bool SO > // Storage order of the adapted sparse matrix
866 {
867  return Iterator( matrix_.end(i), matrix_, i );
868 }
870 //*************************************************************************************************
871 
872 
873 //*************************************************************************************************
885 template< typename MT // Type of the adapted sparse matrix
886  , bool SO > // Storage order of the adapted sparse matrix
888  HermitianMatrix<MT,SO,false>::end( size_t i ) const
889 {
890  return matrix_.end(i);
891 }
893 //*************************************************************************************************
894 
895 
896 //*************************************************************************************************
908 template< typename MT // Type of the adapted sparse matrix
909  , bool SO > // Storage order of the adapted sparse matrix
911  HermitianMatrix<MT,SO,false>::cend( size_t i ) const
912 {
913  return matrix_.cend(i);
914 }
916 //*************************************************************************************************
917 
918 
919 
920 
921 //=================================================================================================
922 //
923 // ASSIGNMENT OPERATORS
924 //
925 //=================================================================================================
926 
927 //*************************************************************************************************
937 template< typename MT // Type of the adapted sparse matrix
938  , bool SO > // Storage order of the adapted sparse matrix
939 inline HermitianMatrix<MT,SO,false>&
940  HermitianMatrix<MT,SO,false>::operator=( const HermitianMatrix& rhs )
941 {
942  matrix_ = rhs.matrix_;
943 
944  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
945  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
946 
947  return *this;
948 }
950 //*************************************************************************************************
951 
952 
953 //*************************************************************************************************
960 template< typename MT // Type of the adapted sparse matrix
961  , bool SO > // Storage order of the adapted sparse matrix
962 inline HermitianMatrix<MT,SO,false>&
963  HermitianMatrix<MT,SO,false>::operator=( HermitianMatrix&& rhs ) noexcept
964 {
965  matrix_ = std::move( rhs.matrix_ );
966 
967  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
968  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
969 
970  return *this;
971 }
973 //*************************************************************************************************
974 
975 
976 //*************************************************************************************************
989 template< typename MT // Type of the adapted sparse matrix
990  , bool SO > // Storage order of the adapted sparse matrix
991 template< typename MT2 // Type of the right-hand side matrix
992  , bool SO2 > // Storage order of the right-hand side matrix
993 inline DisableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
994  HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
995 {
996  if( !IsHermitian<MT2>::value && !isHermitian( ~rhs ) ) {
997  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
998  }
999 
1000  matrix_ = ~rhs;
1001 
1002  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1003  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1004 
1005  return *this;
1006 }
1008 //*************************************************************************************************
1009 
1010 
1011 //*************************************************************************************************
1024 template< typename MT // Type of the adapted sparse matrix
1025  , bool SO > // Storage order of the adapted sparse matrix
1026 template< typename MT2 // Type of the right-hand side matrix
1027  , bool SO2 > // Storage order of the right-hand side matrix
1028 inline EnableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1029  HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1030 {
1031  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1032  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1033  }
1034 
1035  if( IsHermitian<MT2>::value ) {
1036  matrix_ = ~rhs;
1037  }
1038  else {
1039  MT tmp( ~rhs );
1040 
1041  if( !isHermitian( tmp ) ) {
1042  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1043  }
1044 
1045  matrix_ = std::move( tmp );
1046  }
1047 
1048  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1049  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1050 
1051  return *this;
1052 }
1054 //*************************************************************************************************
1055 
1056 
1057 //*************************************************************************************************
1070 template< typename MT // Type of the adapted sparse matrix
1071  , bool SO > // Storage order of the adapted sparse matrix
1072 template< typename MT2 > // Type of the right-hand side matrix
1073 inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix<MT,SO,false>& >
1074  HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,!SO>& rhs )
1075 {
1076  return this->operator=( trans( ~rhs ) );
1077 }
1079 //*************************************************************************************************
1080 
1081 
1082 //*************************************************************************************************
1095 template< typename MT // Type of the adapted sparse matrix
1096  , bool SO > // Storage order of the adapted sparse matrix
1097 template< typename MT2 // Type of the right-hand side matrix
1098  , bool SO2 > // Storage order of the right-hand side matrix
1099 inline DisableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1100  HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1101 {
1102  if( !IsHermitian<MT2>::value && !isHermitian( ~rhs ) ) {
1103  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1104  }
1105 
1106  matrix_ += ~rhs;
1107 
1108  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1109  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1110 
1111  return *this;
1112 }
1114 //*************************************************************************************************
1115 
1116 
1117 //*************************************************************************************************
1130 template< typename MT // Type of the adapted sparse matrix
1131  , bool SO > // Storage order of the adapted sparse matrix
1132 template< typename MT2 // Type of the right-hand side matrix
1133  , bool SO2 > // Storage order of the right-hand side matrix
1134 inline EnableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1135  HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1136 {
1137  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1138  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1139  }
1140 
1141  if( IsHermitian<MT2>::value ) {
1142  matrix_ += ~rhs;
1143  }
1144  else {
1145  const ResultType_<MT2> tmp( ~rhs );
1146 
1147  if( !isHermitian( tmp ) ) {
1148  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1149  }
1150 
1151  matrix_ += tmp;
1152  }
1153 
1154  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1155  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1156 
1157  return *this;
1158 }
1160 //*************************************************************************************************
1161 
1162 
1163 //*************************************************************************************************
1177 template< typename MT // Type of the adapted sparse matrix
1178  , bool SO > // Storage order of the adapted sparse matrix
1179 template< typename MT2 > // Type of the right-hand side matrix
1180 inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix<MT,SO,false>& >
1181  HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,!SO>& rhs )
1182 {
1183  return this->operator+=( trans( ~rhs ) );
1184 }
1186 //*************************************************************************************************
1187 
1188 
1189 //*************************************************************************************************
1202 template< typename MT // Type of the adapted sparse matrix
1203  , bool SO > // Storage order of the adapted sparse matrix
1204 template< typename MT2 // Type of the right-hand side matrix
1205  , bool SO2 > // Storage order of the right-hand side matrix
1206 inline DisableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1207  HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1208 {
1209  if( !IsHermitian<MT2>::value && !isHermitian( ~rhs ) ) {
1210  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1211  }
1212 
1213  matrix_ -= ~rhs;
1214 
1215  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1216  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1217 
1218  return *this;
1219 }
1221 //*************************************************************************************************
1222 
1223 
1224 //*************************************************************************************************
1237 template< typename MT // Type of the adapted sparse matrix
1238  , bool SO > // Storage order of the adapted sparse matrix
1239 template< typename MT2 // Type of the right-hand side matrix
1240  , bool SO2 > // Storage order of the right-hand side matrix
1241 inline EnableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1242  HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1243 {
1244  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1245  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1246  }
1247 
1248  if( IsHermitian<MT2>::value ) {
1249  matrix_ -= ~rhs;
1250  }
1251  else {
1252  const ResultType_<MT2> tmp( ~rhs );
1253 
1254  if( !isHermitian( tmp ) ) {
1255  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1256  }
1257 
1258  matrix_ -= tmp;
1259  }
1260 
1261  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1262  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1263 
1264  return *this;
1265 }
1267 //*************************************************************************************************
1268 
1269 
1270 //*************************************************************************************************
1284 template< typename MT // Type of the adapted sparse matrix
1285  , bool SO > // Storage order of the adapted sparse matrix
1286 template< typename MT2 > // Type of the right-hand side matrix
1287 inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix<MT,SO,false>& >
1288  HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,!SO>& rhs )
1289 {
1290  return this->operator-=( trans( ~rhs ) );
1291 }
1293 //*************************************************************************************************
1294 
1295 
1296 //*************************************************************************************************
1308 template< typename MT // Type of the adapted sparse matrix
1309  , bool SO > // Storage order of the adapted sparse matrix
1310 template< typename MT2 // Type of the right-hand side matrix
1311  , bool SO2 > // Storage order of the right-hand side matrix
1312 inline HermitianMatrix<MT,SO,false>&
1313  HermitianMatrix<MT,SO,false>::operator*=( const Matrix<MT2,SO2>& rhs )
1314 {
1315  if( matrix_.rows() != (~rhs).columns() ) {
1316  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1317  }
1318 
1319  MT tmp( matrix_ * ~rhs );
1320 
1321  if( !isHermitian( tmp ) ) {
1322  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1323  }
1324 
1325  matrix_ = std::move( tmp );
1326 
1327  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1328  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1329 
1330  return *this;
1331 }
1333 //*************************************************************************************************
1334 
1335 
1336 //*************************************************************************************************
1344 template< typename MT // Type of the adapted sparse matrix
1345  , bool SO > // Storage order of the adapted sparse matrix
1346 template< typename Other > // Data type of the right-hand side scalar
1347 inline EnableIf_< IsNumeric<Other>, HermitianMatrix<MT,SO,false> >&
1349 {
1350  matrix_ *= rhs;
1351  return *this;
1352 }
1353 //*************************************************************************************************
1354 
1355 
1356 //*************************************************************************************************
1364 template< typename MT // Type of the adapted sparse matrix
1365  , bool SO > // Storage order of the adapted sparse matrix
1366 template< typename Other > // Data type of the right-hand side scalar
1367 inline EnableIf_< IsNumeric<Other>, HermitianMatrix<MT,SO,false> >&
1369 {
1370  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1371 
1372  matrix_ /= rhs;
1373  return *this;
1374 }
1376 //*************************************************************************************************
1377 
1378 
1379 
1380 
1381 //=================================================================================================
1382 //
1383 // UTILITY FUNCTIONS
1384 //
1385 //=================================================================================================
1386 
1387 //*************************************************************************************************
1393 template< typename MT // Type of the adapted sparse matrix
1394  , bool SO > // Storage order of the adapted sparse matrix
1395 inline size_t HermitianMatrix<MT,SO,false>::rows() const noexcept
1396 {
1397  return matrix_.rows();
1398 }
1400 //*************************************************************************************************
1401 
1402 
1403 //*************************************************************************************************
1409 template< typename MT // Type of the adapted sparse matrix
1410  , bool SO > // Storage order of the adapted sparse matrix
1411 inline size_t HermitianMatrix<MT,SO,false>::columns() const noexcept
1412 {
1413  return matrix_.columns();
1414 }
1416 //*************************************************************************************************
1417 
1418 
1419 //*************************************************************************************************
1425 template< typename MT // Type of the adapted sparse matrix
1426  , bool SO > // Storage order of the adapted sparse matrix
1427 inline size_t HermitianMatrix<MT,SO,false>::capacity() const noexcept
1428 {
1429  return matrix_.capacity();
1430 }
1432 //*************************************************************************************************
1433 
1434 
1435 //*************************************************************************************************
1446 template< typename MT // Type of the adapted sparse matrix
1447  , bool SO > // Storage order of the adapted sparse matrix
1448 inline size_t HermitianMatrix<MT,SO,false>::capacity( size_t i ) const noexcept
1449 {
1450  return matrix_.capacity(i);
1451 }
1453 //*************************************************************************************************
1454 
1455 
1456 //*************************************************************************************************
1462 template< typename MT // Type of the adapted sparse matrix
1463  , bool SO > // Storage order of the adapted sparse matrix
1464 inline size_t HermitianMatrix<MT,SO,false>::nonZeros() const
1465 {
1466  return matrix_.nonZeros();
1467 }
1469 //*************************************************************************************************
1470 
1471 
1472 //*************************************************************************************************
1484 template< typename MT // Type of the adapted sparse matrix
1485  , bool SO > // Storage order of the adapted sparse matrix
1486 inline size_t HermitianMatrix<MT,SO,false>::nonZeros( size_t i ) const
1487 {
1488  return matrix_.nonZeros(i);
1489 }
1491 //*************************************************************************************************
1492 
1493 
1494 //*************************************************************************************************
1500 template< typename MT // Type of the adapted sparse matrix
1501  , bool SO > // Storage order of the adapted sparse matrix
1503 {
1504  matrix_.reset();
1505 }
1507 //*************************************************************************************************
1508 
1509 
1510 //*************************************************************************************************
1546 template< typename MT // Type of the adapted sparse matrix
1547  , bool SO > // Storage order of the adapted sparse matrix
1548 inline void HermitianMatrix<MT,SO,false>::reset( size_t i )
1549 {
1550  for( Iterator_<MT> it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1551  {
1552  const size_t j( it->index() );
1553 
1554  if( i == j )
1555  continue;
1556 
1557  if( SO ) {
1558  const Iterator_<MT> pos( matrix_.find( i, j ) );
1559  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1560  matrix_.erase( j, pos );
1561  }
1562  else {
1563  const Iterator_<MT> pos( matrix_.find( j, i ) );
1564  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1565  matrix_.erase( j, pos );
1566  }
1567  }
1568 
1569  matrix_.reset( i );
1570 }
1572 //*************************************************************************************************
1573 
1574 
1575 //*************************************************************************************************
1583 template< typename MT // Type of the adapted sparse matrix
1584  , bool SO > // Storage order of the adapted sparse matrix
1586 {
1587  using blaze::clear;
1588 
1589  clear( matrix_ );
1590 }
1592 //*************************************************************************************************
1593 
1594 
1595 //*************************************************************************************************
1610 template< typename MT // Type of the adapted sparse matrix
1611  , bool SO > // Storage order of the adapted sparse matrix
1613  HermitianMatrix<MT,SO,false>::set( size_t i, size_t j, const ElementType& value )
1614 {
1615  const bool isDiagonal( i == j );
1616 
1617  if( IsComplex<ElementType>::value && isDiagonal && !isReal( value ) ) {
1618  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
1619  }
1620 
1621  if( !isDiagonal )
1622  matrix_.set( j, i, conj( value ) );
1623  return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
1624 }
1626 //*************************************************************************************************
1627 
1628 
1629 //*************************************************************************************************
1645 template< typename MT // Type of the adapted sparse matrix
1646  , bool SO > // Storage order of the adapted sparse matrix
1648  HermitianMatrix<MT,SO,false>::insert( size_t i, size_t j, const ElementType& value )
1649 {
1650  const bool isDiagonal( i == j );
1651 
1652  if( IsComplex<ElementType>::value && isDiagonal && !isReal( value ) ) {
1653  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
1654  }
1655 
1656  if( !isDiagonal )
1657  matrix_.insert( j, i, conj( value ) );
1658  return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
1659 }
1661 //*************************************************************************************************
1662 
1663 
1664 //*************************************************************************************************
1674 template< typename MT // Type of the adapted sparse matrix
1675  , bool SO > // Storage order of the adapted sparse matrix
1676 inline void HermitianMatrix<MT,SO,false>::erase( size_t i, size_t j )
1677 {
1678  matrix_.erase( i, j );
1679  if( i != j )
1680  matrix_.erase( j, i );
1681 }
1683 //*************************************************************************************************
1684 
1685 
1686 //*************************************************************************************************
1698 template< typename MT // Type of the adapted sparse matrix
1699  , bool SO > // Storage order of the adapted sparse matrix
1701  HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator pos )
1702 {
1703  const Iterator_<MT> base( pos.base() );
1704 
1705  if( base == matrix_.end( i ) )
1706  return pos;
1707 
1708  const size_t j( base->index() );
1709 
1710  if( i == j ) {
1711  BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
1712  return Iterator( matrix_.erase( i, base ), matrix_, i );
1713  }
1714 
1715  if( SO ) {
1716  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1717  matrix_.erase( j, matrix_.find( i, j ) );
1718  return Iterator( matrix_.erase( i, base ), matrix_, i );
1719  }
1720  else {
1721  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1722  matrix_.erase( j, matrix_.find( j, i ) );
1723  return Iterator( matrix_.erase( i, base ), matrix_, i );
1724  }
1725 }
1727 //*************************************************************************************************
1728 
1729 
1730 //*************************************************************************************************
1744 template< typename MT // Type of the adapted sparse matrix
1745  , bool SO > // Storage order of the adapted sparse matrix
1747  HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last )
1748 {
1749  for( Iterator_<MT> it=first.base(); it!=last.base(); ++it )
1750  {
1751  const size_t j( it->index() );
1752 
1753  if( i == j )
1754  continue;
1755 
1756  if( SO ) {
1757  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1758  matrix_.erase( i, j );
1759  }
1760  else {
1761  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1762  matrix_.erase( j, i );
1763  }
1764  }
1765 
1766  return Iterator( matrix_.erase( i, first.base(), last.base() ), matrix_, i );
1767 }
1769 //*************************************************************************************************
1770 
1771 
1772 //*************************************************************************************************
1787 template< typename MT // Type of the adapted sparse matrix
1788  , bool SO > // Storage order of the adapted sparse matrix
1789 void HermitianMatrix<MT,SO,false>::resize( size_t n, bool preserve )
1790 {
1792 
1793  UNUSED_PARAMETER( preserve );
1794 
1795  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1796 
1797  matrix_.resize( n, n, true );
1798 }
1800 //*************************************************************************************************
1801 
1802 
1803 //*************************************************************************************************
1814 template< typename MT // Type of the adapted sparse matrix
1815  , bool SO > // Storage order of the adapted sparse matrix
1816 inline void HermitianMatrix<MT,SO,false>::reserve( size_t nonzeros )
1817 {
1818  matrix_.reserve( nonzeros );
1819 }
1821 //*************************************************************************************************
1822 
1823 
1824 //*************************************************************************************************
1838 template< typename MT // Type of the adapted sparse matrix
1839  , bool SO > // Storage order of the adapted sparse matrix
1840 inline void HermitianMatrix<MT,SO,false>::reserve( size_t i, size_t nonzeros )
1841 {
1842  matrix_.reserve( i, nonzeros );
1843 }
1845 //*************************************************************************************************
1846 
1847 
1848 //*************************************************************************************************
1859 template< typename MT // Type of the adapted sparse matrix
1860  , bool SO > // Storage order of the adapted sparse matrix
1861 inline void HermitianMatrix<MT,SO,false>::trim()
1862 {
1863  matrix_.trim();
1864 }
1866 //*************************************************************************************************
1867 
1868 
1869 //*************************************************************************************************
1881 template< typename MT // Type of the adapted sparse matrix
1882  , bool SO > // Storage order of the adapted sparse matrix
1883 inline void HermitianMatrix<MT,SO,false>::trim( size_t i )
1884 {
1885  matrix_.trim( i );
1886 }
1888 //*************************************************************************************************
1889 
1890 
1891 //*************************************************************************************************
1897 template< typename MT // Type of the adapted sparse matrix
1898  , bool SO > // Storage order of the adapted sparse matrix
1899 inline HermitianMatrix<MT,SO,false>& HermitianMatrix<MT,SO,false>::transpose()
1900 {
1901  if( IsComplex<ElementType>::value )
1902  matrix_.transpose();
1903  return *this;
1904 }
1906 //*************************************************************************************************
1907 
1908 
1909 //*************************************************************************************************
1915 template< typename MT // Type of the adapted sparse matrix
1916  , bool SO > // Storage order of the adapted sparse matrix
1917 inline HermitianMatrix<MT,SO,false>& HermitianMatrix<MT,SO,false>::ctranspose()
1918 {
1919  return *this;
1920 }
1922 //*************************************************************************************************
1923 
1924 
1925 //*************************************************************************************************
1932 template< typename MT // Type of the adapted sparse matrix
1933  , bool SO > // Storage order of the adapted sparse matrix
1934 template< typename Other > // Data type of the scalar value
1935 inline HermitianMatrix<MT,SO,false>&
1936  HermitianMatrix<MT,SO,false>::scale( const Other& scalar )
1937 {
1938  matrix_.scale( scalar );
1939  return *this;
1940 }
1942 //*************************************************************************************************
1943 
1944 
1945 //*************************************************************************************************
1952 template< typename MT // Type of the adapted sparse matrix
1953  , bool SO > // Storage order of the adapted sparse matrix
1954 template< typename Other > // Data type of the scalar value
1955 inline HermitianMatrix<MT,SO,false>&
1956  HermitianMatrix<MT,SO,false>::scaleDiagonal( Other scalar )
1957 {
1958  matrix_.scaleDiagonal( scalar );
1959  return *this;
1960 }
1962 //*************************************************************************************************
1963 
1964 
1965 //*************************************************************************************************
1972 template< typename MT // Type of the adapted sparse matrix
1973  , bool SO > // Storage order of the adapted sparse matrix
1974 inline void HermitianMatrix<MT,SO,false>::swap( HermitianMatrix& m ) noexcept
1975 {
1976  using std::swap;
1977 
1978  swap( matrix_, m.matrix_ );
1979 }
1981 //*************************************************************************************************
1982 
1983 
1984 
1985 
1986 //=================================================================================================
1987 //
1988 // LOOKUP FUNCTIONS
1989 //
1990 //=================================================================================================
1991 
1992 //*************************************************************************************************
2008 template< typename MT // Type of the adapted sparse matrix
2009  , bool SO > // Storage order of the adapted sparse matrix
2011  HermitianMatrix<MT,SO,false>::find( size_t i, size_t j )
2012 {
2013  return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2014 }
2016 //*************************************************************************************************
2017 
2018 
2019 //*************************************************************************************************
2035 template< typename MT // Type of the adapted sparse matrix
2036  , bool SO > // Storage order of the adapted sparse matrix
2038  HermitianMatrix<MT,SO,false>::find( size_t i, size_t j ) const
2039 {
2040  return matrix_.find( i, j );
2041 }
2043 //*************************************************************************************************
2044 
2045 
2046 //*************************************************************************************************
2062 template< typename MT // Type of the adapted sparse matrix
2063  , bool SO > // Storage order of the adapted sparse matrix
2065  HermitianMatrix<MT,SO,false>::lowerBound( size_t i, size_t j )
2066 {
2067  return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2068 }
2070 //*************************************************************************************************
2071 
2072 
2073 //*************************************************************************************************
2089 template< typename MT // Type of the adapted sparse matrix
2090  , bool SO > // Storage order of the adapted sparse matrix
2092  HermitianMatrix<MT,SO,false>::lowerBound( size_t i, size_t j ) const
2093 {
2094  return matrix_.lowerBound( i, j );
2095 }
2097 //*************************************************************************************************
2098 
2099 
2100 //*************************************************************************************************
2116 template< typename MT // Type of the adapted sparse matrix
2117  , bool SO > // Storage order of the adapted sparse matrix
2119  HermitianMatrix<MT,SO,false>::upperBound( size_t i, size_t j )
2120 {
2121  return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2122 }
2124 //*************************************************************************************************
2125 
2126 
2127 //*************************************************************************************************
2143 template< typename MT // Type of the adapted sparse matrix
2144  , bool SO > // Storage order of the adapted sparse matrix
2146  HermitianMatrix<MT,SO,false>::upperBound( size_t i, size_t j ) const
2147 {
2148  return matrix_.upperBound( i, j );
2149 }
2151 //*************************************************************************************************
2152 
2153 
2154 
2155 
2156 //=================================================================================================
2157 //
2158 // LOW-LEVEL UTILITY FUNCTIONS
2159 //
2160 //=================================================================================================
2161 
2162 //*************************************************************************************************
2221 template< typename MT // Type of the adapted sparse matrix
2222  , bool SO > // Storage order of the adapted sparse matrix
2223 inline void HermitianMatrix<MT,SO,false>::append( size_t i, size_t j, const ElementType& value, bool check )
2224 {
2225  const bool isDiagonal( i == j );
2226 
2227  if( IsComplex<ElementType>::value && isDiagonal && !isReal( value ) ) {
2228  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2229  }
2230 
2231  matrix_.append( i, j, value, check );
2232  if( !isDiagonal && ( !check || !isDefault( value ) ) )
2233  matrix_.insert( j, i, conj( value ) );
2234 }
2236 //*************************************************************************************************
2237 
2238 
2239 //*************************************************************************************************
2253 template< typename MT // Type of the adapted sparse matrix
2254  , bool SO > // Storage order of the adapted sparse matrix
2255 inline void HermitianMatrix<MT,SO,false>::finalize( size_t i )
2256 {
2257  matrix_.trim( i );
2258 }
2260 //*************************************************************************************************
2261 
2262 
2263 
2264 
2265 //=================================================================================================
2266 //
2267 // DEBUGGING FUNCTIONS
2268 //
2269 //=================================================================================================
2270 
2271 //*************************************************************************************************
2281 template< typename MT // Type of the adapted sparse matrix
2282  , bool SO > // Storage order of the adapted sparse matrix
2283 inline bool HermitianMatrix<MT,SO,false>::isIntact() const noexcept
2284 {
2285  using blaze::isIntact;
2286 
2287  return ( isIntact( matrix_ ) && isHermitian( matrix_ ) );
2288 }
2290 //*************************************************************************************************
2291 
2292 
2293 
2294 
2295 //=================================================================================================
2296 //
2297 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
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 HermitianMatrix<MT,SO,false>::canAlias( const Other* alias ) const noexcept
2316 {
2317  return matrix_.canAlias( 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 template< typename Other > // Data type of the foreign expression
2337 inline bool HermitianMatrix<MT,SO,false>::isAliased( const Other* alias ) const noexcept
2338 {
2339  return matrix_.isAliased( alias );
2340 }
2342 //*************************************************************************************************
2343 
2344 
2345 //*************************************************************************************************
2356 template< typename MT // Type of the adapted sparse matrix
2357  , bool SO > // Storage order of the adapted sparse matrix
2358 inline bool HermitianMatrix<MT,SO,false>::canSMPAssign() const noexcept
2359 {
2360  return matrix_.canSMPAssign();
2361 }
2363 //*************************************************************************************************
2364 
2365 
2366 
2367 
2368 //=================================================================================================
2369 //
2370 // CONSTRUCTION FUNCTIONS
2371 //
2372 //=================================================================================================
2373 
2374 //*************************************************************************************************
2376 template< typename MT // Type of the adapted dense matrix
2377  , bool SO > // Storage order of the adapted dense matrix
2378 template< typename MT2 // Type of the foreign matrix
2379  , bool SO2 // Storage order of the foreign matrix
2380  , typename T > // Type of the third argument
2381 inline const MT2& HermitianMatrix<MT,SO,false>::construct( const Matrix<MT2,SO2>& m, T )
2382 {
2383  return ~m;
2384 }
2386 //*************************************************************************************************
2387 
2388 
2389 //*************************************************************************************************
2391 template< typename MT // Type of the adapted dense matrix
2392  , bool SO > // Storage order of the adapted dense matrix
2393 template< typename MT2 > // Type of the foreign matrix
2394 inline TransExprTrait_<MT2>
2395  HermitianMatrix<MT,SO,false>::construct( const Matrix<MT2,!SO>& m, TrueType )
2396 {
2397  return trans( ~m );
2398 }
2400 //*************************************************************************************************
2401 
2402 } // namespace blaze
2403 
2404 #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
const DMatForEachExpr< MT, Conj, SO > conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatForEachExpr.h:1158
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
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is diagonal.
Definition: DenseMatrix.h:1499
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.
bool isReal(const DiagonalProxy< MT > &proxy)
Returns whether the matrix element represents a real number.
Definition: DiagonalProxy.h:595
#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.
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
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
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.
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
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.
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:143
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 clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
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.
typename T::ElementType ElementType_
Alias declaration for nested ElementType type definitions.The ElementType_ alias declaration provides...
Definition: Aliases.h:163
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 the implementation of the base template of the HeritianMatrix.
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 HermitianElement class.
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 TransExprTrait class template.
Constraint on the data type.
Constraint on the data type.
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.
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:759
#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
Header file for the HermitianProxy class.
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
Header file for the IsComplex type trait.
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
Header file for the IsHermitian type trait.
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:609
Header file for the isReal shim.
#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
Header file for the TrueType type/value trait base class.
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:564