Blaze 3.9
SparseNonScalar.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSENONSCALAR_H_
36#define _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSENONSCALAR_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <iterator>
44#include <utility>
45#include <vector>
49#include <blaze/math/Aliases.h>
77#include <blaze/util/Assert.h>
82#include <blaze/util/EnableIf.h>
84#include <blaze/util/mpl/If.h>
86#include <blaze/util/Types.h>
87
88
89namespace blaze {
90
91//=================================================================================================
92//
93// CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES WITH NON-SCALAR ELEMENT TYPE
94//
95//=================================================================================================
96
97//*************************************************************************************************
105template< typename MT // Type of the adapted sparse matrix
106 , bool SO > // Storage order of the adapted sparse matrix
107class SymmetricMatrix<MT,SO,false,false>
108 : public SparseMatrix< SymmetricMatrix<MT,SO,false,false>, SO >
109{
110 private:
111 //**Type definitions****************************************************************************
112 using OT = OppositeType_t<MT>;
113 using TT = TransposeType_t<MT>;
114 using ET = ElementType_t<MT>;
115
117 using MatrixType = typename MT::template Rebind< SharedValue<ET> >::Other;
118 //**********************************************************************************************
119
120 public:
121 //**Type definitions****************************************************************************
122 using This = SymmetricMatrix<MT,SO,false,false>;
123 using BaseType = SparseMatrix<This,SO>;
124 using ResultType = This;
125 using OppositeType = SymmetricMatrix<OT,!SO,false,false>;
126 using TransposeType = SymmetricMatrix<TT,!SO,false,false>;
127 using ElementType = ET;
128 using TagType = TagType_t<MT>;
129 using ReturnType = ReturnType_t<MT>;
130 using CompositeType = const This&;
131 using Reference = NonScalarProxy<MatrixType>;
132 using ConstReference = ConstReference_t<MT>;
133 //**********************************************************************************************
134
135 //**Rebind struct definition********************************************************************
138 template< typename NewType > // Data type of the other matrix
139 struct Rebind {
141 using Other = SymmetricMatrix< typename MT::template Rebind<NewType>::Other >;
142 };
143 //**********************************************************************************************
144
145 //**Resize struct definition********************************************************************
148 template< size_t NewM // Number of rows of the other matrix
149 , size_t NewN > // Number of columns of the other matrix
150 struct Resize {
152 using Other = SymmetricMatrix< typename MT::template Resize<NewM,NewN>::Other >;
153 };
154 //**********************************************************************************************
155
156 //**SharedElement class definition**************************************************************
159 template< typename IteratorType > // Type of the sparse matrix iterator
160 class SharedElement
161 : private SparseElement
162 {
163 public:
164 //**Type definitions*************************************************************************
165 using ValueType = ET;
166 using IndexType = size_t;
167 using Reference = ValueType&;
168 using ConstReference = const ValueType&;
169 using Pointer = SharedElement*;
170 using ConstPointer = const SharedElement*;
171 //*******************************************************************************************
172
173 //**Constructor******************************************************************************
178 inline SharedElement( IteratorType pos )
179 : pos_( pos ) // Iterator to the current sparse symmetric matrix element
180 {}
181 //*******************************************************************************************
182
183 //**Assignment operator**********************************************************************
189 template< typename T > inline SharedElement& operator=( const T& v ) {
190 *pos_->value() = v;
191 return *this;
192 }
193 //*******************************************************************************************
194
195 //**Addition assignment operator*************************************************************
201 template< typename T > inline SharedElement& operator+=( const T& v ) {
202 *pos_->value() += v;
203 return *this;
204 }
205 //*******************************************************************************************
206
207 //**Subtraction assignment operator**********************************************************
213 template< typename T > inline SharedElement& operator-=( const T& v ) {
214 *pos_->value() -= v;
215 return *this;
216 }
217 //*******************************************************************************************
218
219 //**Multiplication assignment operator*******************************************************
225 template< typename T > inline SharedElement& operator*=( const T& v ) {
226 *pos_->value() *= v;
227 return *this;
228 }
229 //*******************************************************************************************
230
231 //**Division assignment operator*************************************************************
237 template< typename T > inline SharedElement& operator/=( const T& v ) {
238 *pos_->value() /= v;
239 return *this;
240 }
241 //*******************************************************************************************
242
243 //**Element access operator******************************************************************
248 inline Pointer operator->() {
249 return this;
250 }
251 //*******************************************************************************************
252
253 //**Element access operator******************************************************************
258 inline ConstPointer operator->() const {
259 return this;
260 }
261 //*******************************************************************************************
262
263 //**Value function***************************************************************************
268 inline Reference value() {
269 return *pos_->value();
270 }
271 //*******************************************************************************************
272
273 //**Value function***************************************************************************
278 inline ConstReference value() const {
279 return *pos_->value();
280 }
281 //*******************************************************************************************
282
283 //**Index function***************************************************************************
288 inline IndexType index() const {
289 return pos_->index();
290 }
291 //*******************************************************************************************
292
293 private:
294 //**Member variables*************************************************************************
295 IteratorType pos_;
296 //*******************************************************************************************
297 };
298 //**********************************************************************************************
299
300 //**SharedIterator class definition*************************************************************
303 template< typename SparseElementType // Type of the underlying sparse elements.
304 , typename IteratorType > // Type of the sparse matrix iterator
305 class SharedIterator
306 {
307 public:
308 //**Type definitions*************************************************************************
309 using IteratorCategory = std::forward_iterator_tag;
310 using ValueType = SparseElementType;
311 using PointerType = SparseElementType;
312 using ReferenceType = SparseElementType;
313 using DifferenceType = ptrdiff_t;
314
315 // STL iterator requirements
316 using iterator_category = IteratorCategory;
317 using value_type = ValueType;
318 using pointer = PointerType;
319 using reference = ReferenceType;
320 using difference_type = DifferenceType;
321 //*******************************************************************************************
322
323 //**Default constructor**********************************************************************
326 inline SharedIterator()
327 : pos_() // Iterator to the current sparse symmetric matrix element
328 {}
329 //*******************************************************************************************
330
331 //**Constructor******************************************************************************
336 inline SharedIterator( IteratorType pos )
337 : pos_( pos ) // Iterator to the current sparse symmetric matrix element
338 {}
339 //*******************************************************************************************
340
341 //**Constructor******************************************************************************
346 template< typename SparseElementType2, typename IteratorType2 >
347 inline SharedIterator( const SharedIterator<SparseElementType2,IteratorType2>& it )
348 : pos_( it.pos_ ) // Iterator to the current sparse symmetric matrix element
349 {}
350 //*******************************************************************************************
351
352 //**Prefix increment operator****************************************************************
357 inline SharedIterator& operator++() {
358 ++pos_;
359 return *this;
360 }
361 //*******************************************************************************************
362
363 //**Postfix increment operator***************************************************************
368 inline const SharedIterator operator++( int ) {
369 const SharedIterator tmp( *this );
370 ++(*this);
371 return tmp;
372 }
373 //*******************************************************************************************
374
375 //**Element access operator******************************************************************
380 inline ReferenceType operator*() const {
381 return ReferenceType( pos_ );
382 }
383 //*******************************************************************************************
384
385 //**Element access operator******************************************************************
390 inline PointerType operator->() const {
391 return PointerType( pos_ );
392 }
393 //*******************************************************************************************
394
395 //**Equality operator************************************************************************
401 inline bool operator==( const SharedIterator& rhs ) const {
402 return pos_ == rhs.pos_;
403 }
404 //*******************************************************************************************
405
406 //**Inequality operator**********************************************************************
412 inline bool operator!=( const SharedIterator& rhs ) const {
413 return !( *this == rhs );
414 }
415 //*******************************************************************************************
416
417 //**Subtraction operator*********************************************************************
423 inline DifferenceType operator-( const SharedIterator& rhs ) const {
424 return pos_ - rhs.pos_;
425 }
426 //*******************************************************************************************
427
428 //**Base function****************************************************************************
433 inline IteratorType base() const {
434 return pos_;
435 }
436 //*******************************************************************************************
437
438 private:
439 //**Member variables*************************************************************************
440 IteratorType pos_;
441 //*******************************************************************************************
442
443 //**Friend declarations**********************************************************************
444 template< typename SparseElementType2, typename IteratorType2 > friend class SharedIterator;
445 //*******************************************************************************************
446 };
447 //**********************************************************************************************
448
449 //**Type definitions****************************************************************************
451 using Iterator = SharedIterator< SharedElement< Iterator_t<MatrixType> >
452 , Iterator_t<MatrixType> >;
453
455 using ConstIterator = SharedIterator< const SharedElement< ConstIterator_t<MatrixType> >
456 , ConstIterator_t<MatrixType> >;
457 //**********************************************************************************************
458
459 //**Compilation flags***************************************************************************
461 static constexpr bool smpAssignable = false;
462 //**********************************************************************************************
463
464 //**Constructors********************************************************************************
467 inline SymmetricMatrix();
468 explicit inline SymmetricMatrix( size_t n );
469 inline SymmetricMatrix( size_t n, size_t nonzeros );
470 inline SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros );
471
472 inline SymmetricMatrix( const SymmetricMatrix& m );
473 inline SymmetricMatrix( SymmetricMatrix&& m ) noexcept;
474
475 template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
476 template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
478 //**********************************************************************************************
479
480 //**Destructor**********************************************************************************
483 ~SymmetricMatrix() = default;
485 //**********************************************************************************************
486
487 //**Data access functions***********************************************************************
490 inline Reference operator()( size_t i, size_t j );
491 inline ConstReference operator()( size_t i, size_t j ) const;
492 inline Reference at( size_t i, size_t j );
493 inline ConstReference at( size_t i, size_t j ) const;
494 inline Iterator begin ( size_t i );
495 inline ConstIterator begin ( size_t i ) const;
496 inline ConstIterator cbegin( size_t i ) const;
497 inline Iterator end ( size_t i );
498 inline ConstIterator end ( size_t i ) const;
499 inline ConstIterator cend ( size_t i ) const;
501 //**********************************************************************************************
502
503 //**Assignment operators************************************************************************
506 inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
507 inline SymmetricMatrix& operator=( SymmetricMatrix&& rhs ) noexcept;
508
509 template< typename MT2 >
510 inline auto operator=( const Matrix<MT2,SO>& rhs )
511 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
512
513 template< typename MT2 >
514 inline auto operator=( const Matrix<MT2,SO>& rhs )
515 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >;
516
517 template< typename MT2 >
518 inline auto operator=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
519
520 template< typename MT2 >
521 inline auto operator+=( const Matrix<MT2,SO>& rhs ) -> SymmetricMatrix&;
522
523 template< typename MT2 >
524 inline auto operator+=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
525
526 template< typename MT2 >
527 inline auto operator-=( const Matrix<MT2,SO>& rhs ) -> SymmetricMatrix&;
528
529 template< typename MT2 >
530 inline auto operator-=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
531
532 template< typename MT2 >
533 inline auto operator%=( const Matrix<MT2,SO>& rhs ) -> SymmetricMatrix&;
534
535 template< typename MT2 >
536 inline auto operator%=( const Matrix<MT2,!SO>& rhs ) -> SymmetricMatrix&;
537
538 template< typename ST >
539 inline auto operator*=( ST rhs ) -> EnableIf_t< IsScalar_v<ST>, SymmetricMatrix& >;
540
541 template< typename ST >
542 inline auto operator/=( ST rhs ) -> EnableIf_t< IsScalar_v<ST>, SymmetricMatrix& >;
544 //**********************************************************************************************
545
546 //**Utility functions***************************************************************************
549 inline size_t rows() const noexcept;
550 inline size_t columns() const noexcept;
551 inline size_t capacity() const noexcept;
552 inline size_t capacity( size_t i ) const noexcept;
553 inline size_t nonZeros() const;
554 inline size_t nonZeros( size_t i ) const;
555 inline void reset();
556 inline void reset( size_t i );
557 inline void clear();
558 inline void resize ( size_t n, bool preserve=true );
559 inline void reserve( size_t nonzeros );
560 inline void reserve( size_t i, size_t nonzeros );
561 inline void trim();
562 inline void trim( size_t i );
563 inline void shrinkToFit();
564 inline void swap( SymmetricMatrix& m ) noexcept;
566 //**********************************************************************************************
567
568 //**Insertion functions*************************************************************************
571 inline Iterator set ( size_t i, size_t j, const ElementType& value );
572 inline Iterator insert ( size_t i, size_t j, const ElementType& value );
573 inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
574 inline void finalize( size_t i );
576 //**********************************************************************************************
577
578 //**Erase functions*****************************************************************************
581 inline void erase( size_t i, size_t j );
582 inline Iterator erase( size_t i, Iterator pos );
583 inline Iterator erase( size_t i, Iterator first, Iterator last );
584
585 template< typename Pred >
586 inline void erase( Pred predicate );
587
588 template< typename Pred >
589 inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
591 //**********************************************************************************************
592
593 //**Lookup functions****************************************************************************
596 inline Iterator find ( size_t i, size_t j );
597 inline ConstIterator find ( size_t i, size_t j ) const;
598 inline Iterator lowerBound( size_t i, size_t j );
599 inline ConstIterator lowerBound( size_t i, size_t j ) const;
600 inline Iterator upperBound( size_t i, size_t j );
601 inline ConstIterator upperBound( size_t i, size_t j ) const;
603 //**********************************************************************************************
604
605 //**Numeric functions***************************************************************************
608 inline SymmetricMatrix& transpose();
609 inline SymmetricMatrix& ctranspose();
610
611 template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
613 //**********************************************************************************************
614
615 //**Debugging functions*************************************************************************
618 inline bool isIntact() const noexcept;
620 //**********************************************************************************************
621
622 //**Expression template evaluation functions****************************************************
625 template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
626 template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
627
628 inline bool canSMPAssign() const noexcept;
630 //**********************************************************************************************
631
632 private:
633 //**Expression template evaluation functions****************************************************
636 template< typename MT2 > void assign( DenseMatrix<MT2,SO>& rhs );
637 template< typename MT2 > void assign( const DenseMatrix<MT2,SO>& rhs );
638 template< typename MT2 > void assign( SparseMatrix<MT2,SO>& rhs );
639 template< typename MT2 > void assign( const SparseMatrix<MT2,SO>& rhs );
641 //**********************************************************************************************
642
643 //**Member variables****************************************************************************
646 MatrixType matrix_;
648 //**********************************************************************************************
649
650 //**Compile time checks*************************************************************************
666 BLAZE_STATIC_ASSERT( ( Size_v<MT,0UL> == Size_v<MT,1UL> ) );
667 //**********************************************************************************************
668};
670//*************************************************************************************************
671
672
673
674
675//=================================================================================================
676//
677// CONSTRUCTORS
678//
679//=================================================================================================
680
681//*************************************************************************************************
685template< typename MT // Type of the adapted sparse matrix
686 , bool SO > // Storage order of the adapted sparse matrix
687inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix()
688 : matrix_() // The adapted sparse matrix
689{
690 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
691}
693//*************************************************************************************************
694
695
696//*************************************************************************************************
704template< typename MT // Type of the adapted sparse matrix
705 , bool SO > // Storage order of the adapted sparse matrix
706inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n )
707 : matrix_( n, n ) // The adapted sparse matrix
708{
710
711 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
712}
714//*************************************************************************************************
715
716
717//*************************************************************************************************
726template< typename MT // Type of the adapted sparse matrix
727 , bool SO > // Storage order of the adapted sparse matrix
728inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n, size_t nonzeros )
729 : matrix_( n, n, nonzeros ) // The adapted sparse matrix
730{
732
733 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
734}
736//*************************************************************************************************
737
738
739//*************************************************************************************************
750template< typename MT // Type of the adapted sparse matrix
751 , bool SO > // Storage order of the adapted sparse matrix
752inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
753 : matrix_( n, n, nonzeros ) // The adapted sparse matrix
754{
756
757 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
758}
760//*************************************************************************************************
761
762
763//*************************************************************************************************
769template< typename MT // Type of the adapted sparse matrix
770 , bool SO > // Storage order of the adapted sparse matrix
771inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const SymmetricMatrix& m )
772 : matrix_() // The adapted sparse matrix
773{
774 using blaze::resize;
775
776 resize( matrix_, m.rows(), m.columns() );
777 assign( m );
778
779 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
780 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
781}
783//*************************************************************************************************
784
785
786//*************************************************************************************************
792template< typename MT // Type of the adapted sparse matrix
793 , bool SO > // Storage order of the adapted sparse matrix
794inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( SymmetricMatrix&& m ) noexcept
795 : matrix_( std::move( m.matrix_ ) ) // The adapted sparse matrix
796{
797 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
798 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
799}
801//*************************************************************************************************
802
803
804//*************************************************************************************************
814template< typename MT // Type of the adapted sparse matrix
815 , bool SO > // Storage order of the adapted sparse matrix
816template< typename MT2 > // Type of the foreign matrix
817inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const Matrix<MT2,SO>& m )
818 : matrix_() // The adapted sparse matrix
819{
820 using blaze::resize;
821
822 using RT = RemoveAdaptor_t< ResultType_t<MT2> >;
823 using Tmp = If_t< IsComputation_v<MT2>, RT, const MT2& >;
824
825 Tmp tmp( *m );
826
827 if( !IsSymmetric_v<MT2> && !isSymmetric( tmp ) ) {
828 BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
829 }
830
831 resize( matrix_, tmp.rows(), tmp.columns() );
832 assign( tmp );
833
834 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
835 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
836}
838//*************************************************************************************************
839
840
841//*************************************************************************************************
851template< typename MT // Type of the adapted sparse matrix
852 , bool SO > // Storage order of the adapted sparse matrix
853template< typename MT2 > // Type of the foreign matrix
854inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
855 : matrix_() // The adapted sparse matrix
856{
857 using blaze::resize;
858
859 using RT = RemoveAdaptor_t< ResultType_t<MT2> >;
860 using Tmp = If_t< IsComputation_v<MT2>, RT, const MT2& >;
861
862 Tmp tmp( *m );
863
864 if( !IsSymmetric_v<MT2> && !isSymmetric( tmp ) ) {
865 BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
866 }
867
868 resize( matrix_, tmp.rows(), tmp.columns() );
869 assign( trans( tmp ) );
870
871 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
872 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
873}
875//*************************************************************************************************
876
877
878
879
880//=================================================================================================
881//
882// DATA ACCESS FUNCTIONS
883//
884//=================================================================================================
885
886//*************************************************************************************************
901template< typename MT // Type of the adapted sparse matrix
902 , bool SO > // Storage order of the adapted sparse matrix
903inline typename SymmetricMatrix<MT,SO,false,false>::Reference
904 SymmetricMatrix<MT,SO,false,false>::operator()( size_t i, size_t j )
905{
906 BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
907 BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
908
909 return Reference( matrix_, i, j );
910}
912//*************************************************************************************************
913
914
915//*************************************************************************************************
930template< typename MT // Type of the adapted sparse matrix
931 , bool SO > // Storage order of the adapted sparse matrix
932inline typename SymmetricMatrix<MT,SO,false,false>::ConstReference
933 SymmetricMatrix<MT,SO,false,false>::operator()( size_t i, size_t j ) const
934{
935 BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
936 BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
937
938 return *matrix_(i,j);
939}
941//*************************************************************************************************
942
943
944//*************************************************************************************************
960template< typename MT // Type of the adapted dense matrix
961 , bool SO > // Storage order of the adapted dense matrix
962inline typename SymmetricMatrix<MT,SO,false,false>::Reference
963 SymmetricMatrix<MT,SO,false,false>::at( size_t i, size_t j )
964{
965 if( i >= rows() ) {
966 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
967 }
968 if( j >= columns() ) {
969 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
970 }
971 return (*this)(i,j);
972}
974//*************************************************************************************************
975
976
977//*************************************************************************************************
993template< typename MT // Type of the adapted dense matrix
994 , bool SO > // Storage order of the adapted dense matrix
995inline typename SymmetricMatrix<MT,SO,false,false>::ConstReference
996 SymmetricMatrix<MT,SO,false,false>::at( size_t i, size_t j ) const
997{
998 if( i >= rows() ) {
999 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1000 }
1001 if( j >= columns() ) {
1002 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1003 }
1004 return (*this)(i,j);
1005}
1007//*************************************************************************************************
1008
1009
1010//*************************************************************************************************
1022template< typename MT // Type of the adapted sparse matrix
1023 , bool SO > // Storage order of the adapted sparse matrix
1024inline typename SymmetricMatrix<MT,SO,false,false>::Iterator
1026{
1027 return Iterator( matrix_.begin(i) );
1028}
1030//*************************************************************************************************
1031
1032
1033//*************************************************************************************************
1045template< typename MT // Type of the adapted sparse matrix
1046 , bool SO > // Storage order of the adapted sparse matrix
1047inline typename SymmetricMatrix<MT,SO,false,false>::ConstIterator
1049{
1050 return ConstIterator( matrix_.begin(i) );
1051}
1053//*************************************************************************************************
1054
1055
1056//*************************************************************************************************
1068template< typename MT // Type of the adapted sparse matrix
1069 , bool SO > // Storage order of the adapted sparse matrix
1070inline typename SymmetricMatrix<MT,SO,false,false>::ConstIterator
1072{
1073 return ConstIterator( matrix_.cbegin(i) );
1074}
1076//*************************************************************************************************
1077
1078
1079//*************************************************************************************************
1091template< typename MT // Type of the adapted sparse matrix
1092 , bool SO > // Storage order of the adapted sparse matrix
1093inline typename SymmetricMatrix<MT,SO,false,false>::Iterator
1095{
1096 return Iterator( matrix_.end(i) );
1097}
1099//*************************************************************************************************
1100
1101
1102//*************************************************************************************************
1114template< typename MT // Type of the adapted sparse matrix
1115 , bool SO > // Storage order of the adapted sparse matrix
1116inline typename SymmetricMatrix<MT,SO,false,false>::ConstIterator
1118{
1119 return ConstIterator( matrix_.end(i) );
1120}
1122//*************************************************************************************************
1123
1124
1125//*************************************************************************************************
1137template< typename MT // Type of the adapted sparse matrix
1138 , bool SO > // Storage order of the adapted sparse matrix
1139inline typename SymmetricMatrix<MT,SO,false,false>::ConstIterator
1141{
1142 return ConstIterator( matrix_.cend(i) );
1143}
1145//*************************************************************************************************
1146
1147
1148
1149
1150//=================================================================================================
1151//
1152// ASSIGNMENT OPERATORS
1153//
1154//=================================================================================================
1155
1156//*************************************************************************************************
1166template< typename MT // Type of the adapted sparse matrix
1167 , bool SO > // Storage order of the adapted sparse matrix
1168inline SymmetricMatrix<MT,SO,false,false>&
1169 SymmetricMatrix<MT,SO,false,false>::operator=( const SymmetricMatrix& rhs )
1170{
1171 using blaze::resize;
1172
1173 if( &rhs == this ) return *this;
1174
1175 resize( matrix_, rhs.rows(), rhs.columns() );
1176 reset();
1177 assign( rhs );
1178
1179 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1180 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1181
1182 return *this;
1183}
1185//*************************************************************************************************
1186
1187
1188//*************************************************************************************************
1195template< typename MT // Type of the adapted sparse matrix
1196 , bool SO > // Storage order of the adapted sparse matrix
1197inline SymmetricMatrix<MT,SO,false,false>&
1198 SymmetricMatrix<MT,SO,false,false>::operator=( SymmetricMatrix&& rhs ) noexcept
1199{
1200 matrix_ = std::move( rhs.matrix_ );
1201
1202 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1203 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1204
1205 return *this;
1206}
1208//*************************************************************************************************
1209
1210
1211//*************************************************************************************************
1225template< typename MT // Type of the adapted sparse matrix
1226 , bool SO > // Storage order of the adapted sparse matrix
1227template< typename MT2 > // Type of the right-hand side matrix
1228inline auto SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1229 -> DisableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1230{
1231 using blaze::resize;
1232
1233 if( !IsSymmetric_v<MT2> && !isSymmetric( *rhs ) ) {
1234 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1235 }
1236
1237 if( (*rhs).canAlias( this ) ) {
1238 SymmetricMatrix tmp( *rhs );
1239 swap( tmp );
1240 }
1241 else {
1242 resize( matrix_, (*rhs).rows(), (*rhs).columns() );
1243 reset();
1244 assign( *rhs );
1245 }
1246
1247 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1248 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1249
1250 return *this;
1251}
1253//*************************************************************************************************
1254
1255
1256//*************************************************************************************************
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,false>::operator=( const Matrix<MT2,SO>& rhs )
1274 -> EnableIf_t< IsComputation_v<MT2>, SymmetricMatrix& >
1275{
1276 using blaze::resize;
1277
1278 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1279 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1280 }
1281
1282 const ResultType_t<MT2> tmp( *rhs );
1283
1284 if( !IsSymmetric_v<MT2> && !isSymmetric( tmp ) ) {
1285 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1286 }
1287
1288 resize( matrix_, tmp.rows(), tmp.columns() );
1289 reset();
1290 assign( tmp );
1291
1292 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1293 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1294
1295 return *this;
1296}
1298//*************************************************************************************************
1299
1300
1301//*************************************************************************************************
1315template< typename MT // Type of the adapted sparse matrix
1316 , bool SO > // Storage order of the adapted sparse matrix
1317template< typename MT2 > // Type of the right-hand side matrix
1318inline auto SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,!SO>& rhs )
1319 -> SymmetricMatrix&
1320{
1321 return this->operator=( trans( *rhs ) );
1322}
1324//*************************************************************************************************
1325
1326
1327//*************************************************************************************************
1340template< typename MT // Type of the adapted sparse matrix
1341 , bool SO > // Storage order of the adapted sparse matrix
1342template< typename MT2 > // Type of the right-hand side matrix
1343inline auto SymmetricMatrix<MT,SO,false,false>::operator+=( const Matrix<MT2,SO>& rhs )
1344 -> SymmetricMatrix&
1345{
1346 using blaze::resize;
1347
1348 using Tmp = AddTrait_t< MT, ResultType_t<MT2> >;
1349
1350 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1351 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1352 }
1353
1354 Tmp tmp( (*this) + *rhs );
1355
1356 if( !IsSymmetric_v<Tmp> && !isSymmetric( tmp ) ) {
1357 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1358 }
1359
1360 resize( matrix_, tmp.rows(), tmp.columns() );
1361 reset();
1362 assign( tmp );
1363
1364 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1365 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1366
1367 return *this;
1368}
1370//*************************************************************************************************
1371
1372
1373//*************************************************************************************************
1387template< typename MT // Type of the adapted sparse matrix
1388 , bool SO > // Storage order of the adapted sparse matrix
1389template< typename MT2 > // Type of the right-hand side matrix
1390inline auto SymmetricMatrix<MT,SO,false,false>::operator+=( const Matrix<MT2,!SO>& rhs )
1391 -> SymmetricMatrix&
1392{
1393 return this->operator+=( trans( *rhs ) );
1394}
1396//*************************************************************************************************
1397
1398
1399//*************************************************************************************************
1412template< typename MT // Type of the adapted sparse matrix
1413 , bool SO > // Storage order of the adapted sparse matrix
1414template< typename MT2 > // Type of the right-hand side matrix
1415inline auto SymmetricMatrix<MT,SO,false,false>::operator-=( const Matrix<MT2,SO>& rhs )
1416 -> SymmetricMatrix&
1417{
1418 using blaze::resize;
1419
1420 using Tmp = SubTrait_t< MT, ResultType_t<MT2> >;
1421
1422 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1423 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1424 }
1425
1426 Tmp tmp( (*this) - *rhs );
1427
1428 if( !IsSymmetric_v<Tmp> && !isSymmetric( tmp ) ) {
1429 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1430 }
1431
1432 resize( matrix_, tmp.rows(), tmp.columns() );
1433 reset();
1434 assign( tmp );
1435
1436 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1437 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1438
1439 return *this;
1440}
1442//*************************************************************************************************
1443
1444
1445//*************************************************************************************************
1459template< typename MT // Type of the adapted sparse matrix
1460 , bool SO > // Storage order of the adapted sparse matrix
1461template< typename MT2 > // Type of the right-hand side matrix
1462inline auto SymmetricMatrix<MT,SO,false,false>::operator-=( const Matrix<MT2,!SO>& rhs )
1463 -> SymmetricMatrix&
1464{
1465 return this->operator-=( trans( *rhs ) );
1466}
1468//*************************************************************************************************
1469
1470
1471//*************************************************************************************************
1484template< typename MT // Type of the adapted sparse matrix
1485 , bool SO > // Storage order of the adapted sparse matrix
1486template< typename MT2 > // Type of the right-hand side matrix
1487inline auto SymmetricMatrix<MT,SO,false,false>::operator%=( const Matrix<MT2,SO>& rhs )
1488 -> SymmetricMatrix&
1489{
1490 using blaze::resize;
1491
1492 using Tmp = SchurTrait_t< MT, ResultType_t<MT2> >;
1493
1494 if( !IsSquare_v<MT2> && !isSquare( *rhs ) ) {
1495 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1496 }
1497
1498 Tmp tmp( (*this) % *rhs );
1499
1500 if( !IsSymmetric_v<Tmp> && !isSymmetric( tmp ) ) {
1501 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1502 }
1503
1504 resize( matrix_, tmp.rows(), tmp.columns() );
1505 reset();
1506 assign( tmp );
1507
1508 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1509 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1510
1511 return *this;
1512}
1514//*************************************************************************************************
1515
1516
1517//*************************************************************************************************
1531template< typename MT // Type of the adapted sparse matrix
1532 , bool SO > // Storage order of the adapted sparse matrix
1533template< typename MT2 > // Type of the right-hand side matrix
1534inline auto SymmetricMatrix<MT,SO,false,false>::operator%=( const Matrix<MT2,!SO>& rhs )
1535 -> SymmetricMatrix&
1536{
1537 return this->operator%=( trans( *rhs ) );
1538}
1540//*************************************************************************************************
1541
1542
1543//*************************************************************************************************
1551template< typename MT // Type of the adapted sparse matrix
1552 , bool SO > // Storage order of the adapted sparse matrix
1553template< typename ST > // Data type of the right-hand side scalar
1555 -> EnableIf_t< IsScalar_v<ST>, SymmetricMatrix& >
1556{
1557 for( size_t i=0UL; i<rows(); ++i ) {
1558 const auto last( matrix_.upperBound(i,i) );
1559 for( auto element=matrix_.begin(i); element!=last; ++element )
1560 *element->value() *= rhs;
1561 }
1562
1563 return *this;
1564}
1566//*************************************************************************************************
1567
1568
1569//*************************************************************************************************
1577template< typename MT // Type of the adapted sparse matrix
1578 , bool SO > // Storage order of the adapted sparse matrix
1579template< typename ST > // Data type of the right-hand side scalar
1581 -> EnableIf_t< IsScalar_v<ST>, SymmetricMatrix& >
1582{
1583 BLAZE_USER_ASSERT( !isZero( rhs ), "Division by zero detected" );
1584
1585 for( size_t i=0UL; i<rows(); ++i ) {
1586 const auto last( matrix_.upperBound(i,i) );
1587 for( auto element=matrix_.begin(i); element!=last; ++element )
1588 *element->value() /= rhs;
1589 }
1590
1591 return *this;
1592}
1594//*************************************************************************************************
1595
1596
1597
1598
1599//=================================================================================================
1600//
1601// UTILITY FUNCTIONS
1602//
1603//=================================================================================================
1604
1605//*************************************************************************************************
1611template< typename MT // Type of the adapted sparse matrix
1612 , bool SO > // Storage order of the adapted sparse matrix
1613inline size_t SymmetricMatrix<MT,SO,false,false>::rows() const noexcept
1614{
1615 return matrix_.rows();
1616}
1618//*************************************************************************************************
1619
1620
1621//*************************************************************************************************
1627template< typename MT // Type of the adapted sparse matrix
1628 , bool SO > // Storage order of the adapted sparse matrix
1629inline size_t SymmetricMatrix<MT,SO,false,false>::columns() const noexcept
1630{
1631 return matrix_.columns();
1632}
1634//*************************************************************************************************
1635
1636
1637//*************************************************************************************************
1643template< typename MT // Type of the adapted sparse matrix
1644 , bool SO > // Storage order of the adapted sparse matrix
1645inline size_t SymmetricMatrix<MT,SO,false,false>::capacity() const noexcept
1646{
1647 return matrix_.capacity();
1648}
1650//*************************************************************************************************
1651
1652
1653//*************************************************************************************************
1664template< typename MT // Type of the adapted sparse matrix
1665 , bool SO > // Storage order of the adapted sparse matrix
1666inline size_t SymmetricMatrix<MT,SO,false,false>::capacity( size_t i ) const noexcept
1667{
1668 return matrix_.capacity(i);
1669}
1671//*************************************************************************************************
1672
1673
1674//*************************************************************************************************
1680template< typename MT // Type of the adapted sparse matrix
1681 , bool SO > // Storage order of the adapted sparse matrix
1683{
1684 return matrix_.nonZeros();
1685}
1687//*************************************************************************************************
1688
1689
1690//*************************************************************************************************
1702template< typename MT // Type of the adapted sparse matrix
1703 , bool SO > // Storage order of the adapted sparse matrix
1704inline size_t SymmetricMatrix<MT,SO,false,false>::nonZeros( size_t i ) const
1705{
1706 return matrix_.nonZeros(i);
1707}
1709//*************************************************************************************************
1710
1711
1712//*************************************************************************************************
1718template< typename MT // Type of the adapted sparse matrix
1719 , bool SO > // Storage order of the adapted sparse matrix
1721{
1722 matrix_.reset();
1723}
1725//*************************************************************************************************
1726
1727
1728//*************************************************************************************************
1768template< typename MT // Type of the adapted sparse matrix
1769 , bool SO > // Storage order of the adapted sparse matrix
1770inline void SymmetricMatrix<MT,SO,false,false>::reset( size_t i )
1771{
1772 using blaze::erase;
1773
1774 for( auto it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1775 {
1776 const size_t j( it->index() );
1777
1778 if( i == j )
1779 continue;
1780
1781 if( SO ) {
1782 const Iterator_t<MatrixType> pos( matrix_.find( i, j ) );
1783 BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1784 erase( matrix_, j, pos );
1785 }
1786 else {
1787 const Iterator_t<MatrixType> pos( matrix_.find( j, i ) );
1788 BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1789 erase( matrix_, j, pos );
1790 }
1791 }
1792
1793 matrix_.reset( i );
1794}
1796//*************************************************************************************************
1797
1798
1799//*************************************************************************************************
1807template< typename MT // Type of the adapted sparse matrix
1808 , bool SO > // Storage order of the adapted sparse matrix
1810{
1811 matrix_.clear();
1812
1813 BLAZE_INTERNAL_ASSERT( matrix_.rows() == 0UL, "Invalid number of rows" );
1814 BLAZE_INTERNAL_ASSERT( matrix_.columns() == 0UL, "Invalid number of columns" );
1815}
1817//*************************************************************************************************
1818
1819
1820//*************************************************************************************************
1835template< typename MT // Type of the adapted sparse matrix
1836 , bool SO > // Storage order of the adapted sparse matrix
1837void SymmetricMatrix<MT,SO,false,false>::resize( size_t n, bool preserve )
1838{
1840
1841 MAYBE_UNUSED( preserve );
1842
1843 BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1844
1845 matrix_.resize( n, n, true );
1846}
1848//*************************************************************************************************
1849
1850
1851//*************************************************************************************************
1862template< typename MT // Type of the adapted sparse matrix
1863 , bool SO > // Storage order of the adapted sparse matrix
1864inline void SymmetricMatrix<MT,SO,false,false>::reserve( size_t nonzeros )
1865{
1866 matrix_.reserve( nonzeros );
1867}
1869//*************************************************************************************************
1870
1871
1872//*************************************************************************************************
1886template< typename MT // Type of the adapted sparse matrix
1887 , bool SO > // Storage order of the adapted sparse matrix
1888inline void SymmetricMatrix<MT,SO,false,false>::reserve( size_t i, size_t nonzeros )
1889{
1890 matrix_.reserve( i, nonzeros );
1891}
1893//*************************************************************************************************
1894
1895
1896//*************************************************************************************************
1907template< typename MT // Type of the adapted sparse matrix
1908 , bool SO > // Storage order of the adapted sparse matrix
1909inline void SymmetricMatrix<MT,SO,false,false>::trim()
1910{
1911 matrix_.trim();
1912}
1914//*************************************************************************************************
1915
1916
1917//*************************************************************************************************
1929template< typename MT // Type of the adapted sparse matrix
1930 , bool SO > // Storage order of the adapted sparse matrix
1931inline void SymmetricMatrix<MT,SO,false,false>::trim( size_t i )
1932{
1933 matrix_.trim( i );
1934}
1936//*************************************************************************************************
1937
1938
1939//*************************************************************************************************
1949template< typename MT // Type of the adapted sparse matrix
1950 , bool SO > // Storage order of the adapted sparse matrix
1952{
1953 matrix_.shrinkToFit();
1954}
1956//*************************************************************************************************
1957
1958
1959//*************************************************************************************************
1966template< typename MT // Type of the adapted sparse matrix
1967 , bool SO > // Storage order of the adapted sparse matrix
1968inline void SymmetricMatrix<MT,SO,false,false>::swap( SymmetricMatrix& m ) noexcept
1969{
1970 using std::swap;
1971
1972 swap( matrix_, m.matrix_ );
1973}
1975//*************************************************************************************************
1976
1977
1978
1979
1980//=================================================================================================
1981//
1982// INSERTION FUNCTIONS
1983//
1984//=================================================================================================
1985
1986//*************************************************************************************************
2000template< typename MT // Type of the adapted sparse matrix
2001 , bool SO > // Storage order of the adapted sparse matrix
2002inline typename SymmetricMatrix<MT,SO,false,false>::Iterator
2003 SymmetricMatrix<MT,SO,false,false>::set( size_t i, size_t j, const ElementType& value )
2004{
2005 SharedValue<ET> shared( value );
2006
2007 if( i != j )
2008 matrix_.set( j, i, shared );
2009
2010 return Iterator( matrix_.set( i, j, shared ) );
2011}
2013//*************************************************************************************************
2014
2015
2016//*************************************************************************************************
2031template< typename MT // Type of the adapted sparse matrix
2032 , bool SO > // Storage order of the adapted sparse matrix
2033inline typename SymmetricMatrix<MT,SO,false,false>::Iterator
2034 SymmetricMatrix<MT,SO,false,false>::insert( size_t i, size_t j, const ElementType& value )
2035{
2036 SharedValue<ET> shared( value );
2037
2038 if( i != j )
2039 matrix_.insert( j, i, shared );
2040
2041 return Iterator( matrix_.insert( i, j, shared ) );
2042}
2044//*************************************************************************************************
2045
2046
2047//*************************************************************************************************
2102template< typename MT // Type of the adapted sparse matrix
2103 , bool SO > // Storage order of the adapted sparse matrix
2104inline void SymmetricMatrix<MT,SO,false,false>::append( size_t i, size_t j, const ElementType& value, bool check )
2105{
2106 SharedValue<ET> shared( value );
2107
2108 matrix_.append( i, j, shared, check );
2109 if( i != j && ( !check || !isDefault<strict>( value ) ) )
2110 matrix_.insert( j, i, shared );
2111}
2113//*************************************************************************************************
2114
2115
2116//*************************************************************************************************
2130template< typename MT // Type of the adapted sparse matrix
2131 , bool SO > // Storage order of the adapted sparse matrix
2132inline void SymmetricMatrix<MT,SO,false,false>::finalize( size_t i )
2133{
2134 matrix_.trim( i );
2135}
2137//*************************************************************************************************
2138
2139
2140
2141
2142//=================================================================================================
2143//
2144// ERASE FUNCTIONS
2145//
2146//=================================================================================================
2147
2148//*************************************************************************************************
2158template< typename MT // Type of the adapted sparse matrix
2159 , bool SO > // Storage order of the adapted sparse matrix
2160inline void SymmetricMatrix<MT,SO,false,false>::erase( size_t i, size_t j )
2161{
2162 using blaze::erase;
2163
2164 erase( matrix_, i, j );
2165 if( i != j )
2166 erase( matrix_, j, i );
2167}
2169//*************************************************************************************************
2170
2171
2172//*************************************************************************************************
2184template< typename MT // Type of the adapted sparse matrix
2185 , bool SO > // Storage order of the adapted sparse matrix
2186inline typename SymmetricMatrix<MT,SO,false,false>::Iterator
2187 SymmetricMatrix<MT,SO,false,false>::erase( size_t i, Iterator pos )
2188{
2189 using blaze::erase;
2190
2191 if( pos == end( i ) )
2192 return pos;
2193
2194 const size_t j( pos->index() );
2195
2196 if( i == j )
2197 return Iterator( erase( matrix_, i, pos.base() ) );
2198
2199 if( SO ) {
2200 BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2201 erase( matrix_, j, matrix_.find( i, j ) );
2202 return Iterator( erase( matrix_, i, pos.base() ) );
2203 }
2204 else {
2205 BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2206 erase( matrix_, j, matrix_.find( j, i ) );
2207 return Iterator( erase( matrix_, i, pos.base() ) );
2208 }
2209}
2211//*************************************************************************************************
2212
2213
2214//*************************************************************************************************
2228template< typename MT // Type of the adapted sparse matrix
2229 , bool SO > // Storage order of the adapted sparse matrix
2230inline typename SymmetricMatrix<MT,SO,false,false>::Iterator
2231 SymmetricMatrix<MT,SO,false,false>::erase( size_t i, Iterator first, Iterator last )
2232{
2233 using blaze::erase;
2234
2235 for( auto it=first; it!=last; ++it )
2236 {
2237 const size_t j( it->index() );
2238
2239 if( i == j )
2240 continue;
2241
2242 if( SO ) {
2243 BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
2244 erase( matrix_, i, j );
2245 }
2246 else {
2247 BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
2248 erase( matrix_, j, i );
2249 }
2250 }
2251
2252 return Iterator( erase( matrix_, i, first.base(), last.base() ) );
2253}
2255//*************************************************************************************************
2256
2257
2258//*************************************************************************************************
2272template< typename MT // Type of the adapted sparse matrix
2273 , bool SO > // Storage order of the adapted sparse matrix
2274template< typename Pred > // Type of the unary predicate
2275inline void SymmetricMatrix<MT,SO,false,false>::erase( Pred predicate )
2276{
2277 using blaze::erase;
2278
2279 erase( matrix_, [predicate=predicate]( const SharedValue<ET>& value ) {
2280 return predicate( *value );
2281 } );
2282
2283 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2284}
2286//*************************************************************************************************
2287
2288
2289//*************************************************************************************************
2308template< typename MT // Type of the adapted sparse matrix
2309 , bool SO > // Storage order of the adapted sparse matrix
2310template< typename Pred > // Type of the unary predicate
2311inline void
2312 SymmetricMatrix<MT,SO,false,false>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
2313{
2314 using blaze::erase;
2315
2316 for( auto it=first; it!=last; ++it ) {
2317 const size_t j( it->index() );
2318 if( i != j && predicate( it->value() ) ) {
2319 if( SO )
2320 erase( matrix_, i, j );
2321 else
2322 erase( matrix_, j, i );
2323 }
2324 }
2325
2326 erase( matrix_, i, first.base(), last.base(),
2327 [predicate=predicate]( const SharedValue<ET>& value ) {
2328 return predicate( *value );
2329 } );
2330
2331 BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
2332}
2334//*************************************************************************************************
2335
2336
2337
2338
2339//=================================================================================================
2340//
2341// LOOKUP FUNCTIONS
2342//
2343//=================================================================================================
2344
2345//*************************************************************************************************
2361template< typename MT // Type of the adapted sparse matrix
2362 , bool SO > // Storage order of the adapted sparse matrix
2363inline typename SymmetricMatrix<MT,SO,false,false>::Iterator
2364 SymmetricMatrix<MT,SO,false,false>::find( size_t i, size_t j )
2365{
2366 return Iterator( matrix_.find( i, j ) );
2367}
2369//*************************************************************************************************
2370
2371
2372//*************************************************************************************************
2388template< typename MT // Type of the adapted sparse matrix
2389 , bool SO > // Storage order of the adapted sparse matrix
2390inline typename SymmetricMatrix<MT,SO,false,false>::ConstIterator
2391 SymmetricMatrix<MT,SO,false,false>::find( size_t i, size_t j ) const
2392{
2393 return ConstIterator( matrix_.find( i, j ) );
2394}
2396//*************************************************************************************************
2397
2398
2399//*************************************************************************************************
2415template< typename MT // Type of the adapted sparse matrix
2416 , bool SO > // Storage order of the adapted sparse matrix
2417inline typename SymmetricMatrix<MT,SO,false,false>::Iterator
2419{
2420 return Iterator( matrix_.lowerBound( i, j ) );
2421}
2423//*************************************************************************************************
2424
2425
2426//*************************************************************************************************
2442template< typename MT // Type of the adapted sparse matrix
2443 , bool SO > // Storage order of the adapted sparse matrix
2444inline typename SymmetricMatrix<MT,SO,false,false>::ConstIterator
2445 SymmetricMatrix<MT,SO,false,false>::lowerBound( size_t i, size_t j ) const
2446{
2447 return ConstIterator( matrix_.lowerBound( i, j ) );
2448}
2450//*************************************************************************************************
2451
2452
2453//*************************************************************************************************
2469template< typename MT // Type of the adapted sparse matrix
2470 , bool SO > // Storage order of the adapted sparse matrix
2471inline typename SymmetricMatrix<MT,SO,false,false>::Iterator
2473{
2474 return Iterator( matrix_.upperBound( i, j ) );
2475}
2477//*************************************************************************************************
2478
2479
2480//*************************************************************************************************
2496template< typename MT // Type of the adapted sparse matrix
2497 , bool SO > // Storage order of the adapted sparse matrix
2498inline typename SymmetricMatrix<MT,SO,false,false>::ConstIterator
2499 SymmetricMatrix<MT,SO,false,false>::upperBound( size_t i, size_t j ) const
2500{
2501 return ConstIterator( matrix_.upperBound( i, j ) );
2502}
2504//*************************************************************************************************
2505
2506
2507
2508
2509//=================================================================================================
2510//
2511// NUMERIC FUNCTIONS
2512//
2513//=================================================================================================
2514
2515//*************************************************************************************************
2521template< typename MT // Type of the adapted sparse matrix
2522 , bool SO > // Storage order of the adapted sparse matrix
2523inline SymmetricMatrix<MT,SO,false,false>& SymmetricMatrix<MT,SO,false,false>::transpose()
2524{
2525 return *this;
2526}
2528//*************************************************************************************************
2529
2530
2531//*************************************************************************************************
2537template< typename MT // Type of the adapted sparse matrix
2538 , bool SO > // Storage order of the adapted sparse matrix
2539inline SymmetricMatrix<MT,SO,false,false>& SymmetricMatrix<MT,SO,false,false>::ctranspose()
2540{
2541 for( size_t i=0UL; i<rows(); ++i ) {
2542 const auto last( matrix_.upperBound(i,i) );
2543 for( auto element=matrix_.begin(i); element!=last; ++element )
2544 conjugate( *element->value() );
2545 }
2546
2547 return *this;
2548}
2550//*************************************************************************************************
2551
2552
2553//*************************************************************************************************
2571template< typename MT // Type of the adapted sparse matrix
2572 , bool SO > // Storage order of the adapted sparse matrix
2573template< typename Other > // Data type of the scalar value
2574inline SymmetricMatrix<MT,SO,false,false>&
2575 SymmetricMatrix<MT,SO,false,false>::scale( const Other& scalar )
2576{
2577 for( size_t i=0UL; i<rows(); ++i ) {
2578 const auto last( matrix_.upperBound(i,i) );
2579 for( auto element=matrix_.begin(i); element!=last; ++element )
2580 ( *element->value() ).scale( scalar );
2581 }
2582
2583 return *this;
2584}
2586//*************************************************************************************************
2587
2588
2589
2590
2591//=================================================================================================
2592//
2593// DEBUGGING FUNCTIONS
2594//
2595//=================================================================================================
2596
2597//*************************************************************************************************
2607template< typename MT // Type of the adapted dense matrix
2608 , bool SO > // Storage order of the adapted dense matrix
2609inline bool SymmetricMatrix<MT,SO,false,false>::isIntact() const noexcept
2610{
2611 using blaze::isIntact;
2612
2613 return ( isIntact( matrix_ ) && isSymmetric( matrix_ ) );
2614}
2616//*************************************************************************************************
2617
2618
2619
2620
2621//=================================================================================================
2622//
2623// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2624//
2625//=================================================================================================
2626
2627//*************************************************************************************************
2638template< typename MT // Type of the adapted sparse matrix
2639 , bool SO > // Storage order of the adapted sparse matrix
2640template< typename Other > // Data type of the foreign expression
2641inline bool SymmetricMatrix<MT,SO,false,false>::canAlias( const Other* alias ) const noexcept
2642{
2643 return matrix_.canAlias( alias );
2644}
2646//*************************************************************************************************
2647
2648
2649//*************************************************************************************************
2660template< typename MT // Type of the adapted sparse matrix
2661 , bool SO > // Storage order of the adapted sparse matrix
2662template< typename Other > // Data type of the foreign expression
2663inline bool SymmetricMatrix<MT,SO,false,false>::isAliased( const Other* alias ) const noexcept
2664{
2665 return matrix_.isAliased( alias );
2666}
2668//*************************************************************************************************
2669
2670
2671//*************************************************************************************************
2682template< typename MT // Type of the adapted sparse matrix
2683 , bool SO > // Storage order of the adapted sparse matrix
2684inline bool SymmetricMatrix<MT,SO,false,false>::canSMPAssign() const noexcept
2685{
2686 return matrix_.canSMPAssign();
2687}
2689//*************************************************************************************************
2690
2691
2692//*************************************************************************************************
2704template< typename MT // Type of the adapted sparse matrix
2705 , bool SO > // Storage order of the adapted sparse matrix
2706template< typename MT2 > // Type of the right-hand side dense matrix
2707void SymmetricMatrix<MT,SO,false,false>::assign( DenseMatrix<MT2,SO>& rhs )
2708{
2710
2711 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2712 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2713
2714 std::vector<size_t> nonzeros( rows(), 0UL );
2715 size_t sum( 0UL );
2716
2717 for( size_t i=0UL; i<rows(); ++i ) {
2718 nonzeros[i] = (*rhs).nonZeros(i);
2719 sum += nonzeros[i];
2720 }
2721
2722 matrix_.reserve( sum );
2723 for( size_t i=0UL; i<rows(); ++i ) {
2724 matrix_.reserve( i, nonzeros[i] );
2725 }
2726
2727 for( size_t i=0UL; i<rows(); ++i ) {
2728 for( size_t j=i; j<columns(); ++j ) {
2729 if( !isDefault( (*rhs)(i,j) ) ) {
2730 SharedValue<ET> shared;
2731 *shared = std::move( (*rhs)(i,j) );
2732 matrix_.append( i, j, shared, false );
2733 if( i != j )
2734 matrix_.append( j, i, shared, false );
2735 }
2736 }
2737 }
2738}
2740//*************************************************************************************************
2741
2742
2743//*************************************************************************************************
2755template< typename MT // Type of the adapted sparse matrix
2756 , bool SO > // Storage order of the adapted sparse matrix
2757template< typename MT2 > // Type of the right-hand side dense matrix
2758void SymmetricMatrix<MT,SO,false,false>::assign( const DenseMatrix<MT2,SO>& rhs )
2759{
2761
2762 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2763 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2764
2765 std::vector<size_t> nonzeros( rows(), 0UL );
2766 size_t sum( 0UL );
2767
2768 for( size_t i=0UL; i<rows(); ++i ) {
2769 nonzeros[i] = (*rhs).nonZeros(i);
2770 sum += nonzeros[i];
2771 }
2772
2773 matrix_.reserve( sum );
2774 for( size_t i=0UL; i<rows(); ++i ) {
2775 matrix_.reserve( i, nonzeros[i] );
2776 }
2777
2778 for( size_t i=0UL; i<rows(); ++i ) {
2779 for( size_t j=i; j<columns(); ++j ) {
2780 if( !isDefault( (*rhs)(i,j) ) ) {
2781 const SharedValue<ET> shared( (*rhs)(i,j) );
2782 matrix_.append( i, j, shared, false );
2783 if( i != j )
2784 matrix_.append( j, i, shared, false );
2785 }
2786 }
2787 }
2788}
2790//*************************************************************************************************
2791
2792
2793//*************************************************************************************************
2805template< typename MT // Type of the adapted sparse matrix
2806 , bool SO > // Storage order of the adapted sparse matrix
2807template< typename MT2 > // Type of the right-hand side sparse matrix
2808void SymmetricMatrix<MT,SO,false,false>::assign( SparseMatrix<MT2,SO>& rhs )
2809{
2811
2812 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2813 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2814
2815 std::vector<size_t> nonzeros( rows(), 0UL );
2816 size_t sum( 0UL );
2817
2818 for( size_t i=0UL; i<rows(); ++i ) {
2819 nonzeros[i] = (*rhs).nonZeros(i);
2820 sum += nonzeros[i];
2821 }
2822
2823 matrix_.reserve( sum );
2824 for( size_t i=0UL; i<rows(); ++i ) {
2825 matrix_.reserve( i, nonzeros[i] );
2826 }
2827
2828 for( size_t i=0UL; i<rows(); ++i ) {
2829 for( auto it=(*rhs).lowerBound(i,i); it!=(*rhs).end(i); ++it ) {
2830 if( !isDefault( it->value() ) ) {
2831 SharedValue<ET> shared;
2832 *shared = std::move( it->value() );
2833 matrix_.append( i, it->index(), shared, false );
2834 if( i != it->index() )
2835 matrix_.append( it->index(), i, shared, false );
2836 }
2837 }
2838 }
2839}
2841//*************************************************************************************************
2842
2843
2844//*************************************************************************************************
2856template< typename MT // Type of the adapted sparse matrix
2857 , bool SO > // Storage order of the adapted sparse matrix
2858template< typename MT2 > // Type of the right-hand side sparse matrix
2859void SymmetricMatrix<MT,SO,false,false>::assign( const SparseMatrix<MT2,SO>& rhs )
2860{
2862
2863 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2864 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2865
2866 std::vector<size_t> nonzeros( rows(), 0UL );
2867 size_t sum( 0UL );
2868
2869 for( size_t i=0UL; i<rows(); ++i ) {
2870 nonzeros[i] = (*rhs).nonZeros(i);
2871 sum += nonzeros[i];
2872 }
2873
2874 matrix_.reserve( sum );
2875 for( size_t i=0UL; i<rows(); ++i ) {
2876 matrix_.reserve( i, nonzeros[i] );
2877 }
2878
2879 for( size_t i=0UL; i<rows(); ++i ) {
2880 for( auto it=(*rhs).lowerBound(i,i); it!=(*rhs).end(i); ++it ) {
2881 if( !isDefault( it->value() ) ) {
2882 const SharedValue<ET> shared( it->value() );
2883 matrix_.append( i, it->index(), shared, false );
2884 if( i != it->index() )
2885 matrix_.append( it->index(), i, shared, false );
2886 }
2887 }
2888 }
2889}
2891//*************************************************************************************************
2892
2893} // namespace blaze
2894
2895#endif
Header file for the addition trait.
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 If class template.
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.
Header file for the NonScalarProxy class.
Constraint on the data type.
Constraint on the data type.
Header file for the RemoveAdaptor type trait.
Constraint on the data type.
Constraint on the data type.
Header file for the Schur product trait.
Header file for the SharedValue class.
Compile time assertion.
Header file for the subtraction trait.
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.
Pointer difference type of the Blaze library.
Size 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 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
decltype(auto) sum(const DenseMatrix< MT, SO > &dm)
Reduces the given dense matrix by means of addition.
Definition: DMatReduceExpr.h:2156
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
bool isDefault(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the given diagonal matrix is in default state.
Definition: DiagonalMatrix.h:169
#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_NOT_BE_SCALAR_TYPE(T)
Constraint on the data type.
Definition: Scalar.h:81
#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.
Constraints on the storage order of matrix types.
Header file for the Size type trait.
Header file for the isZero shim.
Header file for the SparseElement base class.
Header file for utility functions for sparse matrices.
Header file for basic type definitions.