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  using OT = OppositeType_<MT>;
113  using TT = TransposeType_<MT>;
114  using ET = ElementType_<MT>;
115  //**********************************************************************************************
116 
117  public:
118  //**Type definitions****************************************************************************
119  using This = HermitianMatrix<MT,SO,false>;
120  using BaseType = SparseMatrix<This,SO>;
121  using ResultType = This;
122  using OppositeType = HermitianMatrix<OT,!SO,false>;
123  using TransposeType = HermitianMatrix<TT,!SO,false>;
124  using ElementType = ET;
125  using ReturnType = ReturnType_<MT>;
126  using CompositeType = const This&;
127  using Reference = HermitianProxy<MT>;
128  using ConstReference = ConstReference_<MT>;
129  using ConstIterator = ConstIterator_<MT>;
130  //**********************************************************************************************
131 
132  //**Rebind struct definition********************************************************************
135  template< typename NewType > // Data type of the other matrix
136  struct Rebind {
138  using Other = HermitianMatrix< typename MT::template Rebind<NewType>::Other >;
139  };
140  //**********************************************************************************************
141 
142  //**Resize struct definition********************************************************************
145  template< size_t NewM // Number of rows of the other matrix
146  , size_t NewN > // Number of columns of the other matrix
147  struct Resize {
149  using Other = HermitianMatrix< typename MT::template Resize<NewM,NewN>::Other >;
150  };
151  //**********************************************************************************************
152 
153  //**Iterator class definition*******************************************************************
156  class Iterator
157  {
158  public:
159  //**Type definitions*************************************************************************
160  using IteratorType = Iterator_<MT>;
161 
162  using IteratorCategory = std::forward_iterator_tag;
163  using ValueType = HermitianElement<MT>;
164  using PointerType = ValueType;
165  using ReferenceType = ValueType;
166  using DifferenceType = ptrdiff_t;
167 
168  // STL iterator requirements
169  using iterator_category = IteratorCategory;
170  using value_type = ValueType;
171  using pointer = PointerType;
172  using reference = ReferenceType;
173  using difference_type = DifferenceType;
174  //*******************************************************************************************
175 
176  //**Default constructor**********************************************************************
179  inline Iterator()
180  : pos_ () // Iterator to the current sparse Hermitian matrix element
181  , matrix_( nullptr ) // The sparse matrix containing the iterator
182  , index_ ( 0UL ) // The row/column index of the iterator
183  {}
184  //*******************************************************************************************
185 
186  //**Constructor******************************************************************************
193  inline Iterator( IteratorType pos, MT& matrix, size_t index )
194  : pos_ ( pos ) // Iterator to the current sparse Hermitian matrix element
195  , matrix_( &matrix ) // The sparse matrix containing the iterator
196  , index_ ( index ) // The row/column index of the iterator
197  {}
198  //*******************************************************************************************
199 
200  //**Prefix increment operator****************************************************************
205  inline Iterator& operator++() {
206  ++pos_;
207  return *this;
208  }
209  //*******************************************************************************************
210 
211  //**Postfix increment operator***************************************************************
216  inline const Iterator operator++( int ) {
217  const Iterator tmp( *this );
218  ++(*this);
219  return tmp;
220  }
221  //*******************************************************************************************
222 
223  //**Element access operator******************************************************************
228  inline ReferenceType operator*() const {
229  return ReferenceType( pos_, matrix_, index_ );
230  }
231  //*******************************************************************************************
232 
233  //**Element access operator******************************************************************
238  inline PointerType operator->() const {
239  return PointerType( pos_, matrix_, index_ );
240  }
241  //*******************************************************************************************
242 
243  //**Conversion operator**********************************************************************
248  inline operator ConstIterator() const {
249  return pos_;
250  }
251  //*******************************************************************************************
252 
253  //**Equality operator************************************************************************
259  inline bool operator==( const Iterator& rhs ) const {
260  return pos_ == rhs.pos_;
261  }
262  //*******************************************************************************************
263 
264  //**Inequality operator**********************************************************************
270  inline bool operator!=( const Iterator& rhs ) const {
271  return !( *this == rhs );
272  }
273  //*******************************************************************************************
274 
275  //**Subtraction operator*********************************************************************
281  inline DifferenceType operator-( const Iterator& rhs ) const {
282  return pos_ - rhs.pos_;
283  }
284  //*******************************************************************************************
285 
286  //**Base function****************************************************************************
291  inline IteratorType base() const {
292  return pos_;
293  }
294  //*******************************************************************************************
295 
296  private:
297  //**Member variables*************************************************************************
298  IteratorType pos_;
299  MT* matrix_;
300  size_t index_;
301  //*******************************************************************************************
302  };
303  //**********************************************************************************************
304 
305  //**Compilation flags***************************************************************************
307  enum : bool { smpAssignable = false };
308  //**********************************************************************************************
309 
310  //**Constructors********************************************************************************
313  explicit inline HermitianMatrix();
314  explicit inline HermitianMatrix( size_t n );
315  explicit inline HermitianMatrix( size_t n, size_t nonzeros );
316  explicit inline HermitianMatrix( size_t n, const std::vector<size_t>& nonzeros );
317 
318  inline HermitianMatrix( const HermitianMatrix& m );
319  inline HermitianMatrix( HermitianMatrix&& m ) noexcept;
320 
321  template< typename MT2, bool SO2 >
322  inline HermitianMatrix( const Matrix<MT2,SO2>& m );
324  //**********************************************************************************************
325 
326  //**Destructor**********************************************************************************
327  // No explicitly declared destructor.
328  //**********************************************************************************************
329 
330  //**Data access functions***********************************************************************
333  inline Reference operator()( size_t i, size_t j );
334  inline ConstReference operator()( size_t i, size_t j ) const;
335  inline Reference at( size_t i, size_t j );
336  inline ConstReference at( size_t i, size_t j ) const;
337  inline Iterator begin ( size_t i );
338  inline ConstIterator begin ( size_t i ) const;
339  inline ConstIterator cbegin( size_t i ) const;
340  inline Iterator end ( size_t i );
341  inline ConstIterator end ( size_t i ) const;
342  inline ConstIterator cend ( size_t i ) const;
344  //**********************************************************************************************
345 
346  //**Assignment operators************************************************************************
349  inline HermitianMatrix& operator=( const HermitianMatrix& rhs );
350  inline HermitianMatrix& operator=( HermitianMatrix&& rhs ) noexcept;
351 
352  template< typename MT2, bool SO2 >
353  inline DisableIf_< IsComputation<MT2>, HermitianMatrix& > operator=( const Matrix<MT2,SO2>& rhs );
354 
355  template< typename MT2, bool SO2 >
356  inline EnableIf_< IsComputation<MT2>, HermitianMatrix& > operator=( const Matrix<MT2,SO2>& rhs );
357 
358  template< typename MT2 >
359  inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix& >
360  operator=( const Matrix<MT2,!SO>& rhs );
361 
362  template< typename MT2, bool SO2 >
363  inline DisableIf_< IsComputation<MT2>, HermitianMatrix& > operator+=( const Matrix<MT2,SO2>& rhs );
364 
365  template< typename MT2, bool SO2 >
366  inline EnableIf_< IsComputation<MT2>, HermitianMatrix& > operator+=( const Matrix<MT2,SO2>& rhs );
367 
368  template< typename MT2 >
369  inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix& >
370  operator+=( const Matrix<MT2,!SO>& rhs );
371 
372  template< typename MT2, bool SO2 >
373  inline DisableIf_< IsComputation<MT2>, HermitianMatrix& > operator-=( const Matrix<MT2,SO2>& rhs );
374 
375  template< typename MT2, bool SO2 >
376  inline EnableIf_< IsComputation<MT2>, HermitianMatrix& > operator-=( const Matrix<MT2,SO2>& rhs );
377 
378  template< typename MT2 >
379  inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix& >
380  operator-=( const Matrix<MT2,!SO>& rhs );
381 
382  template< typename MT2, bool SO2 >
383  inline DisableIf_< IsComputation<MT2>, HermitianMatrix& > operator%=( const Matrix<MT2,SO2>& rhs );
384 
385  template< typename MT2, bool SO2 >
386  inline EnableIf_< IsComputation<MT2>, HermitianMatrix& > operator%=( const Matrix<MT2,SO2>& rhs );
387 
388  template< typename MT2 >
389  inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix& >
390  operator%=( const Matrix<MT2,!SO>& rhs );
391 
392  template< typename MT2, bool SO2 >
393  inline HermitianMatrix& operator*=( const Matrix<MT2,SO2>& rhs );
394 
395  template< typename Other >
396  inline EnableIf_< IsNumeric<Other>, HermitianMatrix >& operator*=( Other rhs );
397 
398  template< typename Other >
399  inline EnableIf_< IsNumeric<Other>, HermitianMatrix >& operator/=( Other rhs );
401  //**********************************************************************************************
402 
403  //**Utility functions***************************************************************************
406  inline size_t rows() const noexcept;
407  inline size_t columns() const noexcept;
408  inline size_t capacity() const noexcept;
409  inline size_t capacity( size_t i ) const noexcept;
410  inline size_t nonZeros() const;
411  inline size_t nonZeros( size_t i ) const;
412  inline void reset();
413  inline void reset( size_t i );
414  inline void clear();
415  inline void resize ( size_t n, bool preserve=true );
416  inline void reserve( size_t nonzeros );
417  inline void reserve( size_t i, size_t nonzeros );
418  inline void trim();
419  inline void trim( size_t i );
420  inline void shrinkToFit();
421  inline void swap( HermitianMatrix& m ) noexcept;
423  //**********************************************************************************************
424 
425  //**Insertion functions*************************************************************************
428  inline Iterator set ( size_t i, size_t j, const ElementType& value );
429  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
430  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
431  inline void finalize( size_t i );
433  //**********************************************************************************************
434 
435  //**Erase functions*****************************************************************************
438  inline void erase( size_t i, size_t j );
439  inline Iterator erase( size_t i, Iterator pos );
440  inline Iterator erase( size_t i, Iterator first, Iterator last );
441 
442  template< typename Pred >
443  inline void erase( Pred predicate );
444 
445  template< typename Pred >
446  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
448  //**********************************************************************************************
449 
450  //**Lookup functions****************************************************************************
453  inline Iterator find ( size_t i, size_t j );
454  inline ConstIterator find ( size_t i, size_t j ) const;
455  inline Iterator lowerBound( size_t i, size_t j );
456  inline ConstIterator lowerBound( size_t i, size_t j ) const;
457  inline Iterator upperBound( size_t i, size_t j );
458  inline ConstIterator upperBound( size_t i, size_t j ) const;
460  //**********************************************************************************************
461 
462  //**Numeric functions***************************************************************************
465  inline HermitianMatrix& transpose();
466  inline HermitianMatrix& ctranspose();
467 
468  template< typename Other > inline HermitianMatrix& scale( const Other& scalar );
469  template< typename Other > inline HermitianMatrix& scaleDiagonal( const Other& scale );
471  //**********************************************************************************************
472 
473  //**Debugging functions*************************************************************************
476  inline bool isIntact() const noexcept;
478  //**********************************************************************************************
479 
480  //**Expression template evaluation functions****************************************************
483  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
484  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
485 
486  inline bool canSMPAssign() const noexcept;
488  //**********************************************************************************************
489 
490  private:
491  //**Construction functions**********************************************************************
494  template< typename MT2, bool SO2, typename T >
495  inline const MT2& construct( const Matrix<MT2,SO2>& m, T );
496 
497  template< typename MT2 >
498  inline TransExprTrait_<MT2> construct( const Matrix<MT2,!SO>& m, TrueType );
500  //**********************************************************************************************
501 
502  //**Member variables****************************************************************************
505  MT matrix_;
506 
507  //**********************************************************************************************
508 
509  //**Friend declarations*************************************************************************
510  template< bool RF, typename MT2, bool SO2, bool DF2 >
511  friend bool isDefault( const HermitianMatrix<MT2,SO2,DF2>& m );
512  //**********************************************************************************************
513 
514  //**Compile time checks*************************************************************************
528  BLAZE_STATIC_ASSERT( Rows<MT>::value == Columns<MT>::value );
529  //**********************************************************************************************
530 };
532 //*************************************************************************************************
533 
534 
535 
536 
537 //=================================================================================================
538 //
539 // CONSTRUCTORS
540 //
541 //=================================================================================================
542 
543 //*************************************************************************************************
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()
550  : matrix_() // The adapted sparse matrix
551 {
552  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
553 }
555 //*************************************************************************************************
556 
557 
558 //*************************************************************************************************
566 template< typename MT // Type of the adapted sparse matrix
567  , bool SO > // Storage order of the adapted sparse matrix
568 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n )
569  : matrix_( n, n ) // The adapted sparse matrix
570 {
572 
573  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
574 }
576 //*************************************************************************************************
577 
578 
579 //*************************************************************************************************
588 template< typename MT // Type of the adapted sparse matrix
589  , bool SO > // Storage order of the adapted sparse matrix
590 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n, size_t nonzeros )
591  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
592 {
594 
595  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
596 }
598 //*************************************************************************************************
599 
600 
601 //*************************************************************************************************
612 template< typename MT // Type of the adapted sparse matrix
613  , bool SO > // Storage order of the adapted sparse matrix
614 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n, const std::vector<size_t>& nonzeros )
615  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
616 {
618 
619  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
620 }
622 //*************************************************************************************************
623 
624 
625 //*************************************************************************************************
631 template< typename MT // Type of the adapted sparse matrix
632  , bool SO > // Storage order of the adapted sparse matrix
633 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( const HermitianMatrix& m )
634  : matrix_( m.matrix_ ) // The adapted sparse matrix
635 {
636  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
637  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
638 }
640 //*************************************************************************************************
641 
642 
643 //*************************************************************************************************
649 template< typename MT // Type of the adapted sparse matrix
650  , bool SO > // Storage order of the adapted sparse matrix
651 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( HermitianMatrix&& m ) noexcept
652  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
653 {
654  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
655  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
656 }
658 //*************************************************************************************************
659 
660 
661 //*************************************************************************************************
671 template< typename MT // Type of the adapted sparse matrix
672  , bool SO > // Storage order of the adapted sparse matrix
673 template< typename MT2 // Type of the foreign matrix
674  , bool SO2 > // Storage order of the foreign matrix
675 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( const Matrix<MT2,SO2>& m )
676  : matrix_( construct( m, typename IsBuiltin< ElementType_<MT2> >::Type() ) ) // The adapted sparse matrix
677 {
678  if( !IsHermitian<MT2>::value && !isHermitian( matrix_ ) ) {
679  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of Hermitian matrix" );
680  }
681 }
683 //*************************************************************************************************
684 
685 
686 
687 
688 //=================================================================================================
689 //
690 // DATA ACCESS FUNCTIONS
691 //
692 //=================================================================================================
693 
694 //*************************************************************************************************
710 template< typename MT // Type of the adapted sparse matrix
711  , bool SO > // Storage order of the adapted sparse matrix
713  HermitianMatrix<MT,SO,false>::operator()( size_t i, size_t j )
714 {
715  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
716  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
717 
718  return Reference( matrix_, i, j );
719 }
721 //*************************************************************************************************
722 
723 
724 //*************************************************************************************************
740 template< typename MT // Type of the adapted sparse matrix
741  , bool SO > // Storage order of the adapted sparse matrix
743  HermitianMatrix<MT,SO,false>::operator()( size_t i, size_t j ) const
744 {
745  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
746  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
747 
748  return matrix_(i,j);
749 }
751 //*************************************************************************************************
752 
753 
754 //*************************************************************************************************
771 template< typename MT // Type of the adapted sparse matrix
772  , bool SO > // Storage order of the adapted sparse matrix
774  HermitianMatrix<MT,SO,false>::at( size_t i, size_t j )
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 //*************************************************************************************************
805 template< typename MT // Type of the adapted sparse matrix
806  , bool SO > // Storage order of the adapted sparse matrix
808  HermitianMatrix<MT,SO,false>::at( size_t i, size_t j ) const
809 {
810  if( i >= rows() ) {
811  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
812  }
813  if( j >= columns() ) {
814  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
815  }
816  return (*this)(i,j);
817 }
819 //*************************************************************************************************
820 
821 
822 //*************************************************************************************************
834 template< typename MT // Type of the adapted sparse matrix
835  , bool SO > // Storage order of the adapted sparse matrix
838 {
839  return Iterator( matrix_.begin(i), matrix_, i );
840 }
842 //*************************************************************************************************
843 
844 
845 //*************************************************************************************************
857 template< typename MT // Type of the adapted sparse matrix
858  , bool SO > // Storage order of the adapted sparse matrix
860  HermitianMatrix<MT,SO,false>::begin( size_t i ) const
861 {
862  return matrix_.begin(i);
863 }
865 //*************************************************************************************************
866 
867 
868 //*************************************************************************************************
880 template< typename MT // Type of the adapted sparse matrix
881  , bool SO > // Storage order of the adapted sparse matrix
883  HermitianMatrix<MT,SO,false>::cbegin( size_t i ) const
884 {
885  return matrix_.cbegin(i);
886 }
888 //*************************************************************************************************
889 
890 
891 //*************************************************************************************************
903 template< typename MT // Type of the adapted sparse matrix
904  , bool SO > // Storage order of the adapted sparse matrix
907 {
908  return Iterator( matrix_.end(i), matrix_, i );
909 }
911 //*************************************************************************************************
912 
913 
914 //*************************************************************************************************
926 template< typename MT // Type of the adapted sparse matrix
927  , bool SO > // Storage order of the adapted sparse matrix
929  HermitianMatrix<MT,SO,false>::end( size_t i ) const
930 {
931  return matrix_.end(i);
932 }
934 //*************************************************************************************************
935 
936 
937 //*************************************************************************************************
949 template< typename MT // Type of the adapted sparse matrix
950  , bool SO > // Storage order of the adapted sparse matrix
952  HermitianMatrix<MT,SO,false>::cend( size_t i ) const
953 {
954  return matrix_.cend(i);
955 }
957 //*************************************************************************************************
958 
959 
960 
961 
962 //=================================================================================================
963 //
964 // ASSIGNMENT OPERATORS
965 //
966 //=================================================================================================
967 
968 //*************************************************************************************************
978 template< typename MT // Type of the adapted sparse matrix
979  , bool SO > // Storage order of the adapted sparse matrix
980 inline HermitianMatrix<MT,SO,false>&
981  HermitianMatrix<MT,SO,false>::operator=( const HermitianMatrix& rhs )
982 {
983  matrix_ = rhs.matrix_;
984 
985  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
986  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
987 
988  return *this;
989 }
991 //*************************************************************************************************
992 
993 
994 //*************************************************************************************************
1001 template< typename MT // Type of the adapted sparse matrix
1002  , bool SO > // Storage order of the adapted sparse matrix
1003 inline HermitianMatrix<MT,SO,false>&
1004  HermitianMatrix<MT,SO,false>::operator=( HermitianMatrix&& rhs ) noexcept
1005 {
1006  matrix_ = std::move( rhs.matrix_ );
1007 
1008  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian 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  , bool SO2 > // Storage order of the right-hand side matrix
1034 inline DisableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1035  HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1036 {
1037  if( !IsHermitian<MT2>::value && !isHermitian( ~rhs ) ) {
1038  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1039  }
1040 
1041  matrix_ = ~rhs;
1042 
1043  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1044  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1045 
1046  return *this;
1047 }
1049 //*************************************************************************************************
1050 
1051 
1052 //*************************************************************************************************
1065 template< typename MT // Type of the adapted sparse matrix
1066  , bool SO > // Storage order of the adapted sparse matrix
1067 template< typename MT2 // Type of the right-hand side matrix
1068  , bool SO2 > // Storage order of the right-hand side matrix
1069 inline EnableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1070  HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1071 {
1072  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1073  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1074  }
1075 
1076  if( IsHermitian<MT2>::value ) {
1077  matrix_ = ~rhs;
1078  }
1079  else {
1080  MT tmp( ~rhs );
1081 
1082  if( !isHermitian( tmp ) ) {
1083  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1084  }
1085 
1086  matrix_ = std::move( tmp );
1087  }
1088 
1089  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1090  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1091 
1092  return *this;
1093 }
1095 //*************************************************************************************************
1096 
1097 
1098 //*************************************************************************************************
1111 template< typename MT // Type of the adapted sparse matrix
1112  , bool SO > // Storage order of the adapted sparse matrix
1113 template< typename MT2 > // Type of the right-hand side matrix
1114 inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix<MT,SO,false>& >
1115  HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,!SO>& rhs )
1116 {
1117  return this->operator=( trans( ~rhs ) );
1118 }
1120 //*************************************************************************************************
1121 
1122 
1123 //*************************************************************************************************
1136 template< typename MT // Type of the adapted sparse matrix
1137  , bool SO > // Storage order of the adapted sparse matrix
1138 template< typename MT2 // Type of the right-hand side matrix
1139  , bool SO2 > // Storage order of the right-hand side matrix
1140 inline DisableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1141  HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1142 {
1143  if( !IsHermitian<MT2>::value && !isHermitian( ~rhs ) ) {
1144  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1145  }
1146 
1147  matrix_ += ~rhs;
1148 
1149  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1150  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1151 
1152  return *this;
1153 }
1155 //*************************************************************************************************
1156 
1157 
1158 //*************************************************************************************************
1171 template< typename MT // Type of the adapted sparse matrix
1172  , bool SO > // Storage order of the adapted sparse matrix
1173 template< typename MT2 // Type of the right-hand side matrix
1174  , bool SO2 > // Storage order of the right-hand side matrix
1175 inline EnableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1176  HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1177 {
1178  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1179  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1180  }
1181 
1182  if( IsHermitian<MT2>::value ) {
1183  matrix_ += ~rhs;
1184  }
1185  else {
1186  const ResultType_<MT2> tmp( ~rhs );
1187 
1188  if( !isHermitian( tmp ) ) {
1189  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1190  }
1191 
1192  matrix_ += tmp;
1193  }
1194 
1195  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1196  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1197 
1198  return *this;
1199 }
1201 //*************************************************************************************************
1202 
1203 
1204 //*************************************************************************************************
1218 template< typename MT // Type of the adapted sparse matrix
1219  , bool SO > // Storage order of the adapted sparse matrix
1220 template< typename MT2 > // Type of the right-hand side matrix
1221 inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix<MT,SO,false>& >
1222  HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,!SO>& rhs )
1223 {
1224  return this->operator+=( trans( ~rhs ) );
1225 }
1227 //*************************************************************************************************
1228 
1229 
1230 //*************************************************************************************************
1243 template< typename MT // Type of the adapted sparse matrix
1244  , bool SO > // Storage order of the adapted sparse matrix
1245 template< typename MT2 // Type of the right-hand side matrix
1246  , bool SO2 > // Storage order of the right-hand side matrix
1247 inline DisableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1248  HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1249 {
1250  if( !IsHermitian<MT2>::value && !isHermitian( ~rhs ) ) {
1251  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1252  }
1253 
1254  matrix_ -= ~rhs;
1255 
1256  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1257  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1258 
1259  return *this;
1260 }
1262 //*************************************************************************************************
1263 
1264 
1265 //*************************************************************************************************
1278 template< typename MT // Type of the adapted sparse matrix
1279  , bool SO > // Storage order of the adapted sparse matrix
1280 template< typename MT2 // Type of the right-hand side matrix
1281  , bool SO2 > // Storage order of the right-hand side matrix
1282 inline EnableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1283  HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1284 {
1285  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1286  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1287  }
1288 
1289  if( IsHermitian<MT2>::value ) {
1290  matrix_ -= ~rhs;
1291  }
1292  else {
1293  const ResultType_<MT2> tmp( ~rhs );
1294 
1295  if( !isHermitian( tmp ) ) {
1296  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1297  }
1298 
1299  matrix_ -= tmp;
1300  }
1301 
1302  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1303  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1304 
1305  return *this;
1306 }
1308 //*************************************************************************************************
1309 
1310 
1311 //*************************************************************************************************
1325 template< typename MT // Type of the adapted sparse matrix
1326  , bool SO > // Storage order of the adapted sparse matrix
1327 template< typename MT2 > // Type of the right-hand side matrix
1328 inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix<MT,SO,false>& >
1329  HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,!SO>& rhs )
1330 {
1331  return this->operator-=( trans( ~rhs ) );
1332 }
1334 //*************************************************************************************************
1335 
1336 
1337 //*************************************************************************************************
1351 template< typename MT // Type of the adapted sparse matrix
1352  , bool SO > // Storage order of the adapted sparse matrix
1353 template< typename MT2 // Type of the right-hand side matrix
1354  , bool SO2 > // Storage order of the right-hand side matrix
1355 inline DisableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1356  HermitianMatrix<MT,SO,false>::operator%=( const Matrix<MT2,SO2>& rhs )
1357 {
1358  if( !IsHermitian<MT2>::value && !isHermitian( ~rhs ) ) {
1359  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1360  }
1361 
1362  matrix_ %= ~rhs;
1363 
1364  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1365  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1366 
1367  return *this;
1368 }
1370 //*************************************************************************************************
1371 
1372 
1373 //*************************************************************************************************
1387 template< typename MT // Type of the adapted sparse matrix
1388  , bool SO > // Storage order of the adapted sparse matrix
1389 template< typename MT2 // Type of the right-hand side matrix
1390  , bool SO2 > // Storage order of the right-hand side matrix
1391 inline EnableIf_< IsComputation<MT2>, HermitianMatrix<MT,SO,false>& >
1392  HermitianMatrix<MT,SO,false>::operator%=( const Matrix<MT2,SO2>& rhs )
1393 {
1394  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1395  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1396  }
1397 
1398  if( IsHermitian<MT2>::value ) {
1399  matrix_ %= ~rhs;
1400  }
1401  else {
1402  const ResultType_<MT2> tmp( ~rhs );
1403 
1404  if( !isHermitian( tmp ) ) {
1405  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1406  }
1407 
1408  matrix_ %= tmp;
1409  }
1410 
1411  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1412  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1413 
1414  return *this;
1415 }
1417 //*************************************************************************************************
1418 
1419 
1420 //*************************************************************************************************
1434 template< typename MT // Type of the adapted sparse matrix
1435  , bool SO > // Storage order of the adapted sparse matrix
1436 template< typename MT2 > // Type of the right-hand side matrix
1437 inline EnableIf_< IsBuiltin< ElementType_<MT2> >, HermitianMatrix<MT,SO,false>& >
1438  HermitianMatrix<MT,SO,false>::operator%=( const Matrix<MT2,!SO>& rhs )
1439 {
1440  return this->operator%=( trans( ~rhs ) );
1441 }
1443 //*************************************************************************************************
1444 
1445 
1446 //*************************************************************************************************
1458 template< typename MT // Type of the adapted sparse matrix
1459  , bool SO > // Storage order of the adapted sparse matrix
1460 template< typename MT2 // Type of the right-hand side matrix
1461  , bool SO2 > // Storage order of the right-hand side matrix
1462 inline HermitianMatrix<MT,SO,false>&
1463  HermitianMatrix<MT,SO,false>::operator*=( const Matrix<MT2,SO2>& rhs )
1464 {
1465  if( matrix_.rows() != (~rhs).columns() ) {
1466  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1467  }
1468 
1469  MT tmp( matrix_ * ~rhs );
1470 
1471  if( !isHermitian( tmp ) ) {
1472  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1473  }
1474 
1475  matrix_ = std::move( tmp );
1476 
1477  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1478  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1479 
1480  return *this;
1481 }
1483 //*************************************************************************************************
1484 
1485 
1486 //*************************************************************************************************
1494 template< typename MT // Type of the adapted sparse matrix
1495  , bool SO > // Storage order of the adapted sparse matrix
1496 template< typename Other > // Data type of the right-hand side scalar
1497 inline EnableIf_< IsNumeric<Other>, HermitianMatrix<MT,SO,false> >&
1499 {
1500  matrix_ *= rhs;
1501  return *this;
1502 }
1503 //*************************************************************************************************
1504 
1505 
1506 //*************************************************************************************************
1514 template< typename MT // Type of the adapted sparse matrix
1515  , bool SO > // Storage order of the adapted sparse matrix
1516 template< typename Other > // Data type of the right-hand side scalar
1517 inline EnableIf_< IsNumeric<Other>, HermitianMatrix<MT,SO,false> >&
1519 {
1520  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1521 
1522  matrix_ /= rhs;
1523  return *this;
1524 }
1526 //*************************************************************************************************
1527 
1528 
1529 
1530 
1531 //=================================================================================================
1532 //
1533 // UTILITY FUNCTIONS
1534 //
1535 //=================================================================================================
1536 
1537 //*************************************************************************************************
1543 template< typename MT // Type of the adapted sparse matrix
1544  , bool SO > // Storage order of the adapted sparse matrix
1545 inline size_t HermitianMatrix<MT,SO,false>::rows() const noexcept
1546 {
1547  return matrix_.rows();
1548 }
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1559 template< typename MT // Type of the adapted sparse matrix
1560  , bool SO > // Storage order of the adapted sparse matrix
1561 inline size_t HermitianMatrix<MT,SO,false>::columns() const noexcept
1562 {
1563  return matrix_.columns();
1564 }
1566 //*************************************************************************************************
1567 
1568 
1569 //*************************************************************************************************
1575 template< typename MT // Type of the adapted sparse matrix
1576  , bool SO > // Storage order of the adapted sparse matrix
1577 inline size_t HermitianMatrix<MT,SO,false>::capacity() const noexcept
1578 {
1579  return matrix_.capacity();
1580 }
1582 //*************************************************************************************************
1583 
1584 
1585 //*************************************************************************************************
1596 template< typename MT // Type of the adapted sparse matrix
1597  , bool SO > // Storage order of the adapted sparse matrix
1598 inline size_t HermitianMatrix<MT,SO,false>::capacity( size_t i ) const noexcept
1599 {
1600  return matrix_.capacity(i);
1601 }
1603 //*************************************************************************************************
1604 
1605 
1606 //*************************************************************************************************
1612 template< typename MT // Type of the adapted sparse matrix
1613  , bool SO > // Storage order of the adapted sparse matrix
1614 inline size_t HermitianMatrix<MT,SO,false>::nonZeros() const
1615 {
1616  return matrix_.nonZeros();
1617 }
1619 //*************************************************************************************************
1620 
1621 
1622 //*************************************************************************************************
1634 template< typename MT // Type of the adapted sparse matrix
1635  , bool SO > // Storage order of the adapted sparse matrix
1636 inline size_t HermitianMatrix<MT,SO,false>::nonZeros( size_t i ) const
1637 {
1638  return matrix_.nonZeros(i);
1639 }
1641 //*************************************************************************************************
1642 
1643 
1644 //*************************************************************************************************
1650 template< typename MT // Type of the adapted sparse matrix
1651  , bool SO > // Storage order of the adapted sparse matrix
1653 {
1654  matrix_.reset();
1655 }
1657 //*************************************************************************************************
1658 
1659 
1660 //*************************************************************************************************
1696 template< typename MT // Type of the adapted sparse matrix
1697  , bool SO > // Storage order of the adapted sparse matrix
1698 inline void HermitianMatrix<MT,SO,false>::reset( size_t i )
1699 {
1700  for( Iterator_<MT> it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1701  {
1702  const size_t j( it->index() );
1703 
1704  if( i == j )
1705  continue;
1706 
1707  if( SO ) {
1708  const Iterator_<MT> pos( matrix_.find( i, j ) );
1709  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1710  matrix_.erase( j, pos );
1711  }
1712  else {
1713  const Iterator_<MT> pos( matrix_.find( j, i ) );
1714  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1715  matrix_.erase( j, pos );
1716  }
1717  }
1718 
1719  matrix_.reset( i );
1720 }
1722 //*************************************************************************************************
1723 
1724 
1725 //*************************************************************************************************
1733 template< typename MT // Type of the adapted sparse matrix
1734  , bool SO > // Storage order of the adapted sparse matrix
1736 {
1737  using blaze::clear;
1738 
1739  clear( matrix_ );
1740 }
1742 //*************************************************************************************************
1743 
1744 
1745 //*************************************************************************************************
1760 template< typename MT // Type of the adapted sparse matrix
1761  , bool SO > // Storage order of the adapted sparse matrix
1762 void HermitianMatrix<MT,SO,false>::resize( size_t n, bool preserve )
1763 {
1765 
1766  UNUSED_PARAMETER( preserve );
1767 
1768  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1769 
1770  matrix_.resize( n, n, true );
1771 }
1773 //*************************************************************************************************
1774 
1775 
1776 //*************************************************************************************************
1787 template< typename MT // Type of the adapted sparse matrix
1788  , bool SO > // Storage order of the adapted sparse matrix
1789 inline void HermitianMatrix<MT,SO,false>::reserve( size_t nonzeros )
1790 {
1791  matrix_.reserve( nonzeros );
1792 }
1794 //*************************************************************************************************
1795 
1796 
1797 //*************************************************************************************************
1811 template< typename MT // Type of the adapted sparse matrix
1812  , bool SO > // Storage order of the adapted sparse matrix
1813 inline void HermitianMatrix<MT,SO,false>::reserve( size_t i, size_t nonzeros )
1814 {
1815  matrix_.reserve( i, nonzeros );
1816 }
1818 //*************************************************************************************************
1819 
1820 
1821 //*************************************************************************************************
1832 template< typename MT // Type of the adapted sparse matrix
1833  , bool SO > // Storage order of the adapted sparse matrix
1834 inline void HermitianMatrix<MT,SO,false>::trim()
1835 {
1836  matrix_.trim();
1837 }
1839 //*************************************************************************************************
1840 
1841 
1842 //*************************************************************************************************
1854 template< typename MT // Type of the adapted sparse matrix
1855  , bool SO > // Storage order of the adapted sparse matrix
1856 inline void HermitianMatrix<MT,SO,false>::trim( size_t i )
1857 {
1858  matrix_.trim( i );
1859 }
1861 //*************************************************************************************************
1862 
1863 
1864 //*************************************************************************************************
1874 template< typename MT // Type of the adapted sparse matrix
1875  , bool SO > // Storage order of the adapted sparse matrix
1877 {
1878  matrix_.shrinkToFit();
1879 }
1881 //*************************************************************************************************
1882 
1883 
1884 //*************************************************************************************************
1891 template< typename MT // Type of the adapted sparse matrix
1892  , bool SO > // Storage order of the adapted sparse matrix
1893 inline void HermitianMatrix<MT,SO,false>::swap( HermitianMatrix& m ) noexcept
1894 {
1895  using std::swap;
1896 
1897  swap( matrix_, m.matrix_ );
1898 }
1900 //*************************************************************************************************
1901 
1902 
1903 
1904 
1905 //=================================================================================================
1906 //
1907 // INSERTION FUNCTIONS
1908 //
1909 //=================================================================================================
1910 
1911 //*************************************************************************************************
1926 template< typename MT // Type of the adapted sparse matrix
1927  , bool SO > // Storage order of the adapted sparse matrix
1929  HermitianMatrix<MT,SO,false>::set( size_t i, size_t j, const ElementType& value )
1930 {
1931  const bool isDiagonal( i == j );
1932 
1933  if( IsComplex<ElementType>::value && isDiagonal && !isReal( value ) ) {
1934  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
1935  }
1936 
1937  if( !isDiagonal )
1938  matrix_.set( j, i, conj( value ) );
1939  return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
1940 }
1942 //*************************************************************************************************
1943 
1944 
1945 //*************************************************************************************************
1961 template< typename MT // Type of the adapted sparse matrix
1962  , bool SO > // Storage order of the adapted sparse matrix
1964  HermitianMatrix<MT,SO,false>::insert( size_t i, size_t j, const ElementType& value )
1965 {
1966  const bool isDiagonal( i == j );
1967 
1968  if( IsComplex<ElementType>::value && isDiagonal && !isReal( value ) ) {
1969  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
1970  }
1971 
1972  if( !isDiagonal )
1973  matrix_.insert( j, i, conj( value ) );
1974  return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
1975 }
1977 //*************************************************************************************************
1978 
1979 
1980 //*************************************************************************************************
2039 template< typename MT // Type of the adapted sparse matrix
2040  , bool SO > // Storage order of the adapted sparse matrix
2041 inline void HermitianMatrix<MT,SO,false>::append( size_t i, size_t j, const ElementType& value, bool check )
2042 {
2043  const bool isDiagonal( i == j );
2044 
2045  if( IsComplex<ElementType>::value && isDiagonal && !isReal( value ) ) {
2046  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2047  }
2048 
2049  matrix_.append( i, j, value, check );
2050  if( !isDiagonal && ( !check || !isDefault<strict>( value ) ) )
2051  matrix_.insert( j, i, conj( value ) );
2052 }
2054 //*************************************************************************************************
2055 
2056 
2057 //*************************************************************************************************
2071 template< typename MT // Type of the adapted sparse matrix
2072  , bool SO > // Storage order of the adapted sparse matrix
2073 inline void HermitianMatrix<MT,SO,false>::finalize( size_t i )
2074 {
2075  matrix_.trim( i );
2076 }
2078 //*************************************************************************************************
2079 
2080 
2081 
2082 
2083 //=================================================================================================
2084 //
2085 // ERASE FUNCTIONS
2086 //
2087 //=================================================================================================
2088 
2089 //*************************************************************************************************
2099 template< typename MT // Type of the adapted sparse matrix
2100  , bool SO > // Storage order of the adapted sparse matrix
2101 inline void HermitianMatrix<MT,SO,false>::erase( size_t i, size_t j )
2102 {
2103  matrix_.erase( i, j );
2104  if( i != j )
2105  matrix_.erase( j, i );
2106 }
2108 //*************************************************************************************************
2109 
2110 
2111 //*************************************************************************************************
2123 template< typename MT // Type of the adapted sparse matrix
2124  , bool SO > // Storage order of the adapted sparse matrix
2126  HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator pos )
2127 {
2128  const Iterator_<MT> base( pos.base() );
2129 
2130  if( base == matrix_.end( i ) )
2131  return pos;
2132 
2133  const size_t j( base->index() );
2134 
2135  if( i == j ) {
2136  BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
2137  return Iterator( matrix_.erase( i, base ), matrix_, i );
2138  }
2139 
2140  if( SO ) {
2141  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2142  matrix_.erase( j, matrix_.find( i, j ) );
2143  return Iterator( matrix_.erase( i, base ), matrix_, i );
2144  }
2145  else {
2146  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2147  matrix_.erase( j, matrix_.find( j, i ) );
2148  return Iterator( matrix_.erase( i, base ), matrix_, i );
2149  }
2150 }
2152 //*************************************************************************************************
2153 
2154 
2155 //*************************************************************************************************
2169 template< typename MT // Type of the adapted sparse matrix
2170  , bool SO > // Storage order of the adapted sparse matrix
2172  HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last )
2173 {
2174  for( Iterator_<MT> it=first.base(); it!=last.base(); ++it )
2175  {
2176  const size_t j( it->index() );
2177 
2178  if( i == j )
2179  continue;
2180 
2181  if( SO ) {
2182  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2183  matrix_.erase( i, j );
2184  }
2185  else {
2186  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2187  matrix_.erase( j, i );
2188  }
2189  }
2190 
2191  return Iterator( matrix_.erase( i, first.base(), last.base() ), matrix_, i );
2192 }
2194 //*************************************************************************************************
2195 
2196 
2197 //*************************************************************************************************
2219 template< typename MT // Type of the adapted sparse matrix
2220  , bool SO > // Storage order of the adapted sparse matrix
2221 template< typename Pred > // Type of the unary predicate
2222 inline void HermitianMatrix<MT,SO,false>::erase( Pred predicate )
2223 {
2224  matrix_.erase( [predicate=predicate]( const ElementType& value ) {
2225  return predicate( value ) || predicate( conj( value ) );
2226  } );
2227 
2228  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2229 }
2231 //*************************************************************************************************
2232 
2233 
2234 //*************************************************************************************************
2262 template< typename MT // Type of the adapted sparse matrix
2263  , bool SO > // Storage order of the adapted sparse matrix
2264 template< typename Pred > // Type of the unary predicate
2265 inline void
2266  HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2267 {
2268  for( Iterator it=first; it!=last; ++it ) {
2269  const size_t j( it->index() );
2270  if( i != j && predicate( it->value() ) ) {
2271  if( SO )
2272  matrix_.erase( i, j );
2273  else
2274  matrix_.erase( j, i );
2275  }
2276  }
2277 
2278  matrix_.erase( i, first.base(), last.base(), predicate );
2279 
2280  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2281 }
2283 //*************************************************************************************************
2284 
2285 
2286 
2287 
2288 //=================================================================================================
2289 //
2290 // LOOKUP FUNCTIONS
2291 //
2292 //=================================================================================================
2293 
2294 //*************************************************************************************************
2310 template< typename MT // Type of the adapted sparse matrix
2311  , bool SO > // Storage order of the adapted sparse matrix
2313  HermitianMatrix<MT,SO,false>::find( size_t i, size_t j )
2314 {
2315  return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2316 }
2318 //*************************************************************************************************
2319 
2320 
2321 //*************************************************************************************************
2337 template< typename MT // Type of the adapted sparse matrix
2338  , bool SO > // Storage order of the adapted sparse matrix
2340  HermitianMatrix<MT,SO,false>::find( size_t i, size_t j ) const
2341 {
2342  return matrix_.find( i, j );
2343 }
2345 //*************************************************************************************************
2346 
2347 
2348 //*************************************************************************************************
2364 template< typename MT // Type of the adapted sparse matrix
2365  , bool SO > // Storage order of the adapted sparse matrix
2367  HermitianMatrix<MT,SO,false>::lowerBound( size_t i, size_t j )
2368 {
2369  return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2370 }
2372 //*************************************************************************************************
2373 
2374 
2375 //*************************************************************************************************
2391 template< typename MT // Type of the adapted sparse matrix
2392  , bool SO > // Storage order of the adapted sparse matrix
2394  HermitianMatrix<MT,SO,false>::lowerBound( size_t i, size_t j ) const
2395 {
2396  return matrix_.lowerBound( i, j );
2397 }
2399 //*************************************************************************************************
2400 
2401 
2402 //*************************************************************************************************
2418 template< typename MT // Type of the adapted sparse matrix
2419  , bool SO > // Storage order of the adapted sparse matrix
2421  HermitianMatrix<MT,SO,false>::upperBound( size_t i, size_t j )
2422 {
2423  return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2424 }
2426 //*************************************************************************************************
2427 
2428 
2429 //*************************************************************************************************
2445 template< typename MT // Type of the adapted sparse matrix
2446  , bool SO > // Storage order of the adapted sparse matrix
2448  HermitianMatrix<MT,SO,false>::upperBound( size_t i, size_t j ) const
2449 {
2450  return matrix_.upperBound( i, j );
2451 }
2453 //*************************************************************************************************
2454 
2455 
2456 
2457 
2458 //=================================================================================================
2459 //
2460 // NUMERIC FUNCTIONS
2461 //
2462 //=================================================================================================
2463 
2464 //*************************************************************************************************
2470 template< typename MT // Type of the adapted sparse matrix
2471  , bool SO > // Storage order of the adapted sparse matrix
2472 inline HermitianMatrix<MT,SO,false>& HermitianMatrix<MT,SO,false>::transpose()
2473 {
2474  if( IsComplex<ElementType>::value )
2475  matrix_.transpose();
2476  return *this;
2477 }
2479 //*************************************************************************************************
2480 
2481 
2482 //*************************************************************************************************
2488 template< typename MT // Type of the adapted sparse matrix
2489  , bool SO > // Storage order of the adapted sparse matrix
2490 inline HermitianMatrix<MT,SO,false>& HermitianMatrix<MT,SO,false>::ctranspose()
2491 {
2492  return *this;
2493 }
2495 //*************************************************************************************************
2496 
2497 
2498 //*************************************************************************************************
2516 template< typename MT // Type of the adapted sparse matrix
2517  , bool SO > // Storage order of the adapted sparse matrix
2518 template< typename Other > // Data type of the scalar value
2519 inline HermitianMatrix<MT,SO,false>&
2520  HermitianMatrix<MT,SO,false>::scale( const Other& scalar )
2521 {
2522  matrix_.scale( scalar );
2523  return *this;
2524 }
2526 //*************************************************************************************************
2527 
2528 
2529 //*************************************************************************************************
2539 template< typename MT // Type of the adapted sparse matrix
2540  , bool SO > // Storage order of the adapted sparse matrix
2541 template< typename Other > // Data type of the scalar value
2542 inline HermitianMatrix<MT,SO,false>&
2543  HermitianMatrix<MT,SO,false>::scaleDiagonal( const Other& scalar )
2544 {
2545  matrix_.scaleDiagonal( scalar );
2546  return *this;
2547 }
2549 //*************************************************************************************************
2550 
2551 
2552 
2553 
2554 //=================================================================================================
2555 //
2556 // DEBUGGING FUNCTIONS
2557 //
2558 //=================================================================================================
2559 
2560 //*************************************************************************************************
2570 template< typename MT // Type of the adapted sparse matrix
2571  , bool SO > // Storage order of the adapted sparse matrix
2572 inline bool HermitianMatrix<MT,SO,false>::isIntact() const noexcept
2573 {
2574  using blaze::isIntact;
2575 
2576  return ( isIntact( matrix_ ) && isHermitian( matrix_ ) );
2577 }
2579 //*************************************************************************************************
2580 
2581 
2582 
2583 
2584 //=================================================================================================
2585 //
2586 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2587 //
2588 //=================================================================================================
2589 
2590 //*************************************************************************************************
2601 template< typename MT // Type of the adapted sparse matrix
2602  , bool SO > // Storage order of the adapted sparse matrix
2603 template< typename Other > // Data type of the foreign expression
2604 inline bool HermitianMatrix<MT,SO,false>::canAlias( const Other* alias ) const noexcept
2605 {
2606  return matrix_.canAlias( alias );
2607 }
2609 //*************************************************************************************************
2610 
2611 
2612 //*************************************************************************************************
2623 template< typename MT // Type of the adapted sparse matrix
2624  , bool SO > // Storage order of the adapted sparse matrix
2625 template< typename Other > // Data type of the foreign expression
2626 inline bool HermitianMatrix<MT,SO,false>::isAliased( const Other* alias ) const noexcept
2627 {
2628  return matrix_.isAliased( alias );
2629 }
2631 //*************************************************************************************************
2632 
2633 
2634 //*************************************************************************************************
2645 template< typename MT // Type of the adapted sparse matrix
2646  , bool SO > // Storage order of the adapted sparse matrix
2647 inline bool HermitianMatrix<MT,SO,false>::canSMPAssign() const noexcept
2648 {
2649  return matrix_.canSMPAssign();
2650 }
2652 //*************************************************************************************************
2653 
2654 
2655 
2656 
2657 //=================================================================================================
2658 //
2659 // CONSTRUCTION FUNCTIONS
2660 //
2661 //=================================================================================================
2662 
2663 //*************************************************************************************************
2665 template< typename MT // Type of the adapted dense matrix
2666  , bool SO > // Storage order of the adapted dense matrix
2667 template< typename MT2 // Type of the foreign matrix
2668  , bool SO2 // Storage order of the foreign matrix
2669  , typename T > // Type of the third argument
2670 inline const MT2& HermitianMatrix<MT,SO,false>::construct( const Matrix<MT2,SO2>& m, T )
2671 {
2672  return ~m;
2673 }
2675 //*************************************************************************************************
2676 
2677 
2678 //*************************************************************************************************
2680 template< typename MT // Type of the adapted dense matrix
2681  , bool SO > // Storage order of the adapted dense matrix
2682 template< typename MT2 > // Type of the foreign matrix
2683 inline TransExprTrait_<MT2>
2684  HermitianMatrix<MT,SO,false>::construct( const Matrix<MT2,!SO>& m, TrueType )
2685 {
2686  return trans( ~m );
2687 }
2689 //*************************************************************************************************
2690 
2691 } // namespace blaze
2692 
2693 #endif
bool isReal(const DiagonalProxy< MT > &proxy)
Returns whether the matrix element represents a real number.
Definition: DiagonalProxy.h:622
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Constraint on the data type.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3079
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:356
Header file for basic type definitions.
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.In case the given data type T is not a dense or sparse matrix type and in...
Definition: StorageOrder.h:63
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1411
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3078
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:198
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
Constraint on the data type.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
BLAZE_ALWAYS_INLINE void shrinkToFit(Matrix< MT, SO > &matrix)
Requesting the removal of unused capacity.
Definition: Matrix.h:609
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:5845
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3080
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:661
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3085
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:79
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is diagonal.
Definition: DenseMatrix.h:1584
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:394
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:731
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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3086
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1393
Constraint on the data type.
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:308
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:242
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:112
Header file for the DisableIf class template.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3084
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5924
Compile time assertion.
bool isIntact(const CompressedMatrix< Type, SO > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:5907
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3077
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3081
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the Columns type trait.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
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:340
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UPPER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a upper triangular matrix type...
Definition: Upper.h:81
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:548
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:264
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Header file for the implementation of the base template of the HeritianMatrix.
Header file for all forward declarations for expression class templates.
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:580
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Constraint on the data type.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_LOWER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower triangular matrix type...
Definition: Lower.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:778
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:270
Header file for the TransExprTrait class template.
Constraint on the data type.
Constraint on the data type.
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:324
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:790
#define BLAZE_CONSTRAINT_MUST_BE_RESIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not resizable, i.e. does not have a &#39;res...
Definition: Resizable.h:61
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3083
#define BLAZE_CONSTRAINT_MUST_NOT_BE_EXPRESSION_TYPE(T)
Constraint on the data type.In case the given data type T is an expression (i.e. a type derived from ...
Definition: Expression.h:81
Header file for the HermitianProxy class.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
Header file for the IsComplex type trait.
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type, a compilation error is created.
Definition: Hermitian.h:79
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1321
#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:742
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:635