Blaze 3.9
SparseScalar.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSESCALAR_H_
36#define _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSESCALAR_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <utility>
44#include <vector>
49#include <blaze/math/Aliases.h>
75#include <blaze/util/Assert.h>
80#include <blaze/util/EnableIf.h>
84#include <blaze/util/Types.h>
85
86
87namespace blaze {
88
89//=================================================================================================
90//
91// CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES WITH SCALAR ELEMENT TYPE
92//
93//=================================================================================================
94
95//*************************************************************************************************
103template< typename MT // Type of the adapted sparse matrix
104 , bool SO > // Storage order of the adapted sparse matrix
105class SymmetricMatrix<MT,SO,false,true>
106 : public SparseMatrix< SymmetricMatrix<MT,SO,false,true>, SO >
107{
108 private:
109 //**Type definitions****************************************************************************
110 using OT = OppositeType_t<MT>;
111 using TT = TransposeType_t<MT>;
112 using ET = ElementType_t<MT>;
113 //**********************************************************************************************
114
115 public:
116 //**Type definitions****************************************************************************
117 using This = SymmetricMatrix<MT,SO,false,true>;
118 using BaseType = SparseMatrix<This,SO>;
119 using ResultType = This;
120 using OppositeType = SymmetricMatrix<OT,!SO,false,true>;
121 using TransposeType = SymmetricMatrix<TT,!SO,false,true>;
122 using ElementType = ET;
123 using TagType = TagType_t<MT>;
124 using ReturnType = ReturnType_t<MT>;
125 using CompositeType = const This&;
126 using Reference = ScalarProxy<MT>;
127 using ConstReference = ConstReference_t<MT>;
128 using ConstIterator = ConstIterator_t<MT>;
129 //**********************************************************************************************
130
131 //**Rebind struct definition********************************************************************
134 template< typename NewType > // Data type of the other matrix
135 struct Rebind {
137 using Other = SymmetricMatrix< typename MT::template Rebind<NewType>::Other >;
138 };
139 //**********************************************************************************************
140
141 //**Resize struct definition********************************************************************
144 template< size_t NewM // Number of rows of the other matrix
145 , size_t NewN > // Number of columns of the other matrix
146 struct Resize {
148 using Other = SymmetricMatrix< typename MT::template Resize<NewM,NewN>::Other >;
149 };
150 //**********************************************************************************************
151
152 //**Iterator class definition*******************************************************************
155 class Iterator
156 {
157 public:
158 //**Type definitions*************************************************************************
159 using IteratorType = Iterator_t<MT>;
160
161 using IteratorCategory = std::forward_iterator_tag;
162 using ValueType = SymmetricElement<MT>;
163 using PointerType = ValueType;
164 using ReferenceType = ValueType;
165 using DifferenceType = ptrdiff_t;
166
167 // STL iterator requirements
168 using iterator_category = IteratorCategory;
169 using value_type = ValueType;
170 using pointer = PointerType;
171 using reference = ReferenceType;
172 using difference_type = DifferenceType;
173 //*******************************************************************************************
174
175 //**Default constructor**********************************************************************
178 inline Iterator()
179 : pos_ () // Iterator to the current sparse symmetric matrix element
180 , matrix_( nullptr ) // The sparse matrix containing the iterator
181 , index_ ( 0UL ) // The row/column index of the iterator
182 {}
183 //*******************************************************************************************
184
185 //**Constructor******************************************************************************
192 inline Iterator( IteratorType pos, MT& matrix, size_t index )
193 : pos_ ( pos ) // Iterator to the current sparse symmetric matrix element
194 , matrix_( &matrix ) // The sparse matrix containing the iterator
195 , index_ ( index ) // The row/column index of the iterator
196 {}
197 //*******************************************************************************************
198
199 //**Prefix increment operator****************************************************************
204 inline Iterator& operator++() {
205 ++pos_;
206 return *this;
207 }
208 //*******************************************************************************************
209
210 //**Postfix increment operator***************************************************************
215 inline const Iterator operator++( int ) {
216 const Iterator tmp( *this );
217 ++(*this);
218 return tmp;
219 }
220 //*******************************************************************************************
221
222 //**Element access operator******************************************************************
227 inline ReferenceType operator*() const {
228 return ReferenceType( pos_, matrix_, index_ );
229 }
230 //*******************************************************************************************
231
232 //**Element access operator******************************************************************
237 inline PointerType operator->() const {
238 return PointerType( pos_, matrix_, index_ );
239 }
240 //*******************************************************************************************
241
242 //**Conversion operator**********************************************************************
247 inline operator ConstIterator() const {
248 return pos_;
249 }
250 //*******************************************************************************************
251
252 //**Equality operator************************************************************************
258 inline bool operator==( const Iterator& rhs ) const {
259 return pos_ == rhs.pos_;
260 }
261 //*******************************************************************************************
262
263 //**Inequality operator**********************************************************************
269 inline bool operator!=( const Iterator& rhs ) const {
270 return !( *this == rhs );
271 }
272 //*******************************************************************************************
273
274 //**Subtraction operator*********************************************************************
280 inline DifferenceType operator-( const Iterator& rhs ) const {
281 return pos_ - rhs.pos_;
282 }
283 //*******************************************************************************************
284
285 //**Base function****************************************************************************
290 inline IteratorType base() const {
291 return pos_;
292 }
293 //*******************************************************************************************
294
295 private:
296 //**Member variables*************************************************************************
297 IteratorType pos_;
298 MT* matrix_;
299 size_t index_;
300 //*******************************************************************************************
301 };
302 //**********************************************************************************************
303
304 //**Compilation flags***************************************************************************
306 static constexpr bool smpAssignable = false;
307 //**********************************************************************************************
308
309 //**Constructors********************************************************************************
312 inline SymmetricMatrix();
313 explicit inline SymmetricMatrix( size_t n );
314 inline SymmetricMatrix( size_t n, size_t nonzeros );
315 inline SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros );
316 inline SymmetricMatrix( initializer_list< initializer_list<ElementType> > list );
317
318 inline SymmetricMatrix( const SymmetricMatrix& m );
319 inline SymmetricMatrix( SymmetricMatrix&& m ) noexcept;
320
321 template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
322 template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
324 //**********************************************************************************************
325
326 //**Destructor**********************************************************************************
329 ~SymmetricMatrix() = default;
331 //**********************************************************************************************
332
333 //**Data access functions***********************************************************************
336 inline Reference operator()( size_t i, size_t j );
337 inline ConstReference operator()( size_t i, size_t j ) const;
338 inline Reference at( size_t i, size_t j );
339 inline ConstReference at( size_t i, size_t j ) const;
340 inline Iterator begin ( size_t i );
341 inline ConstIterator begin ( size_t i ) const;
342 inline ConstIterator cbegin( size_t i ) const;
343 inline Iterator end ( size_t i );
344 inline ConstIterator end ( size_t i ) const;
345 inline ConstIterator cend ( size_t i ) const;
347 //**********************************************************************************************
348
349 //**Assignment operators************************************************************************
352 inline SymmetricMatrix& operator=( initializer_list< initializer_list<ElementType> > list );
353
354 inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
355 inline SymmetricMatrix& operator=( SymmetricMatrix&& rhs ) noexcept;
356
357 template< typename MT2 >
358 inline auto operator=( const Matrix<MT2,SO>& rhs )
359 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
360
361 template< typename MT2 >
362 inline auto operator=( const Matrix<MT2,SO>& rhs )
363 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
364
365 template< typename MT2 >
366 inline auto operator=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
367
368 template< typename MT2 >
369 inline auto operator+=( const Matrix<MT2,SO>& rhs )
370 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
371
372 template< typename MT2 >
373 inline auto operator+=( const Matrix<MT2,SO>& rhs )
374 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
375
376 template< typename MT2 >
377 inline auto operator+=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
378
379 template< typename MT2 >
380 inline auto operator-=( const Matrix<MT2,SO>& rhs )
381 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
382
383 template< typename MT2 >
384 inline auto operator-=( const Matrix<MT2,SO>& rhs )
385 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
386
387 template< typename MT2 >
388 inline auto operator-=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
389
390 template< typename MT2 >
391 inline auto operator%=( const Matrix<MT2,SO>& rhs )
392 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
393
394 template< typename MT2 >
395 inline auto operator%=( const Matrix<MT2,SO>& rhs )
396 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
397
398 template< typename MT2 >
399 inline auto operator%=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
400
401 template< typename ST >
402 inline auto operator*=( ST rhs ) -> EnableIf_t< IsScalar_v<ST>, SymmetricMatrix& >;
403
404 template< typename ST >
405 inline auto operator/=( ST rhs ) -> EnableIf_t< IsScalar_v<ST>, SymmetricMatrix& >;
407 //**********************************************************************************************
408
409 //**Utility functions***************************************************************************
412 inline size_t rows() const noexcept;
413 inline size_t columns() const noexcept;
414 inline size_t capacity() const noexcept;
415 inline size_t capacity( size_t i ) const noexcept;
416 inline size_t nonZeros() const;
417 inline size_t nonZeros( size_t i ) const;
418 inline void reset();
419 inline void reset( size_t i );
420 inline void clear();
421 inline void resize ( size_t n, bool preserve=true );
422 inline void reserve( size_t nonzeros );
423 inline void reserve( size_t i, size_t nonzeros );
424 inline void trim();
425 inline void trim( size_t i );
426 inline void shrinkToFit();
427 inline void swap( SymmetricMatrix& m ) noexcept;
429 //**********************************************************************************************
430
431 //**Insertion functions*************************************************************************
434 inline Iterator set ( size_t i, size_t j, const ElementType& value );
435 inline Iterator insert ( size_t i, size_t j, const ElementType& value );
436 inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
437 inline void finalize( size_t i );
439 //**********************************************************************************************
440
441 //**Erase functions*****************************************************************************
444 inline void erase( size_t i, size_t j );
445 inline Iterator erase( size_t i, Iterator pos );
446 inline Iterator erase( size_t i, Iterator first, Iterator last );
447
448 template< typename Pred >
449 inline void erase( Pred predicate );
450
451 template< typename Pred >
452 inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
454 //**********************************************************************************************
455
456 //**Lookup functions****************************************************************************
459 inline Iterator find ( size_t i, size_t j );
460 inline ConstIterator find ( size_t i, size_t j ) const;
461 inline Iterator lowerBound( size_t i, size_t j );
462 inline ConstIterator lowerBound( size_t i, size_t j ) const;
463 inline Iterator upperBound( size_t i, size_t j );
464 inline ConstIterator upperBound( size_t i, size_t j ) const;
466 //**********************************************************************************************
467
468 //**Numeric functions***************************************************************************
471 inline SymmetricMatrix& transpose();
472 inline SymmetricMatrix& ctranspose();
473
474 template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
476 //**********************************************************************************************
477
478 //**Debugging functions*************************************************************************
481 inline bool isIntact() const noexcept;
483 //**********************************************************************************************
484
485 //**Expression template evaluation functions****************************************************
488 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
489 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
490
491 inline bool canSMPAssign() const noexcept;
493 //**********************************************************************************************
494
495 private:
496 //**Member variables****************************************************************************
499 MT matrix_;
501 //**********************************************************************************************
502
503 //**Compile time checks*************************************************************************
519 BLAZE_STATIC_ASSERT( ( Size_v<MT,0UL> == Size_v<MT,1UL> ) );
520 //**********************************************************************************************
521};
523//*************************************************************************************************
524
525
526
527
528//=================================================================================================
529//
530// CONSTRUCTORS
531//
532//=================================================================================================
533
534//*************************************************************************************************
538template< typename MT // Type of the adapted sparse matrix
539 , bool SO > // Storage order of the adapted sparse matrix
540inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix()
541 : matrix_() // The adapted sparse matrix
542{
543 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
544}
546//*************************************************************************************************
547
548
549//*************************************************************************************************
557template< typename MT // Type of the adapted sparse matrix
558 , bool SO > // Storage order of the adapted sparse matrix
559inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n )
560 : matrix_( n, n ) // The adapted sparse matrix
561{
563
564 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
565}
567//*************************************************************************************************
568
569
570//*************************************************************************************************
579template< typename MT // Type of the adapted sparse matrix
580 , bool SO > // Storage order of the adapted sparse matrix
581inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, size_t nonzeros )
582 : matrix_( n, n, nonzeros ) // The adapted sparse matrix
583{
585
586 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
587}
589//*************************************************************************************************
590
591
592//*************************************************************************************************
603template< typename MT // Type of the adapted sparse matrix
604 , bool SO > // Storage order of the adapted sparse matrix
605inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
606 : matrix_( n, n, nonzeros ) // The adapted sparse matrix
607{
609
610 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
611}
613//*************************************************************************************************
614
615
616//*************************************************************************************************
640template< typename MT // Type of the adapted sparse matrix
641 , bool SO > // Storage order of the adapted sparse matrix
642inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( initializer_list< initializer_list<ElementType> > list )
643 : matrix_( list ) // The adapted sparse matrix
644{
645 if( !isSymmetric( matrix_ ) ) {
646 BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
647 }
648
649 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
650}
652//*************************************************************************************************
653
654
655//*************************************************************************************************
661template< typename MT // Type of the adapted sparse matrix
662 , bool SO > // Storage order of the adapted sparse matrix
663inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const SymmetricMatrix& m )
664 : matrix_( m.matrix_ ) // The adapted sparse matrix
665{
666 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
667 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
668}
670//*************************************************************************************************
671
672
673//*************************************************************************************************
679template< typename MT // Type of the adapted sparse matrix
680 , bool SO > // Storage order of the adapted sparse matrix
681inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( SymmetricMatrix&& m ) noexcept
682 : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
683{
684 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
685 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
686}
688//*************************************************************************************************
689
690
691//*************************************************************************************************
701template< typename MT // Type of the adapted sparse matrix
702 , bool SO > // Storage order of the adapted sparse matrix
703template< typename MT2 > // Type of the foreign matrix
704inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,SO>& m )
705 : matrix_( *m ) // The adapted sparse matrix
706{
707 if( !IsSymmetric_v<MT2> && !isSymmetric( matrix_ ) ) {
708 BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
709 }
710
711 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
712 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
713}
715//*************************************************************************************************
716
717
718//*************************************************************************************************
728template< typename MT // Type of the adapted sparse matrix
729 , bool SO > // Storage order of the adapted sparse matrix
730template< typename MT2 > // Type of the foreign matrix
731inline SymmetricMatrix<MT,SO,false,true>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
732 : matrix_( trans( *m ) ) // The adapted sparse matrix
733{
734 if( !IsSymmetric_v<MT2> && !isSymmetric( matrix_ ) ) {
735 BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
736 }
737
738 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
739 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
740}
742//*************************************************************************************************
743
744
745
746
747//=================================================================================================
748//
749// DATA ACCESS FUNCTIONS
750//
751//=================================================================================================
752
753//*************************************************************************************************
768template< typename MT // Type of the adapted sparse matrix
769 , bool SO > // Storage order of the adapted sparse matrix
770inline typename SymmetricMatrix<MT,SO,false,true>::Reference
771 SymmetricMatrix<MT,SO,false,true>::operator()( size_t i, size_t j )
772{
773 BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
774 BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
775
776 return Reference( matrix_, i, j );
777}
779//*************************************************************************************************
780
781
782//*************************************************************************************************
797template< typename MT // Type of the adapted sparse matrix
798 , bool SO > // Storage order of the adapted sparse matrix
799inline typename SymmetricMatrix<MT,SO,false,true>::ConstReference
800 SymmetricMatrix<MT,SO,false,true>::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//*************************************************************************************************
827template< typename MT // Type of the adapted dense matrix
828 , bool SO > // Storage order of the adapted dense matrix
829inline typename SymmetricMatrix<MT,SO,false,true>::Reference
830 SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j )
831{
832 if( i >= rows() ) {
833 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
834 }
835 if( j >= columns() ) {
836 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
837 }
838 return (*this)(i,j);
839}
841//*************************************************************************************************
842
843
844//*************************************************************************************************
860template< typename MT // Type of the adapted dense matrix
861 , bool SO > // Storage order of the adapted dense matrix
862inline typename SymmetricMatrix<MT,SO,false,true>::ConstReference
863 SymmetricMatrix<MT,SO,false,true>::at( size_t i, size_t j ) const
864{
865 if( i >= rows() ) {
866 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
867 }
868 if( j >= columns() ) {
869 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
870 }
871 return (*this)(i,j);
872}
874//*************************************************************************************************
875
876
877//*************************************************************************************************
889template< typename MT // Type of the adapted sparse matrix
890 , bool SO > // Storage order of the adapted sparse matrix
891inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
893{
894 return Iterator( matrix_.begin(i), matrix_, i );
895}
897//*************************************************************************************************
898
899
900//*************************************************************************************************
912template< typename MT // Type of the adapted sparse matrix
913 , bool SO > // Storage order of the adapted sparse matrix
914inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
916{
917 return matrix_.begin(i);
918}
920//*************************************************************************************************
921
922
923//*************************************************************************************************
935template< typename MT // Type of the adapted sparse matrix
936 , bool SO > // Storage order of the adapted sparse matrix
937inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
939{
940 return matrix_.cbegin(i);
941}
943//*************************************************************************************************
944
945
946//*************************************************************************************************
958template< typename MT // Type of the adapted sparse matrix
959 , bool SO > // Storage order of the adapted sparse matrix
960inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
962{
963 return Iterator( matrix_.end(i), matrix_, i );
964}
966//*************************************************************************************************
967
968
969//*************************************************************************************************
981template< typename MT // Type of the adapted sparse matrix
982 , bool SO > // Storage order of the adapted sparse matrix
983inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
985{
986 return matrix_.end(i);
987}
989//*************************************************************************************************
990
991
992//*************************************************************************************************
1004template< typename MT // Type of the adapted sparse matrix
1005 , bool SO > // Storage order of the adapted sparse matrix
1006inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
1008{
1009 return matrix_.cend(i);
1010}
1012//*************************************************************************************************
1013
1014
1015
1016
1017//=================================================================================================
1018//
1019// ASSIGNMENT OPERATORS
1020//
1021//=================================================================================================
1022
1023//*************************************************************************************************
1048template< typename MT // Type of the adapted sparse matrix
1049 , bool SO > // Storage order of the adapted sparse matrix
1050inline SymmetricMatrix<MT,SO,false,true>&
1051 SymmetricMatrix<MT,SO,false,true>::operator=( initializer_list< initializer_list<ElementType> > list )
1052{
1053 const InitializerMatrix<ElementType> tmp( list, list.size() );
1054
1055 if( !isSymmetric( tmp ) ) {
1056 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1057 }
1058
1059 matrix_ = list;
1060
1061 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1062 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1063
1064 return *this;
1065}
1067//*************************************************************************************************
1068
1069
1070//*************************************************************************************************
1080template< typename MT // Type of the adapted sparse matrix
1081 , bool SO > // Storage order of the adapted sparse matrix
1082inline SymmetricMatrix<MT,SO,false,true>&
1083 SymmetricMatrix<MT,SO,false,true>::operator=( const SymmetricMatrix& rhs )
1084{
1085 matrix_ = rhs.matrix_;
1086
1087 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1088 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1089
1090 return *this;
1091}
1093//*************************************************************************************************
1094
1095
1096//*************************************************************************************************
1103template< typename MT // Type of the adapted sparse matrix
1104 , bool SO > // Storage order of the adapted sparse matrix
1105inline SymmetricMatrix<MT,SO,false,true>&
1106 SymmetricMatrix<MT,SO,false,true>::operator=( SymmetricMatrix&& rhs ) noexcept
1107{
1108 matrix_ = std::move( rhs.matrix_ );
1109
1110 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1111 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1112
1113 return *this;
1114}
1116//*************************************************************************************************
1117
1118
1119//*************************************************************************************************
1132template< typename MT // Type of the adapted sparse matrix
1133 , bool SO > // Storage order of the adapted sparse matrix
1134template< typename MT2 > // Type of the right-hand side matrix
1135inline auto SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1136 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1137{
1138 if( !IsSymmetric_v<MT2> && !isSymmetric( *rhs ) ) {
1139 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1140 }
1141
1142 matrix_ = *rhs;
1143
1144 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1145 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1146
1147 return *this;
1148}
1150//*************************************************************************************************
1151
1152
1153//*************************************************************************************************
1166template< typename MT // Type of the adapted sparse matrix
1167 , bool SO > // Storage order of the adapted sparse matrix
1168template< typename MT2 > // Type of the right-hand side matrix
1169inline auto SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,SO>& rhs )
1170 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1171{
1172 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1173 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1174 }
1175
1176 if( IsSymmetric_v<MT2> ) {
1177 matrix_ = *rhs;
1178 }
1179 else {
1180 MT tmp( *rhs );
1181
1182 if( !isSymmetric( tmp ) ) {
1183 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1184 }
1185
1186 matrix_ = std::move( tmp );
1187 }
1188
1189 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric 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 SymmetricMatrix<MT,SO,false,true>::operator=( const Matrix<MT2,!SO>& rhs )
1215 -> SymmetricMatrix&
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
1239inline auto SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1240 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1241{
1242 if( !IsSymmetric_v<MT2> && !isSymmetric( *rhs ) ) {
1243 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1244 }
1245
1246 matrix_ += *rhs;
1247
1248 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1249 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1250
1251 return *this;
1252}
1254//*************************************************************************************************
1255
1256
1257//*************************************************************************************************
1270template< typename MT // Type of the adapted sparse matrix
1271 , bool SO > // Storage order of the adapted sparse matrix
1272template< typename MT2 > // Type of the right-hand side matrix
1273inline auto SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,SO>& rhs )
1274 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1275{
1276 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1277 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1278 }
1279
1280 if( IsSymmetric_v<MT2> ) {
1281 matrix_ += *rhs;
1282 }
1283 else {
1284 const ResultType_t<MT2> tmp( *rhs );
1285
1286 if( !isSymmetric( tmp ) ) {
1287 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1288 }
1289
1290 matrix_ += tmp;
1291 }
1292
1293 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1294 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1295
1296 return *this;
1297}
1299//*************************************************************************************************
1300
1301
1302//*************************************************************************************************
1316template< typename MT // Type of the adapted sparse matrix
1317 , bool SO > // Storage order of the adapted sparse matrix
1318template< typename MT2 > // Type of the right-hand side matrix
1319inline auto SymmetricMatrix<MT,SO,false,true>::operator+=( const Matrix<MT2,!SO>& rhs )
1320 -> SymmetricMatrix&
1321{
1322 return this->operator+=( trans( *rhs ) );
1323}
1325//*************************************************************************************************
1326
1327
1328//*************************************************************************************************
1341template< typename MT // Type of the adapted sparse matrix
1342 , bool SO > // Storage order of the adapted sparse matrix
1343template< typename MT2 > // Type of the right-hand side matrix
1344inline auto SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1345 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1346{
1347 if( !IsSymmetric_v<MT2> && !isSymmetric( *rhs ) ) {
1348 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1349 }
1350
1351 matrix_ -= *rhs;
1352
1353 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1354 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1355
1356 return *this;
1357}
1359//*************************************************************************************************
1360
1361
1362//*************************************************************************************************
1375template< typename MT // Type of the adapted sparse matrix
1376 , bool SO > // Storage order of the adapted sparse matrix
1377template< typename MT2 > // Type of the right-hand side matrix
1378inline auto SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,SO>& rhs )
1379 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1380{
1381 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1382 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1383 }
1384
1385 if( IsSymmetric_v<MT2> ) {
1386 matrix_ -= *rhs;
1387 }
1388 else {
1389 const ResultType_t<MT2> tmp( *rhs );
1390
1391 if( !isSymmetric( tmp ) ) {
1392 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1393 }
1394
1395 matrix_ -= tmp;
1396 }
1397
1398 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1399 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1400
1401 return *this;
1402}
1404//*************************************************************************************************
1405
1406
1407//*************************************************************************************************
1421template< typename MT // Type of the adapted sparse matrix
1422 , bool SO > // Storage order of the adapted sparse matrix
1423template< typename MT2 > // Type of the right-hand side matrix
1424inline auto SymmetricMatrix<MT,SO,false,true>::operator-=( const Matrix<MT2,!SO>& rhs )
1425 -> SymmetricMatrix&
1426{
1427 return this->operator-=( trans( *rhs ) );
1428}
1430//*************************************************************************************************
1431
1432
1433//*************************************************************************************************
1447template< typename MT // Type of the adapted sparse matrix
1448 , bool SO > // Storage order of the adapted sparse matrix
1449template< typename MT2 > // Type of the right-hand side matrix
1450inline auto SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1451 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1452{
1453 if( !IsSymmetric_v<MT2> && !isSymmetric( *rhs ) ) {
1454 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1455 }
1456
1457 matrix_ %= *rhs;
1458
1459 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1460 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1461
1462 return *this;
1463}
1465//*************************************************************************************************
1466
1467
1468//*************************************************************************************************
1482template< typename MT // Type of the adapted sparse matrix
1483 , bool SO > // Storage order of the adapted sparse matrix
1484template< typename MT2 > // Type of the right-hand side matrix
1485inline auto SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,SO>& rhs )
1486 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1487{
1488 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1489 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1490 }
1491
1492 if( IsSymmetric_v<MT2> ) {
1493 matrix_ %= *rhs;
1494 }
1495 else {
1496 const ResultType_t<MT2> tmp( *rhs );
1497
1498 if( !isSymmetric( tmp ) ) {
1499 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1500 }
1501
1502 matrix_ %= tmp;
1503 }
1504
1505 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1506 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1507
1508 return *this;
1509}
1511//*************************************************************************************************
1512
1513
1514//*************************************************************************************************
1528template< typename MT // Type of the adapted sparse matrix
1529 , bool SO > // Storage order of the adapted sparse matrix
1530template< typename MT2 > // Type of the right-hand side matrix
1531inline auto SymmetricMatrix<MT,SO,false,true>::operator%=( const Matrix<MT2,!SO>& rhs )
1532 -> SymmetricMatrix&
1533{
1534 return this->operator%=( trans( *rhs ) );
1535}
1537//*************************************************************************************************
1538
1539
1540//*************************************************************************************************
1548template< typename MT // Type of the adapted sparse matrix
1549 , bool SO > // Storage order of the adapted sparse matrix
1550template< typename ST > // Data type of the right-hand side scalar
1552 -> EnableIf_t< IsScalar_v<ST>, SymmetricMatrix& >
1553{
1554 matrix_ *= rhs;
1555 return *this;
1556}
1557//*************************************************************************************************
1558
1559
1560//*************************************************************************************************
1568template< typename MT // Type of the adapted sparse matrix
1569 , bool SO > // Storage order of the adapted sparse matrix
1570template< typename ST > // Data type of the right-hand side scalar
1572 -> EnableIf_t< IsScalar_v<ST>, SymmetricMatrix& >
1573{
1574 BLAZE_USER_ASSERT( !isZero( rhs ), "Division by zero detected" );
1575
1576 matrix_ /= rhs;
1577 return *this;
1578}
1580//*************************************************************************************************
1581
1582
1583
1584
1585//=================================================================================================
1586//
1587// UTILITY FUNCTIONS
1588//
1589//=================================================================================================
1590
1591//*************************************************************************************************
1597template< typename MT // Type of the adapted sparse matrix
1598 , bool SO > // Storage order of the adapted sparse matrix
1599inline size_t SymmetricMatrix<MT,SO,false,true>::rows() const noexcept
1600{
1601 return matrix_.rows();
1602}
1604//*************************************************************************************************
1605
1606
1607//*************************************************************************************************
1613template< typename MT // Type of the adapted sparse matrix
1614 , bool SO > // Storage order of the adapted sparse matrix
1615inline size_t SymmetricMatrix<MT,SO,false,true>::columns() const noexcept
1616{
1617 return matrix_.columns();
1618}
1620//*************************************************************************************************
1621
1622
1623//*************************************************************************************************
1629template< typename MT // Type of the adapted sparse matrix
1630 , bool SO > // Storage order of the adapted sparse matrix
1631inline size_t SymmetricMatrix<MT,SO,false,true>::capacity() const noexcept
1632{
1633 return matrix_.capacity();
1634}
1636//*************************************************************************************************
1637
1638
1639//*************************************************************************************************
1650template< typename MT // Type of the adapted sparse matrix
1651 , bool SO > // Storage order of the adapted sparse matrix
1652inline size_t SymmetricMatrix<MT,SO,false,true>::capacity( size_t i ) const noexcept
1653{
1654 return matrix_.capacity(i);
1655}
1657//*************************************************************************************************
1658
1659
1660//*************************************************************************************************
1666template< typename MT // Type of the adapted sparse matrix
1667 , bool SO > // Storage order of the adapted sparse matrix
1669{
1670 return matrix_.nonZeros();
1671}
1673//*************************************************************************************************
1674
1675
1676//*************************************************************************************************
1688template< typename MT // Type of the adapted sparse matrix
1689 , bool SO > // Storage order of the adapted sparse matrix
1690inline size_t SymmetricMatrix<MT,SO,false,true>::nonZeros( size_t i ) const
1691{
1692 return matrix_.nonZeros(i);
1693}
1695//*************************************************************************************************
1696
1697
1698//*************************************************************************************************
1704template< typename MT // Type of the adapted sparse matrix
1705 , bool SO > // Storage order of the adapted sparse matrix
1707{
1708 matrix_.reset();
1709}
1711//*************************************************************************************************
1712
1713
1714//*************************************************************************************************
1750template< typename MT // Type of the adapted sparse matrix
1751 , bool SO > // Storage order of the adapted sparse matrix
1752inline void SymmetricMatrix<MT,SO,false,true>::reset( size_t i )
1753{
1754 using blaze::erase;
1755
1756 for( auto it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1757 {
1758 const size_t j( it->index() );
1759
1760 if( i == j )
1761 continue;
1762
1763 if( SO ) {
1764 const Iterator_t<MT> pos( matrix_.find( i, j ) );
1765 BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1766 erase( matrix_, j, pos );
1767 }
1768 else {
1769 const Iterator_t<MT> pos( matrix_.find( j, i ) );
1770 BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1771 erase( matrix_, j, pos );
1772 }
1773 }
1774
1775 matrix_.reset( i );
1776}
1778//*************************************************************************************************
1779
1780
1781//*************************************************************************************************
1789template< typename MT // Type of the adapted sparse matrix
1790 , bool SO > // Storage order of the adapted sparse matrix
1792{
1793 matrix_.clear();
1794
1795 BLAZE_INTERNAL_ASSERT( matrix_.rows() == 0UL, "Invalid number of rows" );
1796 BLAZE_INTERNAL_ASSERT( matrix_.columns() == 0UL, "Invalid number of columns" );
1797}
1799//*************************************************************************************************
1800
1801
1802//*************************************************************************************************
1817template< typename MT // Type of the adapted sparse matrix
1818 , bool SO > // Storage order of the adapted sparse matrix
1819void SymmetricMatrix<MT,SO,false,true>::resize( size_t n, bool preserve )
1820{
1822
1823 MAYBE_UNUSED( preserve );
1824
1825 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1826
1827 matrix_.resize( n, n, true );
1828}
1830//*************************************************************************************************
1831
1832
1833//*************************************************************************************************
1844template< typename MT // Type of the adapted sparse matrix
1845 , bool SO > // Storage order of the adapted sparse matrix
1846inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t nonzeros )
1847{
1848 matrix_.reserve( nonzeros );
1849}
1851//*************************************************************************************************
1852
1853
1854//*************************************************************************************************
1868template< typename MT // Type of the adapted sparse matrix
1869 , bool SO > // Storage order of the adapted sparse matrix
1870inline void SymmetricMatrix<MT,SO,false,true>::reserve( size_t i, size_t nonzeros )
1871{
1872 matrix_.reserve( i, nonzeros );
1873}
1875//*************************************************************************************************
1876
1877
1878//*************************************************************************************************
1889template< typename MT // Type of the adapted sparse matrix
1890 , bool SO > // Storage order of the adapted sparse matrix
1891inline void SymmetricMatrix<MT,SO,false,true>::trim()
1892{
1893 matrix_.trim();
1894}
1896//*************************************************************************************************
1897
1898
1899//*************************************************************************************************
1911template< typename MT // Type of the adapted sparse matrix
1912 , bool SO > // Storage order of the adapted sparse matrix
1913inline void SymmetricMatrix<MT,SO,false,true>::trim( size_t i )
1914{
1915 matrix_.trim( i );
1916}
1918//*************************************************************************************************
1919
1920
1921//*************************************************************************************************
1931template< typename MT // Type of the adapted sparse matrix
1932 , bool SO > // Storage order of the adapted sparse matrix
1934{
1935 matrix_.shrinkToFit();
1936}
1938//*************************************************************************************************
1939
1940
1941//*************************************************************************************************
1948template< typename MT // Type of the adapted sparse matrix
1949 , bool SO > // Storage order of the adapted sparse matrix
1950inline void SymmetricMatrix<MT,SO,false,true>::swap( SymmetricMatrix& m ) noexcept
1951{
1952 using std::swap;
1953
1954 swap( matrix_, m.matrix_ );
1955}
1957//*************************************************************************************************
1958
1959
1960
1961
1962//=================================================================================================
1963//
1964// INSERTION FUNCTIONS
1965//
1966//=================================================================================================
1967
1968//*************************************************************************************************
1982template< typename MT // Type of the adapted sparse matrix
1983 , bool SO > // Storage order of the adapted sparse matrix
1984inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
1985 SymmetricMatrix<MT,SO,false,true>::set( size_t i, size_t j, const ElementType& value )
1986{
1987 if( i != j )
1988 matrix_.set( j, i, value );
1989 return Iterator( matrix_.set( i, j, value ), matrix_, ( SO ? j : i ) );
1990}
1992//*************************************************************************************************
1993
1994
1995//*************************************************************************************************
2010template< typename MT // Type of the adapted sparse matrix
2011 , bool SO > // Storage order of the adapted sparse matrix
2012inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2013 SymmetricMatrix<MT,SO,false,true>::insert( size_t i, size_t j, const ElementType& value )
2014{
2015 if( i != j )
2016 matrix_.insert( j, i, value );
2017 return Iterator( matrix_.insert( i, j, value ), matrix_, ( SO ? j : i ) );
2018}
2020//*************************************************************************************************
2021
2022
2023//*************************************************************************************************
2078template< typename MT // Type of the adapted sparse matrix
2079 , bool SO > // Storage order of the adapted sparse matrix
2080inline void SymmetricMatrix<MT,SO,false,true>::append( size_t i, size_t j, const ElementType& value, bool check )
2081{
2082 matrix_.append( i, j, value, check );
2083 if( i != j && ( !check || !isDefault<strict>( value ) ) )
2084 matrix_.insert( j, i, value );
2085}
2087//*************************************************************************************************
2088
2089
2090//*************************************************************************************************
2104template< typename MT // Type of the adapted sparse matrix
2105 , bool SO > // Storage order of the adapted sparse matrix
2106inline void SymmetricMatrix<MT,SO,false,true>::finalize( size_t i )
2107{
2108 matrix_.trim( i );
2109}
2111//*************************************************************************************************
2112
2113
2114
2115
2116//=================================================================================================
2117//
2118// ERASE FUNCTIONS
2119//
2120//=================================================================================================
2121
2122//*************************************************************************************************
2132template< typename MT // Type of the adapted sparse matrix
2133 , bool SO > // Storage order of the adapted sparse matrix
2134inline void SymmetricMatrix<MT,SO,false,true>::erase( size_t i, size_t j )
2135{
2136 using blaze::erase;
2137
2138 erase( matrix_, i, j );
2139 if( i != j )
2140 erase( matrix_, j, i );
2141}
2143//*************************************************************************************************
2144
2145
2146//*************************************************************************************************
2158template< typename MT // Type of the adapted sparse matrix
2159 , bool SO > // Storage order of the adapted sparse matrix
2160inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2161 SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator pos )
2162{
2163 using blaze::erase;
2164
2165 const Iterator_t<MT> base( pos.base() );
2166
2167 if( base == matrix_.end( i ) )
2168 return pos;
2169
2170 const size_t j( base->index() );
2171
2172 if( i == j ) {
2173 BLAZE_INTERNAL_ASSERT( matrix_.find( i, i ) != matrix_.end( i ), "Missing element detected" );
2174 return Iterator( erase( matrix_, i, base ), matrix_, i );
2175 }
2176
2177 if( SO ) {
2178 BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2179 erase( matrix_, j, matrix_.find( i, j ) );
2180 return Iterator( erase( matrix_, i, base ), matrix_, i );
2181 }
2182 else {
2183 BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2184 erase( matrix_, j, matrix_.find( j, i ) );
2185 return Iterator( erase(matrix_, i, base ), matrix_, i );
2186 }
2187}
2189//*************************************************************************************************
2190
2191
2192//*************************************************************************************************
2206template< typename MT // Type of the adapted sparse matrix
2207 , bool SO > // Storage order of the adapted sparse matrix
2208inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2209 SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last )
2210{
2211 using blaze::erase;
2212
2213 for( auto it=first.base(); it!=last.base(); ++it )
2214 {
2215 const size_t j( it->index() );
2216
2217 if( i == j )
2218 continue;
2219
2220 if( SO ) {
2221 BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2222 erase( matrix_, i, j );
2223 }
2224 else {
2225 BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2226 erase( matrix_, j, i );
2227 }
2228 }
2229
2230 return Iterator( erase( matrix_, i, first.base(), last.base() ), matrix_, i );
2231}
2233//*************************************************************************************************
2234
2235
2236//*************************************************************************************************
2258template< typename MT // Type of the adapted sparse matrix
2259 , bool SO > // Storage order of the adapted sparse matrix
2260template< typename Pred > // Type of the unary predicate
2261inline void SymmetricMatrix<MT,SO,false,true>::erase( Pred predicate )
2262{
2263 using blaze::erase;
2264
2265 erase( matrix_, predicate );
2266
2267 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2268}
2270//*************************************************************************************************
2271
2272
2273//*************************************************************************************************
2301template< typename MT // Type of the adapted sparse matrix
2302 , bool SO > // Storage order of the adapted sparse matrix
2303template< typename Pred > // Type of the unary predicate
2304inline void
2305 SymmetricMatrix<MT,SO,false,true>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2306{
2307 using blaze::erase;
2308
2309 for( auto it=first; it!=last; ++it ) {
2310 const size_t j( it->index() );
2311 if( i != j && predicate( it->value() ) ) {
2312 if( SO )
2313 erase( matrix_, i, j );
2314 else
2315 erase( matrix_, j, i );
2316 }
2317 }
2318
2319 erase( matrix_, i, first.base(), last.base(), predicate );
2320
2321 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2322}
2324//*************************************************************************************************
2325
2326
2327
2328
2329//=================================================================================================
2330//
2331// LOOKUP FUNCTIONS
2332//
2333//=================================================================================================
2334
2335//*************************************************************************************************
2351template< typename MT // Type of the adapted sparse matrix
2352 , bool SO > // Storage order of the adapted sparse matrix
2353inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2354 SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j )
2355{
2356 return Iterator( matrix_.find( i, j ), matrix_, ( SO ? j : i ) );
2357}
2359//*************************************************************************************************
2360
2361
2362//*************************************************************************************************
2378template< typename MT // Type of the adapted sparse matrix
2379 , bool SO > // Storage order of the adapted sparse matrix
2380inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
2381 SymmetricMatrix<MT,SO,false,true>::find( size_t i, size_t j ) const
2382{
2383 return matrix_.find( i, j );
2384}
2386//*************************************************************************************************
2387
2388
2389//*************************************************************************************************
2405template< typename MT // Type of the adapted sparse matrix
2406 , bool SO > // Storage order of the adapted sparse matrix
2407inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2409{
2410 return Iterator( matrix_.lowerBound( i, j ), matrix_, ( SO ? j : i ) );
2411}
2413//*************************************************************************************************
2414
2415
2416//*************************************************************************************************
2432template< typename MT // Type of the adapted sparse matrix
2433 , bool SO > // Storage order of the adapted sparse matrix
2434inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
2435 SymmetricMatrix<MT,SO,false,true>::lowerBound( size_t i, size_t j ) const
2436{
2437 return matrix_.lowerBound( i, j );
2438}
2440//*************************************************************************************************
2441
2442
2443//*************************************************************************************************
2459template< typename MT // Type of the adapted sparse matrix
2460 , bool SO > // Storage order of the adapted sparse matrix
2461inline typename SymmetricMatrix<MT,SO,false,true>::Iterator
2463{
2464 return Iterator( matrix_.upperBound( i, j ), matrix_, ( SO ? j : i ) );
2465}
2467//*************************************************************************************************
2468
2469
2470//*************************************************************************************************
2486template< typename MT // Type of the adapted sparse matrix
2487 , bool SO > // Storage order of the adapted sparse matrix
2488inline typename SymmetricMatrix<MT,SO,false,true>::ConstIterator
2489 SymmetricMatrix<MT,SO,false,true>::upperBound( size_t i, size_t j ) const
2490{
2491 return matrix_.upperBound( i, j );
2492}
2494//*************************************************************************************************
2495
2496
2497
2498
2499//=================================================================================================
2500//
2501// NUMERIC FUNCTIONS
2502//
2503//=================================================================================================
2504
2505//*************************************************************************************************
2511template< typename MT // Type of the adapted sparse matrix
2512 , bool SO > // Storage order of the adapted sparse matrix
2513inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::transpose()
2514{
2515 return *this;
2516}
2518//*************************************************************************************************
2519
2520
2521//*************************************************************************************************
2527template< typename MT // Type of the adapted sparse matrix
2528 , bool SO > // Storage order of the adapted sparse matrix
2529inline SymmetricMatrix<MT,SO,false,true>& SymmetricMatrix<MT,SO,false,true>::ctranspose()
2530{
2531 if( !IsBuiltin_v<ElementType> )
2532 conjugate( matrix_ );
2533
2534 return *this;
2535}
2537//*************************************************************************************************
2538
2539
2540//*************************************************************************************************
2558template< typename MT // Type of the adapted sparse matrix
2559 , bool SO > // Storage order of the adapted sparse matrix
2560template< typename Other > // Data type of the scalar value
2561inline SymmetricMatrix<MT,SO,false,true>&
2562 SymmetricMatrix<MT,SO,false,true>::scale( const Other& scalar )
2563{
2564 matrix_.scale( scalar );
2565 return *this;
2566}
2568//*************************************************************************************************
2569
2570
2571
2572
2573//=================================================================================================
2574//
2575// DEBUGGING FUNCTIONS
2576//
2577//=================================================================================================
2578
2579//*************************************************************************************************
2589template< typename MT // Type of the adapted sparse matrix
2590 , bool SO > // Storage order of the adapted sparse matrix
2591inline bool SymmetricMatrix<MT,SO,false,true>::isIntact() const noexcept
2592{
2593 using blaze::isIntact;
2594
2595 return ( isIntact( matrix_ ) && isSymmetric( matrix_ ) );
2596}
2598//*************************************************************************************************
2599
2600
2601
2602
2603//=================================================================================================
2604//
2605// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2606//
2607//=================================================================================================
2608
2609//*************************************************************************************************
2620template< typename MT // Type of the adapted sparse matrix
2621 , bool SO > // Storage order of the adapted sparse matrix
2622template< typename Other > // Data type of the foreign expression
2623inline bool SymmetricMatrix<MT,SO,false,true>::canAlias( const Other* alias ) const noexcept
2624{
2625 return matrix_.canAlias( alias );
2626}
2628//*************************************************************************************************
2629
2630
2631//*************************************************************************************************
2642template< typename MT // Type of the adapted sparse matrix
2643 , bool SO > // Storage order of the adapted sparse matrix
2644template< typename Other > // Data type of the foreign expression
2645inline bool SymmetricMatrix<MT,SO,false,true>::isAliased( const Other* alias ) const noexcept
2646{
2647 return matrix_.isAliased( alias );
2648}
2650//*************************************************************************************************
2651
2652
2653//*************************************************************************************************
2664template< typename MT // Type of the adapted sparse matrix
2665 , bool SO > // Storage order of the adapted sparse matrix
2666inline bool SymmetricMatrix<MT,SO,false,true>::canSMPAssign() const noexcept
2667{
2668 return matrix_.canSMPAssign();
2669}
2671//*************************************************************************************************
2672
2673} // namespace blaze
2674
2675#endif
Header file for auxiliary alias declarations.
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.
Constraint on the data type.
Header file for the IsBuiltin type trait.
Header file for the IsComputation type trait class.
Header file for the isDefault shim.
Header file for the IsScalar type trait.
Header file for the IsSquare type trait.
Header file for the IsSymmetric 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.
Header file for the ScalarProxy class.
Constraint on the data type.
Compile time assertion.
Header file for the SymmetricElement class.
Header file for the SymmetricValue class.
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 SymmetricMatrix.
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) 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
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
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:1456
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 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
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric_v< T >)
In-place conjugation of the given value/object.
Definition: Conjugate.h:118
constexpr ptrdiff_t Size_v
Auxiliary variable template for the Size type trait.
Definition: Size.h:176
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
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.