Blaze 3.9
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>
76#include <blaze/util/Assert.h>
81#include <blaze/util/EnableIf.h>
85#include <blaze/util/Types.h>
88
89
90namespace blaze {
91
92//=================================================================================================
93//
94// CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES
95//
96//=================================================================================================
97
98//*************************************************************************************************
106template< typename MT // Type of the adapted sparse matrix
107 , bool SO > // Storage order of the adapted sparse matrix
108class HermitianMatrix<MT,SO,false>
109 : public SparseMatrix< HermitianMatrix<MT,SO,false>, SO >
110{
111 private:
112 //**Type definitions****************************************************************************
113 using OT = OppositeType_t<MT>;
114 using TT = TransposeType_t<MT>;
115 using ET = ElementType_t<MT>;
116 //**********************************************************************************************
117
118 public:
119 //**Type definitions****************************************************************************
120 using This = HermitianMatrix<MT,SO,false>;
121 using BaseType = SparseMatrix<This,SO>;
122 using ResultType = This;
123 using OppositeType = HermitianMatrix<OT,!SO,false>;
124 using TransposeType = HermitianMatrix<TT,!SO,false>;
125 using ElementType = ET;
126 using TagType = TagType_t<MT>;
127 using ReturnType = ReturnType_t<MT>;
128 using CompositeType = const This&;
129 using Reference = HermitianProxy<MT>;
130 using ConstReference = ConstReference_t<MT>;
131 using ConstIterator = ConstIterator_t<MT>;
132 //**********************************************************************************************
133
134 //**Rebind struct definition********************************************************************
137 template< typename NewType > // Data type of the other matrix
138 struct Rebind {
140 using Other = HermitianMatrix< typename MT::template Rebind<NewType>::Other >;
141 };
142 //**********************************************************************************************
143
144 //**Resize struct definition********************************************************************
147 template< size_t NewM // Number of rows of the other matrix
148 , size_t NewN > // Number of columns of the other matrix
149 struct Resize {
151 using Other = HermitianMatrix< typename MT::template Resize<NewM,NewN>::Other >;
152 };
153 //**********************************************************************************************
154
155 //**Iterator class definition*******************************************************************
158 class Iterator
159 {
160 public:
161 //**Type definitions*************************************************************************
162 using IteratorType = Iterator_t<MT>;
163
164 using IteratorCategory = std::forward_iterator_tag;
165 using ValueType = HermitianElement<MT>;
166 using PointerType = ValueType;
167 using ReferenceType = ValueType;
168 using DifferenceType = ptrdiff_t;
169
170 // STL iterator requirements
171 using iterator_category = IteratorCategory;
172 using value_type = ValueType;
173 using pointer = PointerType;
174 using reference = ReferenceType;
175 using difference_type = DifferenceType;
176 //*******************************************************************************************
177
178 //**Default constructor**********************************************************************
181 inline Iterator()
182 : pos_ () // Iterator to the current sparse Hermitian matrix element
183 , matrix_( nullptr ) // The sparse matrix containing the iterator
184 , index_ ( 0UL ) // The row/column index of the iterator
185 {}
186 //*******************************************************************************************
187
188 //**Constructor******************************************************************************
195 inline Iterator( IteratorType pos, MT& matrix, size_t index )
196 : pos_ ( pos ) // Iterator to the current sparse Hermitian matrix element
197 , matrix_( &matrix ) // The sparse matrix containing the iterator
198 , index_ ( index ) // The row/column index of the iterator
199 {}
200 //*******************************************************************************************
201
202 //**Prefix increment operator****************************************************************
207 inline Iterator& operator++() {
208 ++pos_;
209 return *this;
210 }
211 //*******************************************************************************************
212
213 //**Postfix increment operator***************************************************************
218 inline const Iterator operator++( int ) {
219 const Iterator tmp( *this );
220 ++(*this);
221 return tmp;
222 }
223 //*******************************************************************************************
224
225 //**Element access operator******************************************************************
230 inline ReferenceType operator*() const {
231 return ReferenceType( pos_, matrix_, index_ );
232 }
233 //*******************************************************************************************
234
235 //**Element access operator******************************************************************
240 inline PointerType operator->() const {
241 return PointerType( pos_, matrix_, index_ );
242 }
243 //*******************************************************************************************
244
245 //**Conversion operator**********************************************************************
250 inline operator ConstIterator() const {
251 return pos_;
252 }
253 //*******************************************************************************************
254
255 //**Equality operator************************************************************************
261 inline bool operator==( const Iterator& rhs ) const {
262 return pos_ == rhs.pos_;
263 }
264 //*******************************************************************************************
265
266 //**Inequality operator**********************************************************************
272 inline bool operator!=( const Iterator& rhs ) const {
273 return !( *this == rhs );
274 }
275 //*******************************************************************************************
276
277 //**Subtraction operator*********************************************************************
283 inline DifferenceType operator-( const Iterator& rhs ) const {
284 return pos_ - rhs.pos_;
285 }
286 //*******************************************************************************************
287
288 //**Base function****************************************************************************
293 inline IteratorType base() const {
294 return pos_;
295 }
296 //*******************************************************************************************
297
298 private:
299 //**Member variables*************************************************************************
300 IteratorType pos_;
301 MT* matrix_;
302 size_t index_;
303 //*******************************************************************************************
304 };
305 //**********************************************************************************************
306
307 //**Compilation flags***************************************************************************
309 static constexpr bool smpAssignable = false;
310 //**********************************************************************************************
311
312 //**Constructors********************************************************************************
315 inline HermitianMatrix();
316 explicit inline HermitianMatrix( size_t n );
317 inline HermitianMatrix( size_t n, size_t nonzeros );
318 inline HermitianMatrix( size_t n, const std::vector<size_t>& nonzeros );
319 inline HermitianMatrix( initializer_list< initializer_list<ElementType> > list );
320
321 inline HermitianMatrix( const HermitianMatrix& m );
322 inline HermitianMatrix( HermitianMatrix&& m ) noexcept;
323
324 template< typename MT2, bool SO2 >
325 inline HermitianMatrix( const Matrix<MT2,SO2>& m );
327 //**********************************************************************************************
328
329 //**Destructor**********************************************************************************
332 ~HermitianMatrix() = default;
334 //**********************************************************************************************
335
336 //**Data access functions***********************************************************************
339 inline Reference operator()( size_t i, size_t j );
340 inline ConstReference operator()( size_t i, size_t j ) const;
341 inline Reference at( size_t i, size_t j );
342 inline ConstReference at( size_t i, size_t j ) const;
343 inline Iterator begin ( size_t i );
344 inline ConstIterator begin ( size_t i ) const;
345 inline ConstIterator cbegin( size_t i ) const;
346 inline Iterator end ( size_t i );
347 inline ConstIterator end ( size_t i ) const;
348 inline ConstIterator cend ( size_t i ) const;
350 //**********************************************************************************************
351
352 //**Assignment operators************************************************************************
355 inline HermitianMatrix& operator=( initializer_list< initializer_list<ElementType> > list );
356
357 inline HermitianMatrix& operator=( const HermitianMatrix& rhs );
358 inline HermitianMatrix& operator=( HermitianMatrix&& rhs ) noexcept;
359
360 template< typename MT2, bool SO2 >
361 inline auto operator=( const Matrix<MT2,SO2>& rhs )
362 -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
363
364 template< typename MT2, bool SO2 >
365 inline auto operator=( const Matrix<MT2,SO2>& rhs )
366 -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
367
368 template< typename MT2 >
369 inline auto operator=( const Matrix<MT2,!SO>& rhs )
370 -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >;
371
372 template< typename MT2, bool SO2 >
373 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
374 -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
375
376 template< typename MT2, bool SO2 >
377 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
378 -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
379
380 template< typename MT2 >
381 inline auto operator+=( const Matrix<MT2,!SO>& rhs )
382 -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >;
383
384 template< typename MT2, bool SO2 >
385 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
386 -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
387
388 template< typename MT2, bool SO2 >
389 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
390 -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
391
392 template< typename MT2 >
393 inline auto operator-=( const Matrix<MT2,!SO>& rhs )
394 -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >;
395
396 template< typename MT2, bool SO2 >
397 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
398 -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
399
400 template< typename MT2, bool SO2 >
401 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
402 -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >;
403
404 template< typename MT2 >
405 inline auto operator%=( const Matrix<MT2,!SO>& rhs )
406 -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >;
407
408 template< typename ST >
409 inline auto operator*=( ST rhs ) -> EnableIf_t< IsScalar_v<ST>, HermitianMatrix& >;
410
411 template< typename ST >
412 inline auto operator/=( ST rhs ) -> EnableIf_t< IsScalar_v<ST>, HermitianMatrix& >;
414 //**********************************************************************************************
415
416 //**Utility functions***************************************************************************
419 inline size_t rows() const noexcept;
420 inline size_t columns() const noexcept;
421 inline size_t capacity() const noexcept;
422 inline size_t capacity( size_t i ) const noexcept;
423 inline size_t nonZeros() const;
424 inline size_t nonZeros( size_t i ) const;
425 inline void reset();
426 inline void reset( size_t i );
427 inline void clear();
428 inline void resize ( size_t n, bool preserve=true );
429 inline void reserve( size_t nonzeros );
430 inline void reserve( size_t i, size_t nonzeros );
431 inline void trim();
432 inline void trim( size_t i );
433 inline void shrinkToFit();
434 inline void swap( HermitianMatrix& m ) noexcept;
436 //**********************************************************************************************
437
438 //**Insertion functions*************************************************************************
441 inline Iterator set ( size_t i, size_t j, const ElementType& value );
442 inline Iterator insert ( size_t i, size_t j, const ElementType& value );
443 inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
444 inline void finalize( size_t i );
446 //**********************************************************************************************
447
448 //**Erase functions*****************************************************************************
451 inline void erase( size_t i, size_t j );
452 inline Iterator erase( size_t i, Iterator pos );
453 inline Iterator erase( size_t i, Iterator first, Iterator last );
454
455 template< typename Pred >
456 inline void erase( Pred predicate );
457
458 template< typename Pred >
459 inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
461 //**********************************************************************************************
462
463 //**Lookup functions****************************************************************************
466 inline Iterator find ( size_t i, size_t j );
467 inline ConstIterator find ( size_t i, size_t j ) const;
468 inline Iterator lowerBound( size_t i, size_t j );
469 inline ConstIterator lowerBound( size_t i, size_t j ) const;
470 inline Iterator upperBound( size_t i, size_t j );
471 inline ConstIterator upperBound( size_t i, size_t j ) const;
473 //**********************************************************************************************
474
475 //**Numeric functions***************************************************************************
478 inline HermitianMatrix& transpose();
479 inline HermitianMatrix& ctranspose();
480
481 template< typename Other > inline HermitianMatrix& scale( const Other& scalar );
483 //**********************************************************************************************
484
485 //**Debugging functions*************************************************************************
488 inline bool isIntact() const noexcept;
490 //**********************************************************************************************
491
492 //**Expression template evaluation functions****************************************************
495 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
496 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
497
498 inline bool canSMPAssign() const noexcept;
500 //**********************************************************************************************
501
502 private:
503 //**Construction functions**********************************************************************
506 template< typename MT2, bool SO2, typename T >
507 inline decltype(auto) construct( const Matrix<MT2,SO2>& m, T );
508
509 template< typename MT2 >
510 inline decltype(auto) construct( const Matrix<MT2,!SO>& m, TrueType );
512 //**********************************************************************************************
513
514 //**Member variables****************************************************************************
517 MT matrix_;
519 //**********************************************************************************************
520
521 //**Compile time checks*************************************************************************
537 BLAZE_STATIC_ASSERT( ( Size_v<MT,0UL> == Size_v<MT,1UL> ) );
538 //**********************************************************************************************
539};
541//*************************************************************************************************
542
543
544
545
546//=================================================================================================
547//
548// CONSTRUCTORS
549//
550//=================================================================================================
551
552//*************************************************************************************************
556template< typename MT // Type of the adapted sparse matrix
557 , bool SO > // Storage order of the adapted sparse matrix
558inline HermitianMatrix<MT,SO,false>::HermitianMatrix()
559 : matrix_() // The adapted sparse matrix
560{
561 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
562}
564//*************************************************************************************************
565
566
567//*************************************************************************************************
575template< typename MT // Type of the adapted sparse matrix
576 , bool SO > // Storage order of the adapted sparse matrix
577inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n )
578 : matrix_( n, n ) // The adapted sparse matrix
579{
581
582 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
583}
585//*************************************************************************************************
586
587
588//*************************************************************************************************
597template< typename MT // Type of the adapted sparse matrix
598 , bool SO > // Storage order of the adapted sparse matrix
599inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n, size_t nonzeros )
600 : matrix_( n, n, nonzeros ) // The adapted sparse matrix
601{
603
604 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
605}
607//*************************************************************************************************
608
609
610//*************************************************************************************************
621template< typename MT // Type of the adapted sparse matrix
622 , bool SO > // Storage order of the adapted sparse matrix
623inline HermitianMatrix<MT,SO,false>::HermitianMatrix( size_t n, const std::vector<size_t>& nonzeros )
624 : matrix_( n, n, nonzeros ) // The adapted sparse matrix
625{
627
628 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
629}
631//*************************************************************************************************
632
633
634//*************************************************************************************************
661template< typename MT // Type of the adapted sparse matrix
662 , bool SO > // Storage order of the adapted sparse matrix
663inline HermitianMatrix<MT,SO,false>::HermitianMatrix( initializer_list< initializer_list<ElementType> > list )
664 : matrix_( list ) // The adapted sparse matrix
665{
666 if( !isHermitian( matrix_ ) ) {
667 BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of Hermitian matrix" );
668 }
669
670 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
671}
673//*************************************************************************************************
674
675
676//*************************************************************************************************
682template< typename MT // Type of the adapted sparse matrix
683 , bool SO > // Storage order of the adapted sparse matrix
684inline HermitianMatrix<MT,SO,false>::HermitianMatrix( const HermitianMatrix& m )
685 : matrix_( m.matrix_ ) // The adapted sparse matrix
686{
687 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
688 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
689}
691//*************************************************************************************************
692
693
694//*************************************************************************************************
700template< typename MT // Type of the adapted sparse matrix
701 , bool SO > // Storage order of the adapted sparse matrix
702inline HermitianMatrix<MT,SO,false>::HermitianMatrix( HermitianMatrix&& m ) noexcept
703 : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
704{
705 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
706 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
707}
709//*************************************************************************************************
710
711
712//*************************************************************************************************
722template< typename MT // Type of the adapted sparse matrix
723 , bool SO > // Storage order of the adapted sparse matrix
724template< typename MT2 // Type of the foreign matrix
725 , bool SO2 > // Storage order of the foreign matrix
726inline HermitianMatrix<MT,SO,false>::HermitianMatrix( const Matrix<MT2,SO2>& m )
727 : matrix_( construct( m, typename IsBuiltin< ElementType_t<MT2> >::Type() ) ) // The adapted sparse matrix
728{
729 if( !IsHermitian_v<MT2> && !isHermitian( matrix_ ) ) {
730 BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of Hermitian matrix" );
731 }
732}
734//*************************************************************************************************
735
736
737
738
739//=================================================================================================
740//
741// DATA ACCESS FUNCTIONS
742//
743//=================================================================================================
744
745//*************************************************************************************************
761template< typename MT // Type of the adapted sparse matrix
762 , bool SO > // Storage order of the adapted sparse matrix
763inline typename HermitianMatrix<MT,SO,false>::Reference
764 HermitianMatrix<MT,SO,false>::operator()( size_t i, size_t j )
765{
766 BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
767 BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
768
769 return Reference( matrix_, i, j );
770}
772//*************************************************************************************************
773
774
775//*************************************************************************************************
791template< typename MT // Type of the adapted sparse matrix
792 , bool SO > // Storage order of the adapted sparse matrix
793inline typename HermitianMatrix<MT,SO,false>::ConstReference
794 HermitianMatrix<MT,SO,false>::operator()( size_t i, size_t j ) const
795{
796 BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
797 BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
798
799 return matrix_(i,j);
800}
802//*************************************************************************************************
803
804
805//*************************************************************************************************
822template< typename MT // Type of the adapted sparse matrix
823 , bool SO > // Storage order of the adapted sparse matrix
824inline typename HermitianMatrix<MT,SO,false>::Reference
825 HermitianMatrix<MT,SO,false>::at( size_t i, size_t j )
826{
827 if( i >= rows() ) {
828 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
829 }
830 if( j >= columns() ) {
831 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
832 }
833 return (*this)(i,j);
834}
836//*************************************************************************************************
837
838
839//*************************************************************************************************
856template< typename MT // Type of the adapted sparse matrix
857 , bool SO > // Storage order of the adapted sparse matrix
858inline typename HermitianMatrix<MT,SO,false>::ConstReference
859 HermitianMatrix<MT,SO,false>::at( size_t i, size_t j ) const
860{
861 if( i >= rows() ) {
862 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
863 }
864 if( j >= columns() ) {
865 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
866 }
867 return (*this)(i,j);
868}
870//*************************************************************************************************
871
872
873//*************************************************************************************************
885template< typename MT // Type of the adapted sparse matrix
886 , bool SO > // Storage order of the adapted sparse matrix
887inline typename HermitianMatrix<MT,SO,false>::Iterator
889{
890 return Iterator( matrix_.begin(i), matrix_, i );
891}
893//*************************************************************************************************
894
895
896//*************************************************************************************************
908template< typename MT // Type of the adapted sparse matrix
909 , bool SO > // Storage order of the adapted sparse matrix
910inline typename HermitianMatrix<MT,SO,false>::ConstIterator
912{
913 return matrix_.begin(i);
914}
916//*************************************************************************************************
917
918
919//*************************************************************************************************
931template< typename MT // Type of the adapted sparse matrix
932 , bool SO > // Storage order of the adapted sparse matrix
933inline typename HermitianMatrix<MT,SO,false>::ConstIterator
935{
936 return matrix_.cbegin(i);
937}
939//*************************************************************************************************
940
941
942//*************************************************************************************************
954template< typename MT // Type of the adapted sparse matrix
955 , bool SO > // Storage order of the adapted sparse matrix
956inline typename HermitianMatrix<MT,SO,false>::Iterator
958{
959 return Iterator( matrix_.end(i), matrix_, i );
960}
962//*************************************************************************************************
963
964
965//*************************************************************************************************
977template< typename MT // Type of the adapted sparse matrix
978 , bool SO > // Storage order of the adapted sparse matrix
979inline typename HermitianMatrix<MT,SO,false>::ConstIterator
980 HermitianMatrix<MT,SO,false>::end( size_t i ) const
981{
982 return matrix_.end(i);
983}
985//*************************************************************************************************
986
987
988//*************************************************************************************************
1000template< typename MT // Type of the adapted sparse matrix
1001 , bool SO > // Storage order of the adapted sparse matrix
1002inline typename HermitianMatrix<MT,SO,false>::ConstIterator
1003 HermitianMatrix<MT,SO,false>::cend( size_t i ) const
1004{
1005 return matrix_.cend(i);
1006}
1008//*************************************************************************************************
1009
1010
1011
1012
1013//=================================================================================================
1014//
1015// ASSIGNMENT OPERATORS
1016//
1017//=================================================================================================
1018
1019//*************************************************************************************************
1046template< typename MT // Type of the adapted sparse matrix
1047 , bool SO > // Storage order of the adapted sparse matrix
1048inline HermitianMatrix<MT,SO,false>&
1049 HermitianMatrix<MT,SO,false>::operator=( initializer_list< initializer_list<ElementType> > list )
1050{
1051 const InitializerMatrix<ElementType> tmp( list, list.size() );
1052
1053 if( !isHermitian( tmp ) ) {
1054 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1055 }
1056
1057 matrix_ = list;
1058
1059 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1060 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1061
1062 return *this;
1063}
1065//*************************************************************************************************
1066
1067
1068//*************************************************************************************************
1078template< typename MT // Type of the adapted sparse matrix
1079 , bool SO > // Storage order of the adapted sparse matrix
1080inline HermitianMatrix<MT,SO,false>&
1081 HermitianMatrix<MT,SO,false>::operator=( const HermitianMatrix& rhs )
1082{
1083 matrix_ = rhs.matrix_;
1084
1085 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1086 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1087
1088 return *this;
1089}
1091//*************************************************************************************************
1092
1093
1094//*************************************************************************************************
1101template< typename MT // Type of the adapted sparse matrix
1102 , bool SO > // Storage order of the adapted sparse matrix
1103inline HermitianMatrix<MT,SO,false>&
1104 HermitianMatrix<MT,SO,false>::operator=( HermitianMatrix&& rhs ) noexcept
1105{
1106 matrix_ = std::move( rhs.matrix_ );
1107
1108 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1109 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1110
1111 return *this;
1112}
1114//*************************************************************************************************
1115
1116
1117//*************************************************************************************************
1130template< typename MT // Type of the adapted sparse matrix
1131 , bool SO > // Storage order of the adapted sparse matrix
1132template< typename MT2 // Type of the right-hand side matrix
1133 , bool SO2 > // Storage order of the right-hand side matrix
1134inline auto HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1135 -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1136{
1137 if( !IsHermitian_v<MT2> && !isHermitian( *rhs ) ) {
1138 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1139 }
1140
1141 matrix_ = *rhs;
1142
1143 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1144 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1145
1146 return *this;
1147}
1149//*************************************************************************************************
1150
1151
1152//*************************************************************************************************
1165template< typename MT // Type of the adapted sparse matrix
1166 , bool SO > // Storage order of the adapted sparse matrix
1167template< typename MT2 // Type of the right-hand side matrix
1168 , bool SO2 > // Storage order of the right-hand side matrix
1169inline auto HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,SO2>& rhs )
1170 -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1171{
1172 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1173 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1174 }
1175
1176 if( IsHermitian_v<MT2> ) {
1177 matrix_ = *rhs;
1178 }
1179 else {
1180 MT tmp( *rhs );
1181
1182 if( !isHermitian( tmp ) ) {
1183 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1184 }
1185
1186 matrix_ = std::move( tmp );
1187 }
1188
1189 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1190 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1191
1192 return *this;
1193}
1195//*************************************************************************************************
1196
1197
1198//*************************************************************************************************
1211template< typename MT // Type of the adapted sparse matrix
1212 , bool SO > // Storage order of the adapted sparse matrix
1213template< typename MT2 > // Type of the right-hand side matrix
1214inline auto HermitianMatrix<MT,SO,false>::operator=( const Matrix<MT2,!SO>& rhs )
1215 -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >
1216{
1217 return this->operator=( trans( *rhs ) );
1218}
1220//*************************************************************************************************
1221
1222
1223//*************************************************************************************************
1236template< typename MT // Type of the adapted sparse matrix
1237 , bool SO > // Storage order of the adapted sparse matrix
1238template< typename MT2 // Type of the right-hand side matrix
1239 , bool SO2 > // Storage order of the right-hand side matrix
1240inline auto HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1241 -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1242{
1243 if( !IsHermitian_v<MT2> && !isHermitian( *rhs ) ) {
1244 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1245 }
1246
1247 matrix_ += *rhs;
1248
1249 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1250 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1251
1252 return *this;
1253}
1255//*************************************************************************************************
1256
1257
1258//*************************************************************************************************
1271template< typename MT // Type of the adapted sparse matrix
1272 , bool SO > // Storage order of the adapted sparse matrix
1273template< typename MT2 // Type of the right-hand side matrix
1274 , bool SO2 > // Storage order of the right-hand side matrix
1275inline auto HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,SO2>& rhs )
1276 -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1277{
1278 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1279 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1280 }
1281
1282 if( IsHermitian_v<MT2> ) {
1283 matrix_ += *rhs;
1284 }
1285 else {
1286 const ResultType_t<MT2> tmp( *rhs );
1287
1288 if( !isHermitian( tmp ) ) {
1289 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1290 }
1291
1292 matrix_ += tmp;
1293 }
1294
1295 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1296 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1297
1298 return *this;
1299}
1301//*************************************************************************************************
1302
1303
1304//*************************************************************************************************
1318template< typename MT // Type of the adapted sparse matrix
1319 , bool SO > // Storage order of the adapted sparse matrix
1320template< typename MT2 > // Type of the right-hand side matrix
1321inline auto HermitianMatrix<MT,SO,false>::operator+=( const Matrix<MT2,!SO>& rhs )
1322 -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >
1323{
1324 return this->operator+=( trans( *rhs ) );
1325}
1327//*************************************************************************************************
1328
1329
1330//*************************************************************************************************
1343template< typename MT // Type of the adapted sparse matrix
1344 , bool SO > // Storage order of the adapted sparse matrix
1345template< typename MT2 // Type of the right-hand side matrix
1346 , bool SO2 > // Storage order of the right-hand side matrix
1347inline auto HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1348 -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1349{
1350 if( !IsHermitian_v<MT2> && !isHermitian( *rhs ) ) {
1351 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1352 }
1353
1354 matrix_ -= *rhs;
1355
1356 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1357 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1358
1359 return *this;
1360}
1362//*************************************************************************************************
1363
1364
1365//*************************************************************************************************
1378template< typename MT // Type of the adapted sparse matrix
1379 , bool SO > // Storage order of the adapted sparse matrix
1380template< typename MT2 // Type of the right-hand side matrix
1381 , bool SO2 > // Storage order of the right-hand side matrix
1382inline auto HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,SO2>& rhs )
1383 -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1384{
1385 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1386 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1387 }
1388
1389 if( IsHermitian_v<MT2> ) {
1390 matrix_ -= *rhs;
1391 }
1392 else {
1393 const ResultType_t<MT2> tmp( *rhs );
1394
1395 if( !isHermitian( tmp ) ) {
1396 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1397 }
1398
1399 matrix_ -= tmp;
1400 }
1401
1402 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1403 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1404
1405 return *this;
1406}
1408//*************************************************************************************************
1409
1410
1411//*************************************************************************************************
1425template< typename MT // Type of the adapted sparse matrix
1426 , bool SO > // Storage order of the adapted sparse matrix
1427template< typename MT2 > // Type of the right-hand side matrix
1428inline auto HermitianMatrix<MT,SO,false>::operator-=( const Matrix<MT2,!SO>& rhs )
1429 -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >
1430{
1431 return this->operator-=( trans( *rhs ) );
1432}
1434//*************************************************************************************************
1435
1436
1437//*************************************************************************************************
1451template< typename MT // Type of the adapted sparse matrix
1452 , bool SO > // Storage order of the adapted sparse matrix
1453template< typename MT2 // Type of the right-hand side matrix
1454 , bool SO2 > // Storage order of the right-hand side matrix
1455inline auto HermitianMatrix<MT,SO,false>::operator%=( const Matrix<MT2,SO2>& rhs )
1456 -> DisableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1457{
1458 if( !IsHermitian_v<MT2> && !isHermitian( *rhs ) ) {
1459 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1460 }
1461
1462 matrix_ %= *rhs;
1463
1464 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1465 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1466
1467 return *this;
1468}
1470//*************************************************************************************************
1471
1472
1473//*************************************************************************************************
1487template< typename MT // Type of the adapted sparse matrix
1488 , bool SO > // Storage order of the adapted sparse matrix
1489template< typename MT2 // Type of the right-hand side matrix
1490 , bool SO2 > // Storage order of the right-hand side matrix
1491inline auto HermitianMatrix<MT,SO,false>::operator%=( const Matrix<MT2,SO2>& rhs )
1492 -> EnableIf_t< IsComputation_v<MT2>, HermitianMatrix& >
1493{
1494 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1495 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1496 }
1497
1498 if( IsHermitian_v<MT2> ) {
1499 matrix_ %= *rhs;
1500 }
1501 else {
1502 const ResultType_t<MT2> tmp( *rhs );
1503
1504 if( !isHermitian( tmp ) ) {
1505 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to Hermitian matrix" );
1506 }
1507
1508 matrix_ %= tmp;
1509 }
1510
1511 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1512 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1513
1514 return *this;
1515}
1517//*************************************************************************************************
1518
1519
1520//*************************************************************************************************
1534template< typename MT // Type of the adapted sparse matrix
1535 , bool SO > // Storage order of the adapted sparse matrix
1536template< typename MT2 > // Type of the right-hand side matrix
1537inline auto HermitianMatrix<MT,SO,false>::operator%=( const Matrix<MT2,!SO>& rhs )
1538 -> EnableIf_t< IsBuiltin_v< ElementType_t<MT2> >, HermitianMatrix& >
1539{
1540 return this->operator%=( trans( *rhs ) );
1541}
1543//*************************************************************************************************
1544
1545
1546//*************************************************************************************************
1554template< typename MT // Type of the adapted sparse matrix
1555 , bool SO > // Storage order of the adapted sparse matrix
1556template< typename ST > // Data type of the right-hand side scalar
1557inline auto HermitianMatrix<MT,SO,false>::operator*=( ST rhs )
1558 -> EnableIf_t< IsScalar_v<ST>, HermitianMatrix& >
1559{
1560 matrix_ *= rhs;
1561 return *this;
1562}
1563//*************************************************************************************************
1564
1565
1566//*************************************************************************************************
1574template< typename MT // Type of the adapted sparse matrix
1575 , bool SO > // Storage order of the adapted sparse matrix
1576template< typename ST > // Data type of the right-hand side scalar
1577inline auto HermitianMatrix<MT,SO,false>::operator/=( ST rhs )
1578 -> EnableIf_t< IsScalar_v<ST>, HermitianMatrix& >
1579{
1580 BLAZE_USER_ASSERT( !isZero( rhs ), "Division by zero detected" );
1581
1582 matrix_ /= rhs;
1583 return *this;
1584}
1586//*************************************************************************************************
1587
1588
1589
1590
1591//=================================================================================================
1592//
1593// UTILITY FUNCTIONS
1594//
1595//=================================================================================================
1596
1597//*************************************************************************************************
1603template< typename MT // Type of the adapted sparse matrix
1604 , bool SO > // Storage order of the adapted sparse matrix
1605inline size_t HermitianMatrix<MT,SO,false>::rows() const noexcept
1606{
1607 return matrix_.rows();
1608}
1610//*************************************************************************************************
1611
1612
1613//*************************************************************************************************
1619template< typename MT // Type of the adapted sparse matrix
1620 , bool SO > // Storage order of the adapted sparse matrix
1621inline size_t HermitianMatrix<MT,SO,false>::columns() const noexcept
1622{
1623 return matrix_.columns();
1624}
1626//*************************************************************************************************
1627
1628
1629//*************************************************************************************************
1635template< typename MT // Type of the adapted sparse matrix
1636 , bool SO > // Storage order of the adapted sparse matrix
1637inline size_t HermitianMatrix<MT,SO,false>::capacity() const noexcept
1638{
1639 return matrix_.capacity();
1640}
1642//*************************************************************************************************
1643
1644
1645//*************************************************************************************************
1656template< typename MT // Type of the adapted sparse matrix
1657 , bool SO > // Storage order of the adapted sparse matrix
1658inline size_t HermitianMatrix<MT,SO,false>::capacity( size_t i ) const noexcept
1659{
1660 return matrix_.capacity(i);
1661}
1663//*************************************************************************************************
1664
1665
1666//*************************************************************************************************
1672template< typename MT // Type of the adapted sparse matrix
1673 , bool SO > // Storage order of the adapted sparse matrix
1674inline size_t HermitianMatrix<MT,SO,false>::nonZeros() const
1675{
1676 return matrix_.nonZeros();
1677}
1679//*************************************************************************************************
1680
1681
1682//*************************************************************************************************
1694template< typename MT // Type of the adapted sparse matrix
1695 , bool SO > // Storage order of the adapted sparse matrix
1696inline size_t HermitianMatrix<MT,SO,false>::nonZeros( size_t i ) const
1697{
1698 return matrix_.nonZeros(i);
1699}
1701//*************************************************************************************************
1702
1703
1704//*************************************************************************************************
1710template< typename MT // Type of the adapted sparse matrix
1711 , bool SO > // Storage order of the adapted sparse matrix
1713{
1714 matrix_.reset();
1715}
1717//*************************************************************************************************
1718
1719
1720//*************************************************************************************************
1756template< typename MT // Type of the adapted sparse matrix
1757 , bool SO > // Storage order of the adapted sparse matrix
1758inline void HermitianMatrix<MT,SO,false>::reset( size_t i )
1759{
1760 using blaze::erase;
1761
1762 for( auto it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1763 {
1764 const size_t j( it->index() );
1765
1766 if( i == j )
1767 continue;
1768
1769 if( SO ) {
1770 const Iterator_t<MT> pos( matrix_.find( i, j ) );
1771 BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1772 erase( matrix_, j, pos );
1773 }
1774 else {
1775 const Iterator_t<MT> pos( matrix_.find( j, i ) );
1776 BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1777 erase( matrix_, j, pos );
1778 }
1779 }
1780
1781 matrix_.reset( i );
1782}
1784//*************************************************************************************************
1785
1786
1787//*************************************************************************************************
1795template< typename MT // Type of the adapted sparse matrix
1796 , bool SO > // Storage order of the adapted sparse matrix
1798{
1799 matrix_.clear();
1800
1801 BLAZE_INTERNAL_ASSERT( matrix_.rows() == 0UL, "Invalid number of rows" );
1802 BLAZE_INTERNAL_ASSERT( matrix_.columns() == 0UL, "Invalid number of columns" );
1803}
1805//*************************************************************************************************
1806
1807
1808//*************************************************************************************************
1823template< typename MT // Type of the adapted sparse matrix
1824 , bool SO > // Storage order of the adapted sparse matrix
1825void HermitianMatrix<MT,SO,false>::resize( size_t n, bool preserve )
1826{
1828
1829 MAYBE_UNUSED( preserve );
1830
1831 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square Hermitian matrix detected" );
1832
1833 matrix_.resize( n, n, true );
1834}
1836//*************************************************************************************************
1837
1838
1839//*************************************************************************************************
1850template< typename MT // Type of the adapted sparse matrix
1851 , bool SO > // Storage order of the adapted sparse matrix
1852inline void HermitianMatrix<MT,SO,false>::reserve( size_t nonzeros )
1853{
1854 matrix_.reserve( nonzeros );
1855}
1857//*************************************************************************************************
1858
1859
1860//*************************************************************************************************
1874template< typename MT // Type of the adapted sparse matrix
1875 , bool SO > // Storage order of the adapted sparse matrix
1876inline void HermitianMatrix<MT,SO,false>::reserve( size_t i, size_t nonzeros )
1877{
1878 matrix_.reserve( i, nonzeros );
1879}
1881//*************************************************************************************************
1882
1883
1884//*************************************************************************************************
1895template< typename MT // Type of the adapted sparse matrix
1896 , bool SO > // Storage order of the adapted sparse matrix
1897inline void HermitianMatrix<MT,SO,false>::trim()
1898{
1899 matrix_.trim();
1900}
1902//*************************************************************************************************
1903
1904
1905//*************************************************************************************************
1917template< typename MT // Type of the adapted sparse matrix
1918 , bool SO > // Storage order of the adapted sparse matrix
1919inline void HermitianMatrix<MT,SO,false>::trim( size_t i )
1920{
1921 matrix_.trim( i );
1922}
1924//*************************************************************************************************
1925
1926
1927//*************************************************************************************************
1937template< typename MT // Type of the adapted sparse matrix
1938 , bool SO > // Storage order of the adapted sparse matrix
1940{
1941 matrix_.shrinkToFit();
1942}
1944//*************************************************************************************************
1945
1946
1947//*************************************************************************************************
1954template< typename MT // Type of the adapted sparse matrix
1955 , bool SO > // Storage order of the adapted sparse matrix
1956inline void HermitianMatrix<MT,SO,false>::swap( HermitianMatrix& m ) noexcept
1957{
1958 using std::swap;
1959
1960 swap( matrix_, m.matrix_ );
1961}
1963//*************************************************************************************************
1964
1965
1966
1967
1968//=================================================================================================
1969//
1970// INSERTION FUNCTIONS
1971//
1972//=================================================================================================
1973
1974//*************************************************************************************************
1989template< typename MT // Type of the adapted sparse matrix
1990 , bool SO > // Storage order of the adapted sparse matrix
1991inline typename HermitianMatrix<MT,SO,false>::Iterator
1992 HermitianMatrix<MT,SO,false>::set( size_t i, size_t j, const ElementType& value )
1993{
1994 const bool isDiagonal( i == j );
1995
1996 if( IsComplex_v<ElementType> && isDiagonal && !isReal( value ) ) {
1997 BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
1998 }
1999
2000 if( !isDiagonal )
2001 matrix_.set( j, i, conj( value ) );
2002 return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
2003}
2005//*************************************************************************************************
2006
2007
2008//*************************************************************************************************
2024template< typename MT // Type of the adapted sparse matrix
2025 , bool SO > // Storage order of the adapted sparse matrix
2026inline typename HermitianMatrix<MT,SO,false>::Iterator
2027 HermitianMatrix<MT,SO,false>::insert( size_t i, size_t j, const ElementType& value )
2028{
2029 const bool isDiagonal( i == j );
2030
2031 if( IsComplex_v<ElementType> && isDiagonal && !isReal( value ) ) {
2032 BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2033 }
2034
2035 if( !isDiagonal )
2036 matrix_.insert( j, i, conj( value ) );
2037 return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
2038}
2040//*************************************************************************************************
2041
2042
2043//*************************************************************************************************
2102template< typename MT // Type of the adapted sparse matrix
2103 , bool SO > // Storage order of the adapted sparse matrix
2104inline void HermitianMatrix<MT,SO,false>::append( size_t i, size_t j, const ElementType& value, bool check )
2105{
2106 const bool isDiagonal( i == j );
2107
2108 if( IsComplex_v<ElementType> && isDiagonal && !isReal( value ) ) {
2109 BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to diagonal matrix element" );
2110 }
2111
2112 matrix_.append( i, j, value, check );
2113 if( !isDiagonal && ( !check || !isDefault<strict>( value ) ) )
2114 matrix_.insert( j, i, conj( value ) );
2115}
2117//*************************************************************************************************
2118
2119
2120//*************************************************************************************************
2134template< typename MT // Type of the adapted sparse matrix
2135 , bool SO > // Storage order of the adapted sparse matrix
2136inline void HermitianMatrix<MT,SO,false>::finalize( size_t i )
2137{
2138 matrix_.trim( i );
2139}
2141//*************************************************************************************************
2142
2143
2144
2145
2146//=================================================================================================
2147//
2148// ERASE FUNCTIONS
2149//
2150//=================================================================================================
2151
2152//*************************************************************************************************
2162template< typename MT // Type of the adapted sparse matrix
2163 , bool SO > // Storage order of the adapted sparse matrix
2164inline void HermitianMatrix<MT,SO,false>::erase( size_t i, size_t j )
2165{
2166 using blaze::erase;
2167
2168 erase( matrix_, i, j );
2169 if( i != j )
2170 erase( matrix_, j, i );
2171}
2173//*************************************************************************************************
2174
2175
2176//*************************************************************************************************
2188template< typename MT // Type of the adapted sparse matrix
2189 , bool SO > // Storage order of the adapted sparse matrix
2190inline typename HermitianMatrix<MT,SO,false>::Iterator
2191 HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator pos )
2192{
2193 using blaze::erase;
2194
2195 const Iterator_t<MT> base( pos.base() );
2196
2197 if( base == matrix_.end( i ) )
2198 return pos;
2199
2200 const size_t j( base->index() );
2201
2202 if( i == j ) {
2203 BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
2204 return Iterator( erase( matrix_, i, base ), matrix_, i );
2205 }
2206
2207 if( SO ) {
2208 BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2209 erase( matrix_, j, matrix_.find( i, j ) );
2210 return Iterator( erase( matrix_, i, base ), matrix_, i );
2211 }
2212 else {
2213 BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2214 erase( matrix_, j, matrix_.find( j, i ) );
2215 return Iterator( erase( matrix_, i, base ), matrix_, i );
2216 }
2217}
2219//*************************************************************************************************
2220
2221
2222//*************************************************************************************************
2236template< typename MT // Type of the adapted sparse matrix
2237 , bool SO > // Storage order of the adapted sparse matrix
2238inline typename HermitianMatrix<MT,SO,false>::Iterator
2239 HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last )
2240{
2241 using blaze::erase;
2242
2243 for( auto it=first.base(); it!=last.base(); ++it )
2244 {
2245 const size_t j( it->index() );
2246
2247 if( i == j )
2248 continue;
2249
2250 if( SO ) {
2251 BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2252 erase( matrix_, i, j );
2253 }
2254 else {
2255 BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2256 erase( matrix_, j, i );
2257 }
2258 }
2259
2260 return Iterator( erase( matrix_, i, first.base(), last.base() ), matrix_, i );
2261}
2263//*************************************************************************************************
2264
2265
2266//*************************************************************************************************
2288template< typename MT // Type of the adapted sparse matrix
2289 , bool SO > // Storage order of the adapted sparse matrix
2290template< typename Pred > // Type of the unary predicate
2291inline void HermitianMatrix<MT,SO,false>::erase( Pred predicate )
2292{
2293 using blaze::erase;
2294
2295 erase( matrix_, [predicate=predicate]( const ElementType& value ) {
2296 return predicate( value ) || predicate( conj( value ) );
2297 } );
2298
2299 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2300}
2302//*************************************************************************************************
2303
2304
2305//*************************************************************************************************
2333template< typename MT // Type of the adapted sparse matrix
2334 , bool SO > // Storage order of the adapted sparse matrix
2335template< typename Pred > // Type of the unary predicate
2336inline void
2337 HermitianMatrix<MT,SO,false>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2338{
2339 using blaze::erase;
2340
2341 for( auto it=first; it!=last; ++it ) {
2342 const size_t j( it->index() );
2343 if( i != j && predicate( it->value() ) ) {
2344 if( SO )
2345 erase( matrix_, i, j );
2346 else
2347 erase( matrix_, j, i );
2348 }
2349 }
2350
2351 erase( matrix_, i, first.base(), last.base(), predicate );
2352
2353 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2354}
2356//*************************************************************************************************
2357
2358
2359
2360
2361//=================================================================================================
2362//
2363// LOOKUP FUNCTIONS
2364//
2365//=================================================================================================
2366
2367//*************************************************************************************************
2383template< typename MT // Type of the adapted sparse matrix
2384 , bool SO > // Storage order of the adapted sparse matrix
2385inline typename HermitianMatrix<MT,SO,false>::Iterator
2386 HermitianMatrix<MT,SO,false>::find( size_t i, size_t j )
2387{
2388 return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2389}
2391//*************************************************************************************************
2392
2393
2394//*************************************************************************************************
2410template< typename MT // Type of the adapted sparse matrix
2411 , bool SO > // Storage order of the adapted sparse matrix
2412inline typename HermitianMatrix<MT,SO,false>::ConstIterator
2413 HermitianMatrix<MT,SO,false>::find( size_t i, size_t j ) const
2414{
2415 return matrix_.find( i, j );
2416}
2418//*************************************************************************************************
2419
2420
2421//*************************************************************************************************
2437template< typename MT // Type of the adapted sparse matrix
2438 , bool SO > // Storage order of the adapted sparse matrix
2439inline typename HermitianMatrix<MT,SO,false>::Iterator
2440 HermitianMatrix<MT,SO,false>::lowerBound( size_t i, size_t j )
2441{
2442 return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2443}
2445//*************************************************************************************************
2446
2447
2448//*************************************************************************************************
2464template< typename MT // Type of the adapted sparse matrix
2465 , bool SO > // Storage order of the adapted sparse matrix
2466inline typename HermitianMatrix<MT,SO,false>::ConstIterator
2467 HermitianMatrix<MT,SO,false>::lowerBound( size_t i, size_t j ) const
2468{
2469 return matrix_.lowerBound( i, j );
2470}
2472//*************************************************************************************************
2473
2474
2475//*************************************************************************************************
2491template< typename MT // Type of the adapted sparse matrix
2492 , bool SO > // Storage order of the adapted sparse matrix
2493inline typename HermitianMatrix<MT,SO,false>::Iterator
2494 HermitianMatrix<MT,SO,false>::upperBound( size_t i, size_t j )
2495{
2496 return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2497}
2499//*************************************************************************************************
2500
2501
2502//*************************************************************************************************
2518template< typename MT // Type of the adapted sparse matrix
2519 , bool SO > // Storage order of the adapted sparse matrix
2520inline typename HermitianMatrix<MT,SO,false>::ConstIterator
2521 HermitianMatrix<MT,SO,false>::upperBound( size_t i, size_t j ) const
2522{
2523 return matrix_.upperBound( i, j );
2524}
2526//*************************************************************************************************
2527
2528
2529
2530
2531//=================================================================================================
2532//
2533// NUMERIC FUNCTIONS
2534//
2535//=================================================================================================
2536
2537//*************************************************************************************************
2543template< typename MT // Type of the adapted sparse matrix
2544 , bool SO > // Storage order of the adapted sparse matrix
2545inline HermitianMatrix<MT,SO,false>& HermitianMatrix<MT,SO,false>::transpose()
2546{
2547 if( IsComplex_v<ElementType> )
2548 matrix_.transpose();
2549 return *this;
2550}
2552//*************************************************************************************************
2553
2554
2555//*************************************************************************************************
2561template< typename MT // Type of the adapted sparse matrix
2562 , bool SO > // Storage order of the adapted sparse matrix
2563inline HermitianMatrix<MT,SO,false>& HermitianMatrix<MT,SO,false>::ctranspose()
2564{
2565 return *this;
2566}
2568//*************************************************************************************************
2569
2570
2571//*************************************************************************************************
2589template< typename MT // Type of the adapted sparse matrix
2590 , bool SO > // Storage order of the adapted sparse matrix
2591template< typename Other > // Data type of the scalar value
2592inline HermitianMatrix<MT,SO,false>&
2593 HermitianMatrix<MT,SO,false>::scale( const Other& scalar )
2594{
2595 matrix_.scale( scalar );
2596 return *this;
2597}
2599//*************************************************************************************************
2600
2601
2602
2603
2604//=================================================================================================
2605//
2606// DEBUGGING FUNCTIONS
2607//
2608//=================================================================================================
2609
2610//*************************************************************************************************
2620template< typename MT // Type of the adapted sparse matrix
2621 , bool SO > // Storage order of the adapted sparse matrix
2622inline bool HermitianMatrix<MT,SO,false>::isIntact() const noexcept
2623{
2624 using blaze::isIntact;
2625
2626 return ( isIntact( matrix_ ) && isHermitian( matrix_ ) );
2627}
2629//*************************************************************************************************
2630
2631
2632
2633
2634//=================================================================================================
2635//
2636// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2637//
2638//=================================================================================================
2639
2640//*************************************************************************************************
2651template< typename MT // Type of the adapted sparse matrix
2652 , bool SO > // Storage order of the adapted sparse matrix
2653template< typename Other > // Data type of the foreign expression
2654inline bool HermitianMatrix<MT,SO,false>::canAlias( const Other* alias ) const noexcept
2655{
2656 return matrix_.canAlias( alias );
2657}
2659//*************************************************************************************************
2660
2661
2662//*************************************************************************************************
2673template< typename MT // Type of the adapted sparse matrix
2674 , bool SO > // Storage order of the adapted sparse matrix
2675template< typename Other > // Data type of the foreign expression
2676inline bool HermitianMatrix<MT,SO,false>::isAliased( const Other* alias ) const noexcept
2677{
2678 return matrix_.isAliased( alias );
2679}
2681//*************************************************************************************************
2682
2683
2684//*************************************************************************************************
2695template< typename MT // Type of the adapted sparse matrix
2696 , bool SO > // Storage order of the adapted sparse matrix
2697inline bool HermitianMatrix<MT,SO,false>::canSMPAssign() const noexcept
2698{
2699 return matrix_.canSMPAssign();
2700}
2702//*************************************************************************************************
2703
2704
2705
2706
2707//=================================================================================================
2708//
2709// CONSTRUCTION FUNCTIONS
2710//
2711//=================================================================================================
2712
2713//*************************************************************************************************
2715template< typename MT // Type of the adapted dense matrix
2716 , bool SO > // Storage order of the adapted dense matrix
2717template< typename MT2 // Type of the foreign matrix
2718 , bool SO2 // Storage order of the foreign matrix
2719 , typename T > // Type of the third argument
2720inline decltype(auto) HermitianMatrix<MT,SO,false>::construct( const Matrix<MT2,SO2>& m, T )
2721{
2722 return *m;
2723}
2725//*************************************************************************************************
2726
2727
2728//*************************************************************************************************
2730template< typename MT // Type of the adapted dense matrix
2731 , bool SO > // Storage order of the adapted dense matrix
2732template< typename MT2 > // Type of the foreign matrix
2733inline decltype(auto) HermitianMatrix<MT,SO,false>::construct( const Matrix<MT2,!SO>& m, TrueType )
2734{
2735 return trans( *m );
2736}
2738//*************************************************************************************************
2739
2740} // namespace blaze
2741
2742#endif
Header file for auxiliary alias declarations.
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.
Definition: Aliases.h:190
Header file for run time assertion macros.
Header file for the conjugate shim.
Constraint on the data type.
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:751
Header file for the EnableIf class template.
Header file for the HermitianElement class.
Header file for the HermitianProxy class.
Constraint on the data type.
Header file for the IntegralConstant class template.
Header file for the IsBuiltin type trait.
Header file for the IsComplex type trait.
Header file for the IsComputation type trait class.
Header file for the isDefault shim.
Header file for the IsHermitian type trait.
Header file for the isReal shim.
Header file for the IsScalar type trait.
Header file for the IsSquare type trait.
Constraint on the data type.
Header file for the MAYBE_UNUSED function template.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Compile time assertion.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the implementation of the base template of the HeritianMatrix.
Initializer list type of the Blaze library.
Pointer difference type of the Blaze library.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
Header file for the SparseMatrix base class.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.
Definition: Volatile.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.
Definition: Const.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:574
decltype(auto) conj(const DenseMatrix< MT, SO > &dm)
Returns a matrix containing the complex conjugate of each single element of dm.
Definition: DMatMapExpr.h:1464
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:386
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:1534
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:510
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:9640
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:448
bool isDiagonal(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is diagonal.
Definition: DenseMatrix.h:2456
bool isZero(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a zero matrix.
Definition: DenseMatrix.h:1819
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:225
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VIEW_TYPE(T)
Constraint on the data type.
Definition: View.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Hermitian.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UPPER_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Upper.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: SparseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_LOWER_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Lower.h:81
#define BLAZE_CONSTRAINT_MUST_BE_RESIZABLE_TYPE(T)
Constraint on the data type.
Definition: Resizable.h:61
#define BLAZE_CONSTRAINT_MUST_BE_SCALAR_TYPE(T)
Constraint on the data type.
Definition: Scalar.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSFORMATION_TYPE(T)
Constraint on the data type.
Definition: Transformation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.
Definition: StorageOrder.h:63
constexpr ptrdiff_t Size_v
Auxiliary variable template for the Size type trait.
Definition: Size.h:176
bool isReal(const Proxy< PT, RT > &proxy)
Returns whether the element represents a real number.
Definition: Proxy.h:2297
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
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
constexpr void clear(Matrix< MT, SO > &matrix)
Clearing the given matrix.
Definition: Matrix.h:960
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:628
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:730
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:562
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:692
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:1108
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:584
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:1221
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:1195
void shrinkToFit(Matrix< MT, SO > &matrix)
Requesting the removal of unused capacity.
Definition: Matrix.h:1169
bool isSquare(const Matrix< MT, SO > &matrix) noexcept
Checks if the given matrix is a square matrix.
Definition: Matrix.h:1383
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
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
MT::Iterator upperBound(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Returns an iterator to the first index greater than the given index.
Definition: SparseMatrix.h:244
MT::Iterator lowerBound(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Returns an iterator to the first index not less than the given index.
Definition: SparseMatrix.h:194
MT::Iterator find(SparseMatrix< MT, SO > &sm, size_t i, size_t j)
Searches for a specific matrix element.
Definition: SparseMatrix.h:144
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.
Definition: StaticAssert.h:112
BoolConstant< true > TrueType
Type traits base class.
Definition: IntegralConstant.h:132
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
Header file for the exception macros of the math module.
Header file for the extended initializer_list functionality.
Constraints on the storage order of matrix types.
Header file for all forward declarations for expression class templates.
Header file for the Size type trait.
Header file for the isZero shim.
Header file for utility functions for sparse matrices.
Header file for basic type definitions.