Blaze  3.6
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>
61 #include <blaze/math/Exception.h>
65 #include <blaze/math/shims/Clear.h>
75 #include <blaze/util/Assert.h>
81 #include <blaze/util/DisableIf.h>
82 #include <blaze/util/EnableIf.h>
84 #include <blaze/util/MaybeUnused.h>
86 #include <blaze/util/Types.h>
90 
91 
92 namespace blaze {
93 
94 //=================================================================================================
95 //
96 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES
97 //
98 //=================================================================================================
99 
100 //*************************************************************************************************
108 template< typename MT // Type of the adapted sparse matrix
109  , bool SO > // Storage order of the adapted sparse matrix
110 class HermitianMatrix<MT,SO,false>
111  : public SparseMatrix< HermitianMatrix<MT,SO,false>, SO >
112 {
113  private:
114  //**Type definitions****************************************************************************
115  using OT = OppositeType_t<MT>;
116  using TT = TransposeType_t<MT>;
117  using ET = ElementType_t<MT>;
118  //**********************************************************************************************
119 
120  public:
121  //**Type definitions****************************************************************************
122  using This = HermitianMatrix<MT,SO,false>;
123  using BaseType = SparseMatrix<This,SO>;
124  using ResultType = This;
125  using OppositeType = HermitianMatrix<OT,!SO,false>;
126  using TransposeType = HermitianMatrix<TT,!SO,false>;
127  using ElementType = ET;
128  using ReturnType = ReturnType_t<MT>;
129  using CompositeType = const This&;
130  using Reference = HermitianProxy<MT>;
131  using ConstReference = ConstReference_t<MT>;
132  using ConstIterator = ConstIterator_t<MT>;
133  //**********************************************************************************************
134 
135  //**Rebind struct definition********************************************************************
138  template< typename NewType > // Data type of the other matrix
139  struct Rebind {
141  using Other = HermitianMatrix< typename MT::template Rebind<NewType>::Other >;
142  };
143  //**********************************************************************************************
144 
145  //**Resize struct definition********************************************************************
148  template< size_t NewM // Number of rows of the other matrix
149  , size_t NewN > // Number of columns of the other matrix
150  struct Resize {
152  using Other = HermitianMatrix< typename MT::template Resize<NewM,NewN>::Other >;
153  };
154  //**********************************************************************************************
155 
156  //**Iterator class definition*******************************************************************
159  class Iterator
160  {
161  public:
162  //**Type definitions*************************************************************************
163  using IteratorType = Iterator_t<MT>;
164 
165  using IteratorCategory = std::forward_iterator_tag;
166  using ValueType = HermitianElement<MT>;
167  using PointerType = ValueType;
168  using ReferenceType = ValueType;
169  using DifferenceType = ptrdiff_t;
170 
171  // STL iterator requirements
172  using iterator_category = IteratorCategory;
173  using value_type = ValueType;
174  using pointer = PointerType;
175  using reference = ReferenceType;
176  using difference_type = DifferenceType;
177  //*******************************************************************************************
178 
179  //**Default constructor**********************************************************************
182  inline Iterator()
183  : pos_ () // Iterator to the current sparse Hermitian matrix element
184  , matrix_( nullptr ) // The sparse matrix containing the iterator
185  , index_ ( 0UL ) // The row/column index of the iterator
186  {}
187  //*******************************************************************************************
188 
189  //**Constructor******************************************************************************
196  inline Iterator( IteratorType pos, MT& matrix, size_t index )
197  : pos_ ( pos ) // Iterator to the current sparse Hermitian matrix element
198  , matrix_( &matrix ) // The sparse matrix containing the iterator
199  , index_ ( index ) // The row/column index of the iterator
200  {}
201  //*******************************************************************************************
202 
203  //**Prefix increment operator****************************************************************
208  inline Iterator& operator++() {
209  ++pos_;
210  return *this;
211  }
212  //*******************************************************************************************
213 
214  //**Postfix increment operator***************************************************************
219  inline const Iterator operator++( int ) {
220  const Iterator tmp( *this );
221  ++(*this);
222  return tmp;
223  }
224  //*******************************************************************************************
225 
226  //**Element access operator******************************************************************
231  inline ReferenceType operator*() const {
232  return ReferenceType( pos_, matrix_, index_ );
233  }
234  //*******************************************************************************************
235 
236  //**Element access operator******************************************************************
241  inline PointerType operator->() const {
242  return PointerType( pos_, matrix_, index_ );
243  }
244  //*******************************************************************************************
245 
246  //**Conversion operator**********************************************************************
251  inline operator ConstIterator() const {
252  return pos_;
253  }
254  //*******************************************************************************************
255 
256  //**Equality operator************************************************************************
262  inline bool operator==( const Iterator& rhs ) const {
263  return pos_ == rhs.pos_;
264  }
265  //*******************************************************************************************
266 
267  //**Inequality operator**********************************************************************
273  inline bool operator!=( const Iterator& rhs ) const {
274  return !( *this == rhs );
275  }
276  //*******************************************************************************************
277 
278  //**Subtraction operator*********************************************************************
284  inline DifferenceType operator-( const Iterator& rhs ) const {
285  return pos_ - rhs.pos_;
286  }
287  //*******************************************************************************************
288 
289  //**Base function****************************************************************************
294  inline IteratorType base() const {
295  return pos_;
296  }
297  //*******************************************************************************************
298 
299  private:
300  //**Member variables*************************************************************************
301  IteratorType pos_;
302  MT* matrix_;
303  size_t index_;
304  //*******************************************************************************************
305  };
306  //**********************************************************************************************
307 
308  //**Compilation flags***************************************************************************
310  static constexpr bool smpAssignable = false;
311  //**********************************************************************************************
312 
313  //**Constructors********************************************************************************
316  explicit inline HermitianMatrix();
317  explicit inline HermitianMatrix( size_t n );
318  explicit inline HermitianMatrix( size_t n, size_t nonzeros );
319  explicit inline HermitianMatrix( size_t n, const std::vector<size_t>& nonzeros );
320  inline HermitianMatrix( initializer_list< initializer_list<ElementType> > list );
321 
322  inline HermitianMatrix( const HermitianMatrix& m );
323  inline HermitianMatrix( HermitianMatrix&& m ) noexcept;
324 
325  template< typename MT2, bool SO2 >
326  inline HermitianMatrix( const Matrix<MT2,SO2>& m );
328  //**********************************************************************************************
329 
330  //**Destructor**********************************************************************************
333  ~HermitianMatrix() = default;
335  //**********************************************************************************************
336 
337  //**Data access functions***********************************************************************
340  inline Reference operator()( size_t i, size_t j );
341  inline ConstReference operator()( size_t i, size_t j ) const;
342  inline Reference at( size_t i, size_t j );
343  inline ConstReference at( size_t i, size_t j ) const;
344  inline Iterator begin ( size_t i );
345  inline ConstIterator begin ( size_t i ) const;
346  inline ConstIterator cbegin( size_t i ) const;
347  inline Iterator end ( size_t i );
348  inline ConstIterator end ( size_t i ) const;
349  inline ConstIterator cend ( size_t i ) const;
351  //**********************************************************************************************
352 
353  //**Assignment operators************************************************************************
356  inline HermitianMatrix& operator=( initializer_list< initializer_list<ElementType> > list );
357 
358  inline HermitianMatrix& operator=( const HermitianMatrix& rhs );
359  inline HermitianMatrix& operator=( HermitianMatrix&& rhs ) noexcept;
360 
361  template< typename MT2, bool SO2 >
362  inline auto operator=( const Matrix<MT2,SO2>& rhs )
363  -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
364 
365  template< typename MT2, bool SO2 >
366  inline auto operator=( const Matrix<MT2,SO2>& rhs )
367  -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
368 
369  template< typename MT2 >
370  inline auto operator=( const Matrix<MT2,!SO>& rhs )
371  -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >;
372 
373  template< typename MT2, bool SO2 >
374  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
375  -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
376 
377  template< typename MT2, bool SO2 >
378  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
379  -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
380 
381  template< typename MT2 >
382  inline auto operator+=( const Matrix<MT2,!SO>& rhs )
383  -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >;
384 
385  template< typename MT2, bool SO2 >
386  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
387  -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
388 
389  template< typename MT2, bool SO2 >
390  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
391  -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
392 
393  template< typename MT2 >
394  inline auto operator-=( const Matrix<MT2,!SO>& rhs )
395  -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >;
396 
397  template< typename MT2, bool SO2 >
398  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
399  -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
400 
401  template< typename MT2, bool SO2 >
402  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
403  -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
404 
405  template< typename MT2 >
406  inline auto operator%=( const Matrix<MT2,!SO>& rhs )
407  -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >;
408 
409  template< typename ST >
410  inline auto operator*=( ST rhs ) -> EnableIf_t< IsNumeric_v<ST>, HermitianMatrix& >;
411 
412  template< typename ST >
413  inline auto operator/=( ST rhs ) -> EnableIf_t< IsNumeric_v<ST>, HermitianMatrix& >;
415  //**********************************************************************************************
416 
417  //**Utility functions***************************************************************************
420  inline size_t rows() const noexcept;
421  inline size_t columns() const noexcept;
422  inline size_t capacity() const noexcept;
423  inline size_t capacity( size_t i ) const noexcept;
424  inline size_t nonZeros() const;
425  inline size_t nonZeros( size_t i ) const;
426  inline void reset();
427  inline void reset( size_t i );
428  inline void clear();
429  inline void resize ( size_t n, bool preserve=true );
430  inline void reserve( size_t nonzeros );
431  inline void reserve( size_t i, size_t nonzeros );
432  inline void trim();
433  inline void trim( size_t i );
434  inline void shrinkToFit();
435  inline void swap( HermitianMatrix& m ) noexcept;
437  //**********************************************************************************************
438 
439  //**Insertion functions*************************************************************************
442  inline Iterator set ( size_t i, size_t j, const ElementType& value );
443  inline Iterator insert ( size_t i, size_t j, const ElementType& value );
444  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
445  inline void finalize( size_t i );
447  //**********************************************************************************************
448 
449  //**Erase functions*****************************************************************************
452  inline void erase( size_t i, size_t j );
453  inline Iterator erase( size_t i, Iterator pos );
454  inline Iterator erase( size_t i, Iterator first, Iterator last );
455 
456  template< typename Pred >
457  inline void erase( Pred predicate );
458 
459  template< typename Pred >
460  inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
462  //**********************************************************************************************
463 
464  //**Lookup functions****************************************************************************
467  inline Iterator find ( size_t i, size_t j );
468  inline ConstIterator find ( size_t i, size_t j ) const;
469  inline Iterator lowerBound( size_t i, size_t j );
470  inline ConstIterator lowerBound( size_t i, size_t j ) const;
471  inline Iterator upperBound( size_t i, size_t j );
472  inline ConstIterator upperBound( size_t i, size_t j ) const;
474  //**********************************************************************************************
475 
476  //**Numeric functions***************************************************************************
479  inline HermitianMatrix& transpose();
480  inline HermitianMatrix& ctranspose();
481 
482  template< typename Other > inline HermitianMatrix& scale( const Other& scalar );
484  //**********************************************************************************************
485 
486  //**Debugging functions*************************************************************************
489  inline bool isIntact() const noexcept;
491  //**********************************************************************************************
492 
493  //**Expression template evaluation functions****************************************************
496  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
497  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
498 
499  inline bool canSMPAssign() const noexcept;
501  //**********************************************************************************************
502 
503  private:
504  //**Construction functions**********************************************************************
507  template< typename MT2, bool SO2, typename T >
508  inline decltype(auto) construct( const Matrix<MT2,SO2>& m, T );
509 
510  template< typename MT2 >
511  inline decltype(auto) construct( const Matrix<MT2,!SO>& m, TrueType );
513  //**********************************************************************************************
514 
515  //**Member variables****************************************************************************
518  MT matrix_;
519 
520  //**********************************************************************************************
521 
522  //**Friend declarations*************************************************************************
523  template< bool RF, typename MT2, bool SO2, bool DF2 >
524  friend bool isDefault( const HermitianMatrix<MT2,SO2,DF2>& m );
525  //**********************************************************************************************
526 
527  //**Compile time checks*************************************************************************
543  BLAZE_STATIC_ASSERT( ( Size_v<MT,0UL> == Size_v<MT,1UL> ) );
544  //**********************************************************************************************
545 };
547 //*************************************************************************************************
548 
549 
550 
551 
552 //=================================================================================================
553 //
554 // CONSTRUCTORS
555 //
556 //=================================================================================================
557 
558 //*************************************************************************************************
562 template< typename MT // Type of the adapted sparse matrix
563  , bool SO > // Storage order of the adapted sparse matrix
564 inline HermitianMatrix<MT,SO,false>::HermitianMatrix()
565  : matrix_() // The adapted sparse matrix
566 {
567  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
568 }
570 //*************************************************************************************************
571 
572 
573 //*************************************************************************************************
581 template< typename MT // Type of the adapted sparse matrix
582  , bool SO > // Storage order of the adapted sparse matrix
583 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n )
584  : matrix_( n, n ) // The adapted sparse matrix
585 {
587 
588  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
589 }
591 //*************************************************************************************************
592 
593 
594 //*************************************************************************************************
603 template< typename MT // Type of the adapted sparse matrix
604  , bool SO > // Storage order of the adapted sparse matrix
605 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n, size_t nonzeros )
606  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
607 {
609 
610  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
611 }
613 //*************************************************************************************************
614 
615 
616 //*************************************************************************************************
627 template< typename MT // Type of the adapted sparse matrix
628  , bool SO > // Storage order of the adapted sparse matrix
629 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n, const std::vector<size_t>& nonzeros )
630  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
631 {
633 
634  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
635 }
637 //*************************************************************************************************
638 
639 
640 //*************************************************************************************************
667 template< typename MT // Type of the adapted sparse matrix
668  , bool SO > // Storage order of the adapted sparse matrix
669 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( initializer_list< initializer_list<ElementType> > list )
670  : matrix_( list ) // The adapted sparse matrix
671 {
672  if( !isHermitian( matrix_ ) ) {
673  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of Hermitian matrix" );
674  }
675 
676  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
677 }
679 //*************************************************************************************************
680 
681 
682 //*************************************************************************************************
688 template< typename MT // Type of the adapted sparse matrix
689  , bool SO > // Storage order of the adapted sparse matrix
690 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( const HermitianMatrix& m )
691  : matrix_( m.matrix_ ) // The adapted sparse matrix
692 {
693  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
694  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
695 }
697 //*************************************************************************************************
698 
699 
700 //*************************************************************************************************
706 template< typename MT // Type of the adapted sparse matrix
707  , bool SO > // Storage order of the adapted sparse matrix
708 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( HermitianMatrix&& m ) noexcept
709  : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
710 {
711  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
712  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
713 }
715 //*************************************************************************************************
716 
717 
718 //*************************************************************************************************
728 template< typename MT // Type of the adapted sparse matrix
729  , bool SO > // Storage order of the adapted sparse matrix
730 template< typename MT2 // Type of the foreign matrix
731  , bool SO2 > // Storage order of the foreign matrix
732 inline HermitianMatrix<MT,SO,false>::HermitianMatrix( const Matrix<MT2,SO2>& m )
733  : matrix_( construct( m, typename IsBuiltin< ElementType_t<MT2> >::Type() ) ) // The adapted sparse matrix
734 {
735  if( !IsHermitian_v<MT2> && !isHermitian( matrix_ ) ) {
736  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of Hermitian matrix" );
737  }
738 }
740 //*************************************************************************************************
741 
742 
743 
744 
745 //=================================================================================================
746 //
747 // DATA ACCESS FUNCTIONS
748 //
749 //=================================================================================================
750 
751 //*************************************************************************************************
767 template< typename MT // Type of the adapted sparse matrix
768  , bool SO > // Storage order of the adapted sparse matrix
769 inline typename HermitianMatrix<MT,SO,false>::Reference
770  HermitianMatrix<MT,SO,false>::operator()( size_t i, size_t j )
771 {
772  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
773  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
774 
775  return Reference( matrix_, i, j );
776 }
778 //*************************************************************************************************
779 
780 
781 //*************************************************************************************************
797 template< typename MT // Type of the adapted sparse matrix
798  , bool SO > // Storage order of the adapted sparse matrix
799 inline typename HermitianMatrix<MT,SO,false>::ConstReference
800  HermitianMatrix<MT,SO,false>::operator()( size_t i, size_t j ) const
801 {
802  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
803  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
804 
805  return matrix_(i,j);
806 }
808 //*************************************************************************************************
809 
810 
811 //*************************************************************************************************
828 template< typename MT // Type of the adapted sparse matrix
829  , bool SO > // Storage order of the adapted sparse matrix
830 inline typename HermitianMatrix<MT,SO,false>::Reference
831  HermitianMatrix<MT,SO,false>::at( size_t i, size_t j )
832 {
833  if( i >= rows() ) {
834  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
835  }
836  if( j >= columns() ) {
837  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
838  }
839  return (*this)(i,j);
840 }
842 //*************************************************************************************************
843 
844 
845 //*************************************************************************************************
862 template< typename MT // Type of the adapted sparse matrix
863  , bool SO > // Storage order of the adapted sparse matrix
864 inline typename HermitianMatrix<MT,SO,false>::ConstReference
865  HermitianMatrix<MT,SO,false>::at( size_t i, size_t j ) const
866 {
867  if( i >= rows() ) {
868  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
869  }
870  if( j >= columns() ) {
871  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
872  }
873  return (*this)(i,j);
874 }
876 //*************************************************************************************************
877 
878 
879 //*************************************************************************************************
891 template< typename MT // Type of the adapted sparse matrix
892  , bool SO > // Storage order of the adapted sparse matrix
893 inline typename HermitianMatrix<MT,SO,false>::Iterator
895 {
896  return Iterator( matrix_.begin(i), matrix_, i );
897 }
899 //*************************************************************************************************
900 
901 
902 //*************************************************************************************************
914 template< typename MT // Type of the adapted sparse matrix
915  , bool SO > // Storage order of the adapted sparse matrix
916 inline typename HermitianMatrix<MT,SO,false>::ConstIterator
917  HermitianMatrix<MT,SO,false>::begin( size_t i ) const
918 {
919  return matrix_.begin(i);
920 }
922 //*************************************************************************************************
923 
924 
925 //*************************************************************************************************
937 template< typename MT // Type of the adapted sparse matrix
938  , bool SO > // Storage order of the adapted sparse matrix
939 inline typename HermitianMatrix<MT,SO,false>::ConstIterator
940  HermitianMatrix<MT,SO,false>::cbegin( size_t i ) const
941 {
942  return matrix_.cbegin(i);
943 }
945 //*************************************************************************************************
946 
947 
948 //*************************************************************************************************
960 template< typename MT // Type of the adapted sparse matrix
961  , bool SO > // Storage order of the adapted sparse matrix
962 inline typename HermitianMatrix<MT,SO,false>::Iterator
964 {
965  return Iterator( matrix_.end(i), matrix_, i );
966 }
968 //*************************************************************************************************
969 
970 
971 //*************************************************************************************************
983 template< typename MT // Type of the adapted sparse matrix
984  , bool SO > // Storage order of the adapted sparse matrix
985 inline typename HermitianMatrix<MT,SO,false>::ConstIterator
986  HermitianMatrix<MT,SO,false>::end( size_t i ) const
987 {
988  return matrix_.end(i);
989 }
991 //*************************************************************************************************
992 
993 
994 //*************************************************************************************************
1006 template< typename MT // Type of the adapted sparse matrix
1007  , bool SO > // Storage order of the adapted sparse matrix
1008 inline typename HermitianMatrix<MT,SO,false>::ConstIterator
1009  HermitianMatrix<MT,SO,false>::cend( size_t i ) const
1010 {
1011  return matrix_.cend(i);
1012 }
1014 //*************************************************************************************************
1015 
1016 
1017 
1018 
1019 //=================================================================================================
1020 //
1021 // ASSIGNMENT OPERATORS
1022 //
1023 //=================================================================================================
1024 
1025 //*************************************************************************************************
1052 template< typename MT // Type of the adapted sparse matrix
1053  , bool SO > // Storage order of the adapted sparse matrix
1054 inline HermitianMatrix<MT,SO,false>&
1055  HermitianMatrix<MT,SO,false>::operator=( initializer_list< initializer_list<ElementType> > list )
1056 {
1057  const InitializerMatrix<ElementType> tmp( list, list.size() );
1058 
1059  if( !isHermitian( tmp ) ) {
1060  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1061  }
1062 
1063  matrix_ = list;
1064 
1065  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1066  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1067 
1068  return *this;
1069 }
1071 //*************************************************************************************************
1072 
1073 
1074 //*************************************************************************************************
1084 template< typename MT // Type of the adapted sparse matrix
1085  , bool SO > // Storage order of the adapted sparse matrix
1086 inline HermitianMatrix<MT,SO,false>&
1087  HermitianMatrix<MT,SO,false>::operator=( const HermitianMatrix& rhs )
1088 {
1089  matrix_ = rhs.matrix_;
1090 
1091  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1092  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1093 
1094  return *this;
1095 }
1097 //*************************************************************************************************
1098 
1099 
1100 //*************************************************************************************************
1107 template< typename MT // Type of the adapted sparse matrix
1108  , bool SO > // Storage order of the adapted sparse matrix
1109 inline HermitianMatrix<MT,SO,false>&
1110  HermitianMatrix<MT,SO,false>::operator=( HermitianMatrix&& rhs ) noexcept
1111 {
1112  matrix_ = std::move( rhs.matrix_ );
1113 
1114  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1115  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1116 
1117  return *this;
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 auto HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1141  -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1142 {
1143  if( !IsHermitian_v<MT2> && !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 auto HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1176  -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1177 {
1178  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1179  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1180  }
1181 
1182  if( IsHermitian_v<MT2> ) {
1183  matrix_ = ~rhs;
1184  }
1185  else {
1186  MT tmp( ~rhs );
1187 
1188  if( !isHermitian( tmp ) ) {
1189  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1190  }
1191 
1192  matrix_ = std::move( 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 //*************************************************************************************************
1217 template< typename MT // Type of the adapted sparse matrix
1218  , bool SO > // Storage order of the adapted sparse matrix
1219 template< typename MT2 > // Type of the right-hand side matrix
1220 inline auto HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,!SO>& rhs )
1221  -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >
1222 {
1223  return this->operator=( trans( ~rhs ) );
1224 }
1226 //*************************************************************************************************
1227 
1228 
1229 //*************************************************************************************************
1242 template< typename MT // Type of the adapted sparse matrix
1243  , bool SO > // Storage order of the adapted sparse matrix
1244 template< typename MT2 // Type of the right-hand side matrix
1245  , bool SO2 > // Storage order of the right-hand side matrix
1246 inline auto HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1247  -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1248 {
1249  if( !IsHermitian_v<MT2> && !isHermitian( ~rhs ) ) {
1250  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1251  }
1252 
1253  matrix_ += ~rhs;
1254 
1255  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1256  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1257 
1258  return *this;
1259 }
1261 //*************************************************************************************************
1262 
1263 
1264 //*************************************************************************************************
1277 template< typename MT // Type of the adapted sparse matrix
1278  , bool SO > // Storage order of the adapted sparse matrix
1279 template< typename MT2 // Type of the right-hand side matrix
1280  , bool SO2 > // Storage order of the right-hand side matrix
1281 inline auto HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1282  -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1283 {
1284  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1285  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1286  }
1287 
1288  if( IsHermitian_v<MT2> ) {
1289  matrix_ += ~rhs;
1290  }
1291  else {
1292  const ResultType_t<MT2> tmp( ~rhs );
1293 
1294  if( !isHermitian( tmp ) ) {
1295  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1296  }
1297 
1298  matrix_ += tmp;
1299  }
1300 
1301  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1302  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1303 
1304  return *this;
1305 }
1307 //*************************************************************************************************
1308 
1309 
1310 //*************************************************************************************************
1324 template< typename MT // Type of the adapted sparse matrix
1325  , bool SO > // Storage order of the adapted sparse matrix
1326 template< typename MT2 > // Type of the right-hand side matrix
1327 inline auto HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,!SO>& rhs )
1328  -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >
1329 {
1330  return this->operator+=( trans( ~rhs ) );
1331 }
1333 //*************************************************************************************************
1334 
1335 
1336 //*************************************************************************************************
1349 template< typename MT // Type of the adapted sparse matrix
1350  , bool SO > // Storage order of the adapted sparse matrix
1351 template< typename MT2 // Type of the right-hand side matrix
1352  , bool SO2 > // Storage order of the right-hand side matrix
1353 inline auto HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1354  -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1355 {
1356  if( !IsHermitian_v<MT2> && !isHermitian( ~rhs ) ) {
1357  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1358  }
1359 
1360  matrix_ -= ~rhs;
1361 
1362  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1363  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1364 
1365  return *this;
1366 }
1368 //*************************************************************************************************
1369 
1370 
1371 //*************************************************************************************************
1384 template< typename MT // Type of the adapted sparse matrix
1385  , bool SO > // Storage order of the adapted sparse matrix
1386 template< typename MT2 // Type of the right-hand side matrix
1387  , bool SO2 > // Storage order of the right-hand side matrix
1388 inline auto HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1389  -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1390 {
1391  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1392  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1393  }
1394 
1395  if( IsHermitian_v<MT2> ) {
1396  matrix_ -= ~rhs;
1397  }
1398  else {
1399  const ResultType_t<MT2> tmp( ~rhs );
1400 
1401  if( !isHermitian( tmp ) ) {
1402  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1403  }
1404 
1405  matrix_ -= tmp;
1406  }
1407 
1408  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1409  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1410 
1411  return *this;
1412 }
1414 //*************************************************************************************************
1415 
1416 
1417 //*************************************************************************************************
1431 template< typename MT // Type of the adapted sparse matrix
1432  , bool SO > // Storage order of the adapted sparse matrix
1433 template< typename MT2 > // Type of the right-hand side matrix
1434 inline auto HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,!SO>& rhs )
1435  -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >
1436 {
1437  return this->operator-=( trans( ~rhs ) );
1438 }
1440 //*************************************************************************************************
1441 
1442 
1443 //*************************************************************************************************
1457 template< typename MT // Type of the adapted sparse matrix
1458  , bool SO > // Storage order of the adapted sparse matrix
1459 template< typename MT2 // Type of the right-hand side matrix
1460  , bool SO2 > // Storage order of the right-hand side matrix
1461 inline auto HermitianMatrix<MT,SO,false>::operator%=( const Matrix<MT2,SO2>& rhs )
1462  -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1463 {
1464  if( !IsHermitian_v<MT2> && !isHermitian( ~rhs ) ) {
1465  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1466  }
1467 
1468  matrix_ %= ~rhs;
1469 
1470  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1471  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1472 
1473  return *this;
1474 }
1476 //*************************************************************************************************
1477 
1478 
1479 //*************************************************************************************************
1493 template< typename MT // Type of the adapted sparse matrix
1494  , bool SO > // Storage order of the adapted sparse matrix
1495 template< typename MT2 // Type of the right-hand side matrix
1496  , bool SO2 > // Storage order of the right-hand side matrix
1497 inline auto HermitianMatrix<MT,SO,false>::operator%=( const Matrix<MT2,SO2>& rhs )
1498  -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1499 {
1500  if( !IsSquare_v<MT2> && !isSquare( ~rhs ) ) {
1501  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1502  }
1503 
1504  if( IsHermitian_v<MT2> ) {
1505  matrix_ %= ~rhs;
1506  }
1507  else {
1508  const ResultType_t<MT2> tmp( ~rhs );
1509 
1510  if( !isHermitian( tmp ) ) {
1511  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1512  }
1513 
1514  matrix_ %= tmp;
1515  }
1516 
1517  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1518  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1519 
1520  return *this;
1521 }
1523 //*************************************************************************************************
1524 
1525 
1526 //*************************************************************************************************
1540 template< typename MT // Type of the adapted sparse matrix
1541  , bool SO > // Storage order of the adapted sparse matrix
1542 template< typename MT2 > // Type of the right-hand side matrix
1543 inline auto HermitianMatrix<MT,SO,false>::operator%=( const Matrix<MT2,!SO>& rhs )
1544  -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >
1545 {
1546  return this->operator%=( trans( ~rhs ) );
1547 }
1549 //*************************************************************************************************
1550 
1551 
1552 //*************************************************************************************************
1560 template< typename MT // Type of the adapted sparse matrix
1561  , bool SO > // Storage order of the adapted sparse matrix
1562 template< typename ST > // Data type of the right-hand side scalar
1563 inline auto HermitianMatrix<MT,SO,false>::operator*=( ST rhs )
1564  -> EnableIf_t< IsNumeric_v<ST>, HermitianMatrix& >
1565 {
1566  matrix_ *= rhs;
1567  return *this;
1568 }
1569 //*************************************************************************************************
1570 
1571 
1572 //*************************************************************************************************
1580 template< typename MT // Type of the adapted sparse matrix
1581  , bool SO > // Storage order of the adapted sparse matrix
1582 template< typename ST > // Data type of the right-hand side scalar
1583 inline auto HermitianMatrix<MT,SO,false>::operator/=( ST rhs )
1584  -> EnableIf_t< IsNumeric_v<ST>, HermitianMatrix& >
1585 {
1586  BLAZE_USER_ASSERT( !isZero( rhs ), "Division by zero detected" );
1587 
1588  matrix_ /= rhs;
1589  return *this;
1590 }
1592 //*************************************************************************************************
1593 
1594 
1595 
1596 
1597 //=================================================================================================
1598 //
1599 // UTILITY FUNCTIONS
1600 //
1601 //=================================================================================================
1602 
1603 //*************************************************************************************************
1609 template< typename MT // Type of the adapted sparse matrix
1610  , bool SO > // Storage order of the adapted sparse matrix
1611 inline size_t HermitianMatrix<MT,SO,false>::rows() const noexcept
1612 {
1613  return matrix_.rows();
1614 }
1616 //*************************************************************************************************
1617 
1618 
1619 //*************************************************************************************************
1625 template< typename MT // Type of the adapted sparse matrix
1626  , bool SO > // Storage order of the adapted sparse matrix
1627 inline size_t HermitianMatrix<MT,SO,false>::columns() const noexcept
1628 {
1629  return matrix_.columns();
1630 }
1632 //*************************************************************************************************
1633 
1634 
1635 //*************************************************************************************************
1641 template< typename MT // Type of the adapted sparse matrix
1642  , bool SO > // Storage order of the adapted sparse matrix
1643 inline size_t HermitianMatrix<MT,SO,false>::capacity() const noexcept
1644 {
1645  return matrix_.capacity();
1646 }
1648 //*************************************************************************************************
1649 
1650 
1651 //*************************************************************************************************
1662 template< typename MT // Type of the adapted sparse matrix
1663  , bool SO > // Storage order of the adapted sparse matrix
1664 inline size_t HermitianMatrix<MT,SO,false>::capacity( size_t i ) const noexcept
1665 {
1666  return matrix_.capacity(i);
1667 }
1669 //*************************************************************************************************
1670 
1671 
1672 //*************************************************************************************************
1678 template< typename MT // Type of the adapted sparse matrix
1679  , bool SO > // Storage order of the adapted sparse matrix
1680 inline size_t HermitianMatrix<MT,SO,false>::nonZeros() const
1681 {
1682  return matrix_.nonZeros();
1683 }
1685 //*************************************************************************************************
1686 
1687 
1688 //*************************************************************************************************
1700 template< typename MT // Type of the adapted sparse matrix
1701  , bool SO > // Storage order of the adapted sparse matrix
1702 inline size_t HermitianMatrix<MT,SO,false>::nonZeros( size_t i ) const
1703 {
1704  return matrix_.nonZeros(i);
1705 }
1707 //*************************************************************************************************
1708 
1709 
1710 //*************************************************************************************************
1716 template< typename MT // Type of the adapted sparse matrix
1717  , bool SO > // Storage order of the adapted sparse matrix
1719 {
1720  matrix_.reset();
1721 }
1723 //*************************************************************************************************
1724 
1725 
1726 //*************************************************************************************************
1762 template< typename MT // Type of the adapted sparse matrix
1763  , bool SO > // Storage order of the adapted sparse matrix
1764 inline void HermitianMatrix<MT,SO,false>::reset( size_t i )
1765 {
1766  using blaze::erase;
1767 
1768  for( auto it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1769  {
1770  const size_t j( it->index() );
1771 
1772  if( i == j )
1773  continue;
1774 
1775  if( SO ) {
1776  const Iterator_t<MT> pos( matrix_.find( i, j ) );
1777  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1778  erase( matrix_, j, pos );
1779  }
1780  else {
1781  const Iterator_t<MT> pos( matrix_.find( j, i ) );
1782  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1783  erase( matrix_, j, pos );
1784  }
1785  }
1786 
1787  matrix_.reset( i );
1788 }
1790 //*************************************************************************************************
1791 
1792 
1793 //*************************************************************************************************
1801 template< typename MT // Type of the adapted sparse matrix
1802  , bool SO > // Storage order of the adapted sparse matrix
1804 {
1805  using blaze::clear;
1806 
1807  clear( matrix_ );
1808 }
1810 //*************************************************************************************************
1811 
1812 
1813 //*************************************************************************************************
1828 template< typename MT // Type of the adapted sparse matrix
1829  , bool SO > // Storage order of the adapted sparse matrix
1830 void HermitianMatrix<MT,SO,false>::resize( size_t n, bool preserve )
1831 {
1833 
1834  MAYBE_UNUSED( preserve );
1835 
1836  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1837 
1838  matrix_.resize( n, n, true );
1839 }
1841 //*************************************************************************************************
1842 
1843 
1844 //*************************************************************************************************
1855 template< typename MT // Type of the adapted sparse matrix
1856  , bool SO > // Storage order of the adapted sparse matrix
1857 inline void HermitianMatrix<MT,SO,false>::reserve( size_t nonzeros )
1858 {
1859  matrix_.reserve( nonzeros );
1860 }
1862 //*************************************************************************************************
1863 
1864 
1865 //*************************************************************************************************
1879 template< typename MT // Type of the adapted sparse matrix
1880  , bool SO > // Storage order of the adapted sparse matrix
1881 inline void HermitianMatrix<MT,SO,false>::reserve( size_t i, size_t nonzeros )
1882 {
1883  matrix_.reserve( i, nonzeros );
1884 }
1886 //*************************************************************************************************
1887 
1888 
1889 //*************************************************************************************************
1900 template< typename MT // Type of the adapted sparse matrix
1901  , bool SO > // Storage order of the adapted sparse matrix
1902 inline void HermitianMatrix<MT,SO,false>::trim()
1903 {
1904  matrix_.trim();
1905 }
1907 //*************************************************************************************************
1908 
1909 
1910 //*************************************************************************************************
1922 template< typename MT // Type of the adapted sparse matrix
1923  , bool SO > // Storage order of the adapted sparse matrix
1924 inline void HermitianMatrix<MT,SO,false>::trim( size_t i )
1925 {
1926  matrix_.trim( i );
1927 }
1929 //*************************************************************************************************
1930 
1931 
1932 //*************************************************************************************************
1942 template< typename MT // Type of the adapted sparse matrix
1943  , bool SO > // Storage order of the adapted sparse matrix
1945 {
1946  matrix_.shrinkToFit();
1947 }
1949 //*************************************************************************************************
1950 
1951 
1952 //*************************************************************************************************
1959 template< typename MT // Type of the adapted sparse matrix
1960  , bool SO > // Storage order of the adapted sparse matrix
1961 inline void HermitianMatrix<MT,SO,false>::swap( HermitianMatrix& m ) noexcept
1962 {
1963  using std::swap;
1964 
1965  swap( matrix_, m.matrix_ );
1966 }
1968 //*************************************************************************************************
1969 
1970 
1971 
1972 
1973 //=================================================================================================
1974 //
1975 // INSERTION FUNCTIONS
1976 //
1977 //=================================================================================================
1978 
1979 //*************************************************************************************************
1994 template< typename MT // Type of the adapted sparse matrix
1995  , bool SO > // Storage order of the adapted sparse matrix
1996 inline typename HermitianMatrix<MT,SO,false>::Iterator
1997  HermitianMatrix<MT,SO,false>::set( size_t i, size_t j, const ElementType& value )
1998 {
1999  const bool isDiagonal( i == j );
2000 
2001  if( IsComplex_v<ElementType> && isDiagonal && !isReal( value ) ) {
2002  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2003  }
2004 
2005  if( !isDiagonal )
2006  matrix_.set( j, i, conj( value ) );
2007  return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
2008 }
2010 //*************************************************************************************************
2011 
2012 
2013 //*************************************************************************************************
2029 template< typename MT // Type of the adapted sparse matrix
2030  , bool SO > // Storage order of the adapted sparse matrix
2031 inline typename HermitianMatrix<MT,SO,false>::Iterator
2032  HermitianMatrix<MT,SO,false>::insert( size_t i, size_t j, const ElementType& value )
2033 {
2034  const bool isDiagonal( i == j );
2035 
2036  if( IsComplex_v<ElementType> && isDiagonal && !isReal( value ) ) {
2037  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2038  }
2039 
2040  if( !isDiagonal )
2041  matrix_.insert( j, i, conj( value ) );
2042  return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
2043 }
2045 //*************************************************************************************************
2046 
2047 
2048 //*************************************************************************************************
2107 template< typename MT // Type of the adapted sparse matrix
2108  , bool SO > // Storage order of the adapted sparse matrix
2109 inline void HermitianMatrix<MT,SO,false>::append( size_t i, size_t j, const ElementType& value, bool check )
2110 {
2111  const bool isDiagonal( i == j );
2112 
2113  if( IsComplex_v<ElementType> && isDiagonal && !isReal( value ) ) {
2114  BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2115  }
2116 
2117  matrix_.append( i, j, value, check );
2118  if( !isDiagonal && ( !check || !isDefault<strict>( value ) ) )
2119  matrix_.insert( j, i, conj( value ) );
2120 }
2122 //*************************************************************************************************
2123 
2124 
2125 //*************************************************************************************************
2139 template< typename MT // Type of the adapted sparse matrix
2140  , bool SO > // Storage order of the adapted sparse matrix
2141 inline void HermitianMatrix<MT,SO,false>::finalize( size_t i )
2142 {
2143  matrix_.trim( i );
2144 }
2146 //*************************************************************************************************
2147 
2148 
2149 
2150 
2151 //=================================================================================================
2152 //
2153 // ERASE FUNCTIONS
2154 //
2155 //=================================================================================================
2156 
2157 //*************************************************************************************************
2167 template< typename MT // Type of the adapted sparse matrix
2168  , bool SO > // Storage order of the adapted sparse matrix
2169 inline void HermitianMatrix<MT,SO,false>::erase( size_t i, size_t j )
2170 {
2171  using blaze::erase;
2172 
2173  erase( matrix_, i, j );
2174  if( i != j )
2175  erase( matrix_, j, i );
2176 }
2178 //*************************************************************************************************
2179 
2180 
2181 //*************************************************************************************************
2193 template< typename MT // Type of the adapted sparse matrix
2194  , bool SO > // Storage order of the adapted sparse matrix
2195 inline typename HermitianMatrix<MT,SO,false>::Iterator
2196  HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator pos )
2197 {
2198  using blaze::erase;
2199 
2200  const Iterator_t<MT> base( pos.base() );
2201 
2202  if( base == matrix_.end( i ) )
2203  return pos;
2204 
2205  const size_t j( base->index() );
2206 
2207  if( i == j ) {
2208  BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
2209  return Iterator( erase( matrix_, i, base ), matrix_, i );
2210  }
2211 
2212  if( SO ) {
2213  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2214  erase( matrix_, j, matrix_.find( i, j ) );
2215  return Iterator( erase( matrix_, i, base ), matrix_, i );
2216  }
2217  else {
2218  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2219  erase( matrix_, j, matrix_.find( j, i ) );
2220  return Iterator( erase( matrix_, i, base ), matrix_, i );
2221  }
2222 }
2224 //*************************************************************************************************
2225 
2226 
2227 //*************************************************************************************************
2241 template< typename MT // Type of the adapted sparse matrix
2242  , bool SO > // Storage order of the adapted sparse matrix
2243 inline typename HermitianMatrix<MT,SO,false>::Iterator
2244  HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last )
2245 {
2246  using blaze::erase;
2247 
2248  for( auto it=first.base(); it!=last.base(); ++it )
2249  {
2250  const size_t j( it->index() );
2251 
2252  if( i == j )
2253  continue;
2254 
2255  if( SO ) {
2256  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2257  erase( matrix_, i, j );
2258  }
2259  else {
2260  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2261  erase( matrix_, j, i );
2262  }
2263  }
2264 
2265  return Iterator( erase( matrix_, i, first.base(), last.base() ), matrix_, i );
2266 }
2268 //*************************************************************************************************
2269 
2270 
2271 //*************************************************************************************************
2293 template< typename MT // Type of the adapted sparse matrix
2294  , bool SO > // Storage order of the adapted sparse matrix
2295 template< typename Pred > // Type of the unary predicate
2296 inline void HermitianMatrix<MT,SO,false>::erase( Pred predicate )
2297 {
2298  using blaze::erase;
2299 
2300  erase( matrix_, [predicate=predicate]( const ElementType& value ) {
2301  return predicate( value ) || predicate( conj( value ) );
2302  } );
2303 
2304  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2305 }
2307 //*************************************************************************************************
2308 
2309 
2310 //*************************************************************************************************
2338 template< typename MT // Type of the adapted sparse matrix
2339  , bool SO > // Storage order of the adapted sparse matrix
2340 template< typename Pred > // Type of the unary predicate
2341 inline void
2342  HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2343 {
2344  using blaze::erase;
2345 
2346  for( auto it=first; it!=last; ++it ) {
2347  const size_t j( it->index() );
2348  if( i != j && predicate( it->value() ) ) {
2349  if( SO )
2350  erase( matrix_, i, j );
2351  else
2352  erase( matrix_, j, i );
2353  }
2354  }
2355 
2356  erase( matrix_, i, first.base(), last.base(), predicate );
2357 
2358  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2359 }
2361 //*************************************************************************************************
2362 
2363 
2364 
2365 
2366 //=================================================================================================
2367 //
2368 // LOOKUP FUNCTIONS
2369 //
2370 //=================================================================================================
2371 
2372 //*************************************************************************************************
2388 template< typename MT // Type of the adapted sparse matrix
2389  , bool SO > // Storage order of the adapted sparse matrix
2390 inline typename HermitianMatrix<MT,SO,false>::Iterator
2391  HermitianMatrix<MT,SO,false>::find( size_t i, size_t j )
2392 {
2393  return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2394 }
2396 //*************************************************************************************************
2397 
2398 
2399 //*************************************************************************************************
2415 template< typename MT // Type of the adapted sparse matrix
2416  , bool SO > // Storage order of the adapted sparse matrix
2417 inline typename HermitianMatrix<MT,SO,false>::ConstIterator
2418  HermitianMatrix<MT,SO,false>::find( size_t i, size_t j ) const
2419 {
2420  return matrix_.find( i, j );
2421 }
2423 //*************************************************************************************************
2424 
2425 
2426 //*************************************************************************************************
2442 template< typename MT // Type of the adapted sparse matrix
2443  , bool SO > // Storage order of the adapted sparse matrix
2444 inline typename HermitianMatrix<MT,SO,false>::Iterator
2445  HermitianMatrix<MT,SO,false>::lowerBound( size_t i, size_t j )
2446 {
2447  return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2448 }
2450 //*************************************************************************************************
2451 
2452 
2453 //*************************************************************************************************
2469 template< typename MT // Type of the adapted sparse matrix
2470  , bool SO > // Storage order of the adapted sparse matrix
2471 inline typename HermitianMatrix<MT,SO,false>::ConstIterator
2472  HermitianMatrix<MT,SO,false>::lowerBound( size_t i, size_t j ) const
2473 {
2474  return matrix_.lowerBound( i, j );
2475 }
2477 //*************************************************************************************************
2478 
2479 
2480 //*************************************************************************************************
2496 template< typename MT // Type of the adapted sparse matrix
2497  , bool SO > // Storage order of the adapted sparse matrix
2498 inline typename HermitianMatrix<MT,SO,false>::Iterator
2499  HermitianMatrix<MT,SO,false>::upperBound( size_t i, size_t j )
2500 {
2501  return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2502 }
2504 //*************************************************************************************************
2505 
2506 
2507 //*************************************************************************************************
2523 template< typename MT // Type of the adapted sparse matrix
2524  , bool SO > // Storage order of the adapted sparse matrix
2525 inline typename HermitianMatrix<MT,SO,false>::ConstIterator
2526  HermitianMatrix<MT,SO,false>::upperBound( size_t i, size_t j ) const
2527 {
2528  return matrix_.upperBound( i, j );
2529 }
2531 //*************************************************************************************************
2532 
2533 
2534 
2535 
2536 //=================================================================================================
2537 //
2538 // NUMERIC FUNCTIONS
2539 //
2540 //=================================================================================================
2541 
2542 //*************************************************************************************************
2548 template< typename MT // Type of the adapted sparse matrix
2549  , bool SO > // Storage order of the adapted sparse matrix
2550 inline HermitianMatrix<MT,SO,false>& HermitianMatrix<MT,SO,false>::transpose()
2551 {
2552  if( IsComplex_v<ElementType> )
2553  matrix_.transpose();
2554  return *this;
2555 }
2557 //*************************************************************************************************
2558 
2559 
2560 //*************************************************************************************************
2566 template< typename MT // Type of the adapted sparse matrix
2567  , bool SO > // Storage order of the adapted sparse matrix
2568 inline HermitianMatrix<MT,SO,false>& HermitianMatrix<MT,SO,false>::ctranspose()
2569 {
2570  return *this;
2571 }
2573 //*************************************************************************************************
2574 
2575 
2576 //*************************************************************************************************
2594 template< typename MT // Type of the adapted sparse matrix
2595  , bool SO > // Storage order of the adapted sparse matrix
2596 template< typename Other > // Data type of the scalar value
2597 inline HermitianMatrix<MT,SO,false>&
2598  HermitianMatrix<MT,SO,false>::scale( const Other& scalar )
2599 {
2600  matrix_.scale( scalar );
2601  return *this;
2602 }
2604 //*************************************************************************************************
2605 
2606 
2607 
2608 
2609 //=================================================================================================
2610 //
2611 // DEBUGGING FUNCTIONS
2612 //
2613 //=================================================================================================
2614 
2615 //*************************************************************************************************
2625 template< typename MT // Type of the adapted sparse matrix
2626  , bool SO > // Storage order of the adapted sparse matrix
2627 inline bool HermitianMatrix<MT,SO,false>::isIntact() const noexcept
2628 {
2629  using blaze::isIntact;
2630 
2631  return ( isIntact( matrix_ ) && isHermitian( matrix_ ) );
2632 }
2634 //*************************************************************************************************
2635 
2636 
2637 
2638 
2639 //=================================================================================================
2640 //
2641 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2642 //
2643 //=================================================================================================
2644 
2645 //*************************************************************************************************
2656 template< typename MT // Type of the adapted sparse matrix
2657  , bool SO > // Storage order of the adapted sparse matrix
2658 template< typename Other > // Data type of the foreign expression
2659 inline bool HermitianMatrix<MT,SO,false>::canAlias( const Other* alias ) const noexcept
2660 {
2661  return matrix_.canAlias( alias );
2662 }
2664 //*************************************************************************************************
2665 
2666 
2667 //*************************************************************************************************
2678 template< typename MT // Type of the adapted sparse matrix
2679  , bool SO > // Storage order of the adapted sparse matrix
2680 template< typename Other > // Data type of the foreign expression
2681 inline bool HermitianMatrix<MT,SO,false>::isAliased( const Other* alias ) const noexcept
2682 {
2683  return matrix_.isAliased( alias );
2684 }
2686 //*************************************************************************************************
2687 
2688 
2689 //*************************************************************************************************
2700 template< typename MT // Type of the adapted sparse matrix
2701  , bool SO > // Storage order of the adapted sparse matrix
2702 inline bool HermitianMatrix<MT,SO,false>::canSMPAssign() const noexcept
2703 {
2704  return matrix_.canSMPAssign();
2705 }
2707 //*************************************************************************************************
2708 
2709 
2710 
2711 
2712 //=================================================================================================
2713 //
2714 // CONSTRUCTION FUNCTIONS
2715 //
2716 //=================================================================================================
2717 
2718 //*************************************************************************************************
2720 template< typename MT // Type of the adapted dense matrix
2721  , bool SO > // Storage order of the adapted dense matrix
2722 template< typename MT2 // Type of the foreign matrix
2723  , bool SO2 // Storage order of the foreign matrix
2724  , typename T > // Type of the third argument
2725 inline decltype(auto) HermitianMatrix<MT,SO,false>::construct( const Matrix<MT2,SO2>& m, T )
2726 {
2727  return ~m;
2728 }
2730 //*************************************************************************************************
2731 
2732 
2733 //*************************************************************************************************
2735 template< typename MT // Type of the adapted dense matrix
2736  , bool SO > // Storage order of the adapted dense matrix
2737 template< typename MT2 > // Type of the foreign matrix
2738 inline decltype(auto) HermitianMatrix<MT,SO,false>::construct( const Matrix<MT2,!SO>& m, TrueType )
2739 {
2740  return trans( ~m );
2741 }
2743 //*************************************************************************************************
2744 
2745 } // namespace blaze
2746 
2747 #endif
bool isReal(const DiagonalProxy< MT > &proxy)
Returns whether the matrix element represents a real number.
Definition: DiagonalProxy.h:657
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSFORMATION_TYPE(T)
Constraint on the data type.In case the given data type T is a transformation expression (i....
Definition: Transformation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type,...
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
constexpr ptrdiff_t Size_v
Auxiliary variable template for the Size type trait.The Size_v variable template provides a convenien...
Definition: Size.h:176
Constraint on the data type.
Constraint on the data type.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:750
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.In case the given data type T is not a dense or sparse matrix type and in...
Definition: StorageOrder.h:63
Header file for the isZero shim.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i....
Definition: Computation.h:81
Constraint on the data type.
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
void shrinkToFit(Matrix< MT, SO > &matrix)
Requesting the removal of unused capacity.
Definition: Matrix.h:799
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
Header file for the MAYBE_UNUSED function template.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type,...
Definition: Volatile.h:79
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the give dense matrix is diagonal.
Definition: DenseMatrix.h:2328
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: IntegralConstant.h:132
Header file for the extended initializer_list functionality.
Constraint on the data type.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:482
MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:416
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
Constraint on the data type.
Constraint on the data type.
Header file for the SparseMatrix base class.
Header file for utility functions for sparse matrices.
Header file for the IsSquare type trait.
Constraint on the data type.
bool isZero(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 0.
Definition: DiagonalProxy.h:677
Header file for the implementation of a matrix representation of an initializer list.
Header file for the DisableIf class template.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Compile time assertion.
decltype(auto) operator *(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9091
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
Constraint on the data type.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
Constraints on the storage order of matrix types.
Header file for the exception macros of the math module.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UPPER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a upper triangular matrix type,...
Definition: Upper.h:81
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:738
MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:438
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
Header file for the implementation of the base template of the HeritianMatrix.
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:615
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:558
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type,...
Definition: Symmetric.h:79
Header file for run time assertion macros.
Constraint on the data type.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_LOWER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower triangular matrix type,...
Definition: Lower.h:81
Header file for all forward declarations for expression class templates.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type,...
Definition: Reference.h:79
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:1406
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:282
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:75
Constraint on the data type.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VIEW_TYPE(T)
Constraint on the data type.In case the given data type T is a view type (i.e. a subvector,...
Definition: View.h:81
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
#define BLAZE_CONSTRAINT_MUST_BE_RESIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not resizable, i.e. does not have a 'res...
Definition: Resizable.h:61
Header file for the IsComputation type trait class.
Header file for the IsBuiltin type trait.
Header file for the HermitianProxy class.
Header file for the IntegralConstant class template.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
Header file for the IsComplex type trait.
auto operator *=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:494
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type,...
Definition: Hermitian.h:79
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1324
#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.
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:951
Constraint on the data type.
Header file for the Size type trait.
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,...
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type,...
Definition: SparseMatrix.h:61
Header file for the clear shim.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825