SparseNonNumeric.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSENONNUMERIC_H_
36 #define _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_SPARSENONNUMERIC_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <iterator>
45 #include <vector>
59 #include <blaze/math/shims/Clear.h>
62 #include <blaze/math/shims/Move.h>
74 #include <blaze/util/Assert.h>
80 #include <blaze/util/EnableIf.h>
81 #include <blaze/util/Exception.h>
82 #include <blaze/util/mpl/If.h>
85 #include <blaze/util/Types.h>
86 #include <blaze/util/Unused.h>
87 
88 
89 namespace blaze {
90 
91 //=================================================================================================
92 //
93 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES WITH NON-NUMERIC ELEMENT TYPE
94 //
95 //=================================================================================================
96 
97 //*************************************************************************************************
105 template< typename MT // Type of the adapted sparse matrix
106  , bool SO > // Storage order of the adapted sparse matrix
107 class SymmetricMatrix<MT,SO,false,false>
108  : public SparseMatrix< SymmetricMatrix<MT,SO,false,false>, SO >
109 {
110  private:
111  //**Type definitions****************************************************************************
112  typedef typename MT::OppositeType OT;
113  typedef typename MT::TransposeType TT;
114  typedef typename MT::ElementType ET;
115 
117  typedef typename MT::template Rebind< SharedValue<ET> >::Other MatrixType;
118  //**********************************************************************************************
119 
120  public:
121  //**Type definitions****************************************************************************
122  typedef SymmetricMatrix<MT,SO,false,false> This;
123  typedef This ResultType;
124  typedef SymmetricMatrix<OT,!SO,false,false> OppositeType;
125  typedef SymmetricMatrix<TT,!SO,false,false> TransposeType;
126  typedef ET ElementType;
127  typedef typename MT::ReturnType ReturnType;
128  typedef const This& CompositeType;
129  typedef NonNumericProxy<MatrixType> Reference;
130  typedef typename MT::ConstReference ConstReference;
131  //**********************************************************************************************
132 
133  //**Rebind struct definition********************************************************************
136  template< typename ET > // Data type of the other matrix
137  struct Rebind {
139  typedef SymmetricMatrix< typename MT::template Rebind<ET>::Other > Other;
140  };
141  //**********************************************************************************************
142 
143  //**SharedElement class definition**************************************************************
146  template< typename IteratorType > // Type of the sparse matrix iterator
147  class SharedElement : private SparseElement
148  {
149  public:
150  //**Type definitions*************************************************************************
151  typedef ET ValueType;
152  typedef size_t IndexType;
153  typedef ValueType& Reference;
154  typedef const ValueType& ConstReference;
155  typedef SharedElement* Pointer;
156  typedef const SharedElement* ConstPointer;
157  //*******************************************************************************************
158 
159  //**Constructor******************************************************************************
164  inline SharedElement( IteratorType pos )
165  : pos_( pos ) // Iterator to the current sparse symmetric matrix element
166  {}
167  //*******************************************************************************************
168 
169  //**Assignment operator**********************************************************************
175  template< typename T > inline SharedElement& operator=( const T& v ) {
176  *pos_->value() = v;
177  return *this;
178  }
179  //*******************************************************************************************
180 
181  //**Addition assignment operator*************************************************************
187  template< typename T > inline SharedElement& operator+=( const T& v ) {
188  *pos_->value() += v;
189  return *this;
190  }
191  //*******************************************************************************************
192 
193  //**Subtraction assignment operator**********************************************************
199  template< typename T > inline SharedElement& operator-=( const T& v ) {
200  *pos_->value() -= v;
201  return *this;
202  }
203  //*******************************************************************************************
204 
205  //**Multiplication assignment operator*******************************************************
211  template< typename T > inline SharedElement& operator*=( const T& v ) {
212  *pos_->value() *= v;
213  return *this;
214  }
215  //*******************************************************************************************
216 
217  //**Division assignment operator*************************************************************
223  template< typename T > inline SharedElement& operator/=( const T& v ) {
224  *pos_->value() /= v;
225  return *this;
226  }
227  //*******************************************************************************************
228 
229  //**Element access operator******************************************************************
234  inline Pointer operator->() {
235  return this;
236  }
237  //*******************************************************************************************
238 
239  //**Element access operator******************************************************************
244  inline ConstPointer operator->() const {
245  return this;
246  }
247  //*******************************************************************************************
248 
249  //**Value function***************************************************************************
254  inline Reference value() {
255  return *pos_->value();
256  }
257  //*******************************************************************************************
258 
259  //**Value function***************************************************************************
264  inline ConstReference value() const {
265  return *pos_->value();
266  }
267  //*******************************************************************************************
268 
269  //**Index function***************************************************************************
274  inline IndexType index() const {
275  return pos_->index();
276  }
277  //*******************************************************************************************
278 
279  private:
280  //**Member variables*************************************************************************
281  IteratorType pos_;
282  //*******************************************************************************************
283  };
284  //**********************************************************************************************
285 
286  //**SharedIterator class definition*************************************************************
289  template< typename SparseElementType // Type of the underlying sparse elements.
290  , typename IteratorType > // Type of the sparse matrix iterator
291  class SharedIterator
292  {
293  public:
294  //**Type definitions*************************************************************************
295  typedef std::forward_iterator_tag IteratorCategory;
296  typedef SparseElementType ValueType;
297  typedef SparseElementType PointerType;
298  typedef SparseElementType ReferenceType;
299  typedef ptrdiff_t DifferenceType;
300 
301  // STL iterator requirements
302  typedef IteratorCategory iterator_category;
303  typedef ValueType value_type;
304  typedef PointerType pointer;
305  typedef ReferenceType reference;
306  typedef DifferenceType difference_type;
307  //*******************************************************************************************
308 
309  //**Default constructor**********************************************************************
312  inline SharedIterator()
313  : pos_() // Iterator to the current sparse symmetric matrix element
314  {}
315  //*******************************************************************************************
316 
317  //**Constructor******************************************************************************
322  inline SharedIterator( IteratorType pos )
323  : pos_( pos ) // Iterator to the current sparse symmetric matrix element
324  {}
325  //*******************************************************************************************
326 
327  //**Constructor******************************************************************************
332  template< typename SparseElementType2, typename IteratorType2 >
333  inline SharedIterator( const SharedIterator<SparseElementType2,IteratorType2>& it )
334  : pos_( it.pos_ ) // Iterator to the current sparse symmetric matrix element
335  {}
336  //*******************************************************************************************
337 
338  //**Prefix increment operator****************************************************************
343  inline SharedIterator& operator++() {
344  ++pos_;
345  return *this;
346  }
347  //*******************************************************************************************
348 
349  //**Postfix increment operator***************************************************************
354  inline const SharedIterator operator++( int ) {
355  const SharedIterator tmp( *this );
356  ++(*this);
357  return tmp;
358  }
359  //*******************************************************************************************
360 
361  //**Element access operator******************************************************************
366  inline ReferenceType operator*() const {
367  return ReferenceType( pos_ );
368  }
369  //*******************************************************************************************
370 
371  //**Element access operator******************************************************************
376  inline PointerType operator->() const {
377  return PointerType( pos_ );
378  }
379  //*******************************************************************************************
380 
381  //**Equality operator************************************************************************
387  inline bool operator==( const SharedIterator& rhs ) const {
388  return pos_ == rhs.pos_;
389  }
390  //*******************************************************************************************
391 
392  //**Inequality operator**********************************************************************
398  inline bool operator!=( const SharedIterator& rhs ) const {
399  return !( *this == rhs );
400  }
401  //*******************************************************************************************
402 
403  //**Subtraction operator*********************************************************************
409  inline DifferenceType operator-( const SharedIterator& rhs ) const {
410  return pos_ - rhs.pos_;
411  }
412  //*******************************************************************************************
413 
414  //**Base function****************************************************************************
419  inline IteratorType base() const {
420  return pos_;
421  }
422  //*******************************************************************************************
423 
424  private:
425  //**Member variables*************************************************************************
426  IteratorType pos_;
427  //*******************************************************************************************
428 
429  //**Friend declarations**********************************************************************
430  template< typename SparseElementType2, typename IteratorType2 > friend class SharedIterator;
431  //*******************************************************************************************
432  };
433  //**********************************************************************************************
434 
435  //**Type definitions****************************************************************************
437  typedef SharedIterator< SharedElement< typename MatrixType::Iterator >
438  , typename MatrixType::Iterator
439  > Iterator;
440 
442  typedef SharedIterator< const SharedElement< typename MatrixType::ConstIterator >
443  , typename MatrixType::ConstIterator
444  > ConstIterator;
445  //**********************************************************************************************
446 
447  //**Compilation flags***************************************************************************
449  enum { smpAssignable = 0 };
450  //**********************************************************************************************
451 
452  //**Constructors********************************************************************************
455  explicit inline SymmetricMatrix();
456  explicit inline SymmetricMatrix( size_t n );
457  explicit inline SymmetricMatrix( size_t n, size_t nonzeros );
458  explicit inline SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros );
459 
460  inline SymmetricMatrix( const SymmetricMatrix& m );
461  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
462  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
464  //**********************************************************************************************
465 
466  //**Destructor**********************************************************************************
467  // No explicitly declared destructor.
468  //**********************************************************************************************
469 
470  //**Data access functions***********************************************************************
473  inline Reference operator()( size_t i, size_t j );
474  inline ConstReference operator()( size_t i, size_t j ) const;
475  inline Reference at( size_t i, size_t j );
476  inline ConstReference at( size_t i, size_t j ) const;
477  inline Iterator begin ( size_t i );
478  inline ConstIterator begin ( size_t i ) const;
479  inline ConstIterator cbegin( size_t i ) const;
480  inline Iterator end ( size_t i );
481  inline ConstIterator end ( size_t i ) const;
482  inline ConstIterator cend ( size_t i ) const;
484  //**********************************************************************************************
485 
486  //**Assignment operators************************************************************************
489  inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
490 
491  template< typename MT2 >
492  inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
493  operator=( const Matrix<MT2,SO>& rhs );
494 
495  template< typename MT2 >
496  inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
497  operator=( const Matrix<MT2,SO>& rhs );
498 
499  template< typename MT2 >
500  inline SymmetricMatrix& operator=( const Matrix<MT2,!SO>& rhs );
501 
502  template< typename MT2 >
503  inline SymmetricMatrix& operator+=( const Matrix<MT2,SO>& rhs );
504 
505  template< typename MT2 >
506  inline SymmetricMatrix& operator+=( const Matrix<MT2,!SO>& rhs );
507 
508  template< typename MT2 >
509  inline SymmetricMatrix& operator-=( const Matrix<MT2,SO>& rhs );
510 
511  template< typename MT2 >
512  inline SymmetricMatrix& operator-=( const Matrix<MT2,!SO>& rhs );
513 
514  template< typename MT2, bool SO2 >
515  inline SymmetricMatrix& operator*=( const Matrix<MT2,SO2>& rhs );
516 
517  template< typename Other >
518  inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix >::Type&
519  operator*=( Other rhs );
520 
521  template< typename Other >
522  inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix >::Type&
523  operator/=( Other rhs );
525  //**********************************************************************************************
526 
527  //**Utility functions***************************************************************************
530  inline size_t rows() const;
531  inline size_t columns() const;
532  inline size_t capacity() const;
533  inline size_t capacity( size_t i ) const;
534  inline size_t nonZeros() const;
535  inline size_t nonZeros( size_t i ) const;
536  inline void reset();
537  inline void reset( size_t i );
538  inline void clear();
539  inline Iterator set( size_t i, size_t j, const ElementType& value );
540  inline Iterator insert( size_t i, size_t j, const ElementType& value );
541  inline void erase( size_t i, size_t j );
542  inline Iterator erase( size_t i, Iterator pos );
543  inline Iterator erase( size_t i, Iterator first, Iterator last );
544  inline void resize ( size_t n, bool preserve=true );
545  inline void reserve( size_t nonzeros );
546  inline void reserve( size_t i, size_t nonzeros );
547  inline void trim();
548  inline void trim( size_t i );
549  inline SymmetricMatrix& transpose();
550  inline SymmetricMatrix& ctranspose();
551  template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
552  template< typename Other > inline SymmetricMatrix& scaleDiagonal( Other scale );
553  inline void swap( SymmetricMatrix& m ) /* throw() */;
555  //**********************************************************************************************
556 
557  //**Lookup functions****************************************************************************
560  inline Iterator find ( size_t i, size_t j );
561  inline ConstIterator find ( size_t i, size_t j ) const;
562  inline Iterator lowerBound( size_t i, size_t j );
563  inline ConstIterator lowerBound( size_t i, size_t j ) const;
564  inline Iterator upperBound( size_t i, size_t j );
565  inline ConstIterator upperBound( size_t i, size_t j ) const;
567  //**********************************************************************************************
568 
569  //**Low-level utility functions*****************************************************************
572  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
573  inline void finalize( size_t i );
575  //**********************************************************************************************
576 
577  //**Debugging functions*************************************************************************
580  inline bool isIntact() const;
582  //**********************************************************************************************
583 
584  //**Expression template evaluation functions****************************************************
587  template< typename Other > inline bool canAlias ( const Other* alias ) const;
588  template< typename Other > inline bool isAliased( const Other* alias ) const;
589 
590  inline bool canSMPAssign() const;
592  //**********************************************************************************************
593 
594  private:
595  //**Expression template evaluation functions****************************************************
598  template< typename MT2 > void assign( DenseMatrix<MT2,SO>& rhs );
599  template< typename MT2 > void assign( const DenseMatrix<MT2,SO>& rhs );
600  template< typename MT2 > void assign( SparseMatrix<MT2,SO>& rhs );
601  template< typename MT2 > void assign( const SparseMatrix<MT2,SO>& rhs );
603  //**********************************************************************************************
604 
605  //**Member variables****************************************************************************
608  MatrixType matrix_;
609 
610  //**********************************************************************************************
611 
612  //**Friend declarations*************************************************************************
613  template< typename MT2, bool SO2, bool DF2, bool NF2 >
614  friend bool isDefault( const SymmetricMatrix<MT2,SO2,DF2,NF2>& m );
615  //**********************************************************************************************
616 
617  //**Compile time checks*************************************************************************
631  BLAZE_STATIC_ASSERT( Rows<MT>::value == Columns<MT>::value );
632  //**********************************************************************************************
633 };
635 //*************************************************************************************************
636 
637 
638 
639 
640 //=================================================================================================
641 //
642 // CONSTRUCTORS
643 //
644 //=================================================================================================
645 
646 //*************************************************************************************************
650 template< typename MT // Type of the adapted sparse matrix
651  , bool SO > // Storage order of the adapted sparse matrix
652 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix()
653  : matrix_() // The adapted sparse matrix
654 {
655  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
656 }
658 //*************************************************************************************************
659 
660 
661 //*************************************************************************************************
669 template< typename MT // Type of the adapted sparse matrix
670  , bool SO > // Storage order of the adapted sparse matrix
671 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n )
672  : matrix_( n, n ) // The adapted sparse matrix
673 {
675 
676  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
677 }
679 //*************************************************************************************************
680 
681 
682 //*************************************************************************************************
691 template< typename MT // Type of the adapted sparse matrix
692  , bool SO > // Storage order of the adapted sparse matrix
693 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n, size_t nonzeros )
694  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
695 {
697 
698  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
699 }
701 //*************************************************************************************************
702 
703 
704 //*************************************************************************************************
715 template< typename MT // Type of the adapted sparse matrix
716  , bool SO > // Storage order of the adapted sparse matrix
717 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
718  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
719 {
721 
722  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
723 }
725 //*************************************************************************************************
726 
727 
728 //*************************************************************************************************
734 template< typename MT // Type of the adapted sparse matrix
735  , bool SO > // Storage order of the adapted sparse matrix
736 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const SymmetricMatrix& m )
737  : matrix_() // The adapted sparse matrix
738 {
739  using blaze::resize;
740 
741  resize( matrix_, m.rows(), m.columns() );
742  assign( m );
743 
744  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
745  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
746 }
748 //*************************************************************************************************
749 
750 
751 //*************************************************************************************************
761 template< typename MT // Type of the adapted sparse matrix
762  , bool SO > // Storage order of the adapted sparse matrix
763 template< typename MT2 > // Type of the foreign matrix
764 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const Matrix<MT2,SO>& m )
765  : matrix_() // The adapted sparse matrix
766 {
767  using blaze::resize;
768 
769  typedef typename RemoveAdaptor<typename MT2::ResultType>::Type RT;
770  typedef typename If< IsComputation<MT2>, RT, const MT2& >::Type Tmp;
771 
772  Tmp tmp( ~m );
773 
774  if( !IsSymmetric<MT2>::value && !isSymmetric( tmp ) ) {
775  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
776  }
777 
778  resize( matrix_, tmp.rows(), tmp.columns() );
779  assign( tmp );
780 
781  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
782  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
783 }
785 //*************************************************************************************************
786 
787 
788 //*************************************************************************************************
798 template< typename MT // Type of the adapted sparse matrix
799  , bool SO > // Storage order of the adapted sparse matrix
800 template< typename MT2 > // Type of the foreign matrix
801 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
802  : matrix_() // The adapted sparse matrix
803 {
804  using blaze::resize;
805 
806  typedef typename RemoveAdaptor<typename MT2::ResultType>::Type RT;
807  typedef typename If< IsComputation<MT2>, RT, const MT2& >::Type Tmp;
808 
809  Tmp tmp( ~m );
810 
811  if( !IsSymmetric<MT2>::value && !isSymmetric( tmp ) ) {
812  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of symmetric matrix" );
813  }
814 
815  resize( matrix_, tmp.rows(), tmp.columns() );
816  assign( trans( tmp ) );
817 
818  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
819  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
820 }
822 //*************************************************************************************************
823 
824 
825 
826 
827 //=================================================================================================
828 //
829 // DATA ACCESS FUNCTIONS
830 //
831 //=================================================================================================
832 
833 //*************************************************************************************************
848 template< typename MT // Type of the adapted sparse matrix
849  , bool SO > // Storage order of the adapted sparse matrix
851  SymmetricMatrix<MT,SO,false,false>::operator()( size_t i, size_t j )
852 {
853  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
854  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
855 
856  return Reference( matrix_, i, j );
857 }
859 //*************************************************************************************************
860 
861 
862 //*************************************************************************************************
877 template< typename MT // Type of the adapted sparse matrix
878  , bool SO > // Storage order of the adapted sparse matrix
880  SymmetricMatrix<MT,SO,false,false>::operator()( size_t i, size_t j ) const
881 {
882  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
883  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
884 
885  return *matrix_(i,j);
886 }
888 //*************************************************************************************************
889 
890 
891 //*************************************************************************************************
907 template< typename MT // Type of the adapted dense matrix
908  , bool SO > // Storage order of the adapted dense matrix
910  SymmetricMatrix<MT,SO,false,false>::at( size_t i, size_t j )
911 {
912  if( i >= rows() ) {
913  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
914  }
915  if( j >= columns() ) {
916  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
917  }
918  return (*this)(i,j);
919 }
921 //*************************************************************************************************
922 
923 
924 //*************************************************************************************************
940 template< typename MT // Type of the adapted dense matrix
941  , bool SO > // Storage order of the adapted dense matrix
943  SymmetricMatrix<MT,SO,false,false>::at( size_t i, size_t j ) const
944 {
945  if( i >= rows() ) {
946  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
947  }
948  if( j >= columns() ) {
949  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
950  }
951  return (*this)(i,j);
952 }
954 //*************************************************************************************************
955 
956 
957 //*************************************************************************************************
969 template< typename MT // Type of the adapted sparse matrix
970  , bool SO > // Storage order of the adapted sparse matrix
973 {
974  return Iterator( matrix_.begin(i) );
975 }
977 //*************************************************************************************************
978 
979 
980 //*************************************************************************************************
992 template< typename MT // Type of the adapted sparse matrix
993  , bool SO > // Storage order of the adapted sparse matrix
996 {
997  return ConstIterator( matrix_.begin(i) );
998 }
1000 //*************************************************************************************************
1001 
1002 
1003 //*************************************************************************************************
1015 template< typename MT // Type of the adapted sparse matrix
1016  , bool SO > // Storage order of the adapted sparse matrix
1019 {
1020  return ConstIterator( matrix_.cbegin(i) );
1021 }
1023 //*************************************************************************************************
1024 
1025 
1026 //*************************************************************************************************
1038 template< typename MT // Type of the adapted sparse matrix
1039  , bool SO > // Storage order of the adapted sparse matrix
1042 {
1043  return Iterator( matrix_.end(i) );
1044 }
1046 //*************************************************************************************************
1047 
1048 
1049 //*************************************************************************************************
1061 template< typename MT // Type of the adapted sparse matrix
1062  , bool SO > // Storage order of the adapted sparse matrix
1064  SymmetricMatrix<MT,SO,false,false>::end( size_t i ) const
1065 {
1066  return ConstIterator( matrix_.end(i) );
1067 }
1069 //*************************************************************************************************
1070 
1071 
1072 //*************************************************************************************************
1084 template< typename MT // Type of the adapted sparse matrix
1085  , bool SO > // Storage order of the adapted sparse matrix
1088 {
1089  return ConstIterator( matrix_.cend(i) );
1090 }
1092 //*************************************************************************************************
1093 
1094 
1095 
1096 
1097 //=================================================================================================
1098 //
1099 // ASSIGNMENT OPERATORS
1100 //
1101 //=================================================================================================
1102 
1103 //*************************************************************************************************
1113 template< typename MT // Type of the adapted sparse matrix
1114  , bool SO > // Storage order of the adapted sparse matrix
1115 inline SymmetricMatrix<MT,SO,false,false>&
1116  SymmetricMatrix<MT,SO,false,false>::operator=( const SymmetricMatrix& rhs )
1117 {
1118  using blaze::resize;
1119 
1120  if( &rhs == this ) return *this;
1121 
1122  resize( matrix_, rhs.rows(), rhs.columns() );
1123  reset();
1124  assign( rhs );
1125 
1126  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1127  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1128 
1129  return *this;
1130 }
1132 //*************************************************************************************************
1133 
1134 
1135 //*************************************************************************************************
1149 template< typename MT // Type of the adapted sparse matrix
1150  , bool SO > // Storage order of the adapted sparse matrix
1151 template< typename MT2 > // Type of the right-hand side matrix
1152 inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,false>& >::Type
1153  SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1154 {
1155  using blaze::resize;
1156 
1157  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) {
1158  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1159  }
1160 
1161  if( (~rhs).canAlias( this ) ) {
1162  SymmetricMatrix tmp( ~rhs );
1163  swap( tmp );
1164  }
1165  else {
1166  resize( matrix_, (~rhs).rows(), (~rhs).columns() );
1167  reset();
1168  assign( ~rhs );
1169  }
1170 
1171  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1172  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1173 
1174  return *this;
1175 }
1177 //*************************************************************************************************
1178 
1179 
1180 //*************************************************************************************************
1194 template< typename MT // Type of the adapted sparse matrix
1195  , bool SO > // Storage order of the adapted sparse matrix
1196 template< typename MT2 > // Type of the right-hand side matrix
1197 inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,false>& >::Type
1198  SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1199 {
1200  using blaze::resize;
1201 
1202  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1203  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1204  }
1205 
1206  typename MT2::ResultType tmp( ~rhs );
1207 
1208  if( !IsSymmetric<MT2>::value && !isSymmetric( tmp ) ) {
1209  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1210  }
1211 
1212  resize( matrix_, tmp.rows(), tmp.columns() );
1213  reset();
1214  assign( tmp );
1215 
1216  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1217  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1218 
1219  return *this;
1220 }
1222 //*************************************************************************************************
1223 
1224 
1225 //*************************************************************************************************
1239 template< typename MT // Type of the adapted sparse matrix
1240  , bool SO > // Storage order of the adapted sparse matrix
1241 template< typename MT2 > // Type of the right-hand side matrix
1242 inline SymmetricMatrix<MT,SO,false,false>&
1243  SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,!SO>& rhs )
1244 {
1245  return this->operator=( trans( ~rhs ) );
1246 }
1248 //*************************************************************************************************
1249 
1250 
1251 //*************************************************************************************************
1264 template< typename MT // Type of the adapted sparse matrix
1265  , bool SO > // Storage order of the adapted sparse matrix
1266 template< typename MT2 > // Type of the right-hand side matrix
1267 inline SymmetricMatrix<MT,SO,false,false>&
1268  SymmetricMatrix<MT,SO,false,false>::operator+=( const Matrix<MT2,SO>& rhs )
1269 {
1270  using blaze::resize;
1271 
1272  typedef typename AddTrait<MT,typename MT2::ResultType>::Type Tmp;
1273 
1274  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1275  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1276  }
1277 
1278  Tmp tmp( (*this) + ~rhs );
1279 
1280  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) ) {
1281  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1282  }
1283 
1284  resize( matrix_, tmp.rows(), tmp.columns() );
1285  reset();
1286  assign( tmp );
1287 
1288  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1289  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1290 
1291  return *this;
1292 }
1294 //*************************************************************************************************
1295 
1296 
1297 //*************************************************************************************************
1311 template< typename MT // Type of the adapted sparse matrix
1312  , bool SO > // Storage order of the adapted sparse matrix
1313 template< typename MT2 > // Type of the right-hand side matrix
1314 inline SymmetricMatrix<MT,SO,false,false>&
1315  SymmetricMatrix<MT,SO,false,false>::operator+=( const Matrix<MT2,!SO>& rhs )
1316 {
1317  return this->operator+=( trans( ~rhs ) );
1318 }
1320 //*************************************************************************************************
1321 
1322 
1323 //*************************************************************************************************
1336 template< typename MT // Type of the adapted sparse matrix
1337  , bool SO > // Storage order of the adapted sparse matrix
1338 template< typename MT2 > // Type of the right-hand side matrix
1339 inline SymmetricMatrix<MT,SO,false,false>&
1340  SymmetricMatrix<MT,SO,false,false>::operator-=( const Matrix<MT2,SO>& rhs )
1341 {
1342  using blaze::resize;
1343 
1344  typedef typename SubTrait<MT,typename MT2::ResultType>::Type Tmp;
1345 
1346  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) ) {
1347  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1348  }
1349 
1350  Tmp tmp( (*this) - ~rhs );
1351 
1352  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) ) {
1353  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1354  }
1355 
1356  resize( matrix_, tmp.rows(), tmp.columns() );
1357  reset();
1358  assign( tmp );
1359 
1360  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1361  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1362 
1363  return *this;
1364 }
1366 //*************************************************************************************************
1367 
1368 
1369 //*************************************************************************************************
1383 template< typename MT // Type of the adapted sparse matrix
1384  , bool SO > // Storage order of the adapted sparse matrix
1385 template< typename MT2 > // Type of the right-hand side matrix
1386 inline SymmetricMatrix<MT,SO,false,false>&
1387  SymmetricMatrix<MT,SO,false,false>::operator-=( const Matrix<MT2,!SO>& rhs )
1388 {
1389  return this->operator-=( trans( ~rhs ) );
1390 }
1392 //*************************************************************************************************
1393 
1394 
1395 //*************************************************************************************************
1407 template< typename MT // Type of the adapted sparse matrix
1408  , bool SO > // Storage order of the adapted sparse matrix
1409 template< typename MT2 // Type of the right-hand side matrix
1410  , bool SO2 > // Storage order of the right-hand side matrix
1411 inline SymmetricMatrix<MT,SO,false,false>&
1412  SymmetricMatrix<MT,SO,false,false>::operator*=( const Matrix<MT2,SO2>& rhs )
1413 {
1414  using blaze::resize;
1415 
1416  typedef typename MultTrait<MT,typename MT2::ResultType>::Type Tmp;
1417 
1418  if( matrix_.rows() != (~rhs).columns() ) {
1419  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1420  }
1421 
1422  Tmp tmp( (*this) * ~rhs );
1423 
1424  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) ) {
1425  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to symmetric matrix" );
1426  }
1427 
1428  resize( matrix_, tmp.rows(), tmp.columns() );
1429  reset();
1430  assign( tmp );
1431 
1432  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1433  BLAZE_INTERNAL_ASSERT( isIntact(), "Broken invariant detected" );
1434 
1435  return *this;
1436 }
1438 //*************************************************************************************************
1439 
1440 
1441 //*************************************************************************************************
1449 template< typename MT // Type of the adapted sparse matrix
1450  , bool SO > // Storage order of the adapted sparse matrix
1451 template< typename Other > // Data type of the right-hand side scalar
1452 inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,false> >::Type&
1453  SymmetricMatrix<MT,SO,false,false>::operator*=( Other rhs )
1454 {
1455  for( size_t i=0UL; i<rows(); ++i ) {
1456  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
1457  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
1458  *element->value() *= rhs;
1459  }
1460 
1461  return *this;
1462 }
1464 //*************************************************************************************************
1465 
1466 
1467 //*************************************************************************************************
1475 template< typename MT // Type of the adapted sparse matrix
1476  , bool SO > // Storage order of the adapted sparse matrix
1477 template< typename Other > // Data type of the right-hand side scalar
1478 inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,false> >::Type&
1479  SymmetricMatrix<MT,SO,false,false>::operator/=( Other rhs )
1480 {
1481  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1482 
1483  for( size_t i=0UL; i<rows(); ++i ) {
1484  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
1485  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
1486  *element->value() /= rhs;
1487  }
1488 
1489  return *this;
1490 }
1492 //*************************************************************************************************
1493 
1494 
1495 
1496 
1497 //=================================================================================================
1498 //
1499 // UTILITY FUNCTIONS
1500 //
1501 //=================================================================================================
1502 
1503 //*************************************************************************************************
1509 template< typename MT // Type of the adapted sparse matrix
1510  , bool SO > // Storage order of the adapted sparse matrix
1511 inline size_t SymmetricMatrix<MT,SO,false,false>::rows() const
1512 {
1513  return matrix_.rows();
1514 }
1516 //*************************************************************************************************
1517 
1518 
1519 //*************************************************************************************************
1525 template< typename MT // Type of the adapted sparse matrix
1526  , bool SO > // Storage order of the adapted sparse matrix
1527 inline size_t SymmetricMatrix<MT,SO,false,false>::columns() const
1528 {
1529  return matrix_.columns();
1530 }
1532 //*************************************************************************************************
1533 
1534 
1535 //*************************************************************************************************
1541 template< typename MT // Type of the adapted sparse matrix
1542  , bool SO > // Storage order of the adapted sparse matrix
1544 {
1545  return matrix_.capacity();
1546 }
1548 //*************************************************************************************************
1549 
1550 
1551 //*************************************************************************************************
1562 template< typename MT // Type of the adapted sparse matrix
1563  , bool SO > // Storage order of the adapted sparse matrix
1564 inline size_t SymmetricMatrix<MT,SO,false,false>::capacity( size_t i ) const
1565 {
1566  return matrix_.capacity(i);
1567 }
1569 //*************************************************************************************************
1570 
1571 
1572 //*************************************************************************************************
1578 template< typename MT // Type of the adapted sparse matrix
1579  , bool SO > // Storage order of the adapted sparse matrix
1581 {
1582  return matrix_.nonZeros();
1583 }
1585 //*************************************************************************************************
1586 
1587 
1588 //*************************************************************************************************
1600 template< typename MT // Type of the adapted sparse matrix
1601  , bool SO > // Storage order of the adapted sparse matrix
1602 inline size_t SymmetricMatrix<MT,SO,false,false>::nonZeros( size_t i ) const
1603 {
1604  return matrix_.nonZeros(i);
1605 }
1607 //*************************************************************************************************
1608 
1609 
1610 //*************************************************************************************************
1616 template< typename MT // Type of the adapted sparse matrix
1617  , bool SO > // Storage order of the adapted sparse matrix
1619 {
1620  matrix_.reset();
1621 }
1623 //*************************************************************************************************
1624 
1625 
1626 //*************************************************************************************************
1666 template< typename MT // Type of the adapted sparse matrix
1667  , bool SO > // Storage order of the adapted sparse matrix
1668 inline void SymmetricMatrix<MT,SO,false,false>::reset( size_t i )
1669 {
1670  for( typename MatrixType::Iterator it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1671  {
1672  const size_t j( it->index() );
1673 
1674  if( i == j )
1675  continue;
1676 
1677  if( SO ) {
1678  const typename MatrixType::Iterator pos( matrix_.find( i, j ) );
1679  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1680  matrix_.erase( j, pos );
1681  }
1682  else {
1683  const typename MatrixType::Iterator pos( matrix_.find( j, i ) );
1684  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1685  matrix_.erase( j, pos );
1686  }
1687  }
1688 
1689  matrix_.reset( i );
1690 }
1692 //*************************************************************************************************
1693 
1694 
1695 //*************************************************************************************************
1703 template< typename MT // Type of the adapted sparse matrix
1704  , bool SO > // Storage order of the adapted sparse matrix
1706 {
1707  using blaze::clear;
1708 
1709  clear( matrix_ );
1710 }
1712 //*************************************************************************************************
1713 
1714 
1715 //*************************************************************************************************
1729 template< typename MT // Type of the adapted sparse matrix
1730  , bool SO > // Storage order of the adapted sparse matrix
1732  SymmetricMatrix<MT,SO,false,false>::set( size_t i, size_t j, const ElementType& value )
1733 {
1734  SharedValue<ET> shared( value );
1735 
1736  if( i != j )
1737  matrix_.set( j, i, shared );
1738 
1739  return Iterator( matrix_.set( i, j, shared ) );
1740 }
1742 //*************************************************************************************************
1743 
1744 
1745 //*************************************************************************************************
1760 template< typename MT // Type of the adapted sparse matrix
1761  , bool SO > // Storage order of the adapted sparse matrix
1763  SymmetricMatrix<MT,SO,false,false>::insert( size_t i, size_t j, const ElementType& value )
1764 {
1765  SharedValue<ET> shared( value );
1766 
1767  if( i != j )
1768  matrix_.insert( j, i, shared );
1769 
1770  return Iterator( matrix_.insert( i, j, shared ) );
1771 }
1773 //*************************************************************************************************
1774 
1775 
1776 //*************************************************************************************************
1786 template< typename MT // Type of the adapted sparse matrix
1787  , bool SO > // Storage order of the adapted sparse matrix
1788 inline void SymmetricMatrix<MT,SO,false,false>::erase( size_t i, size_t j )
1789 {
1790  matrix_.erase( i, j );
1791  if( i != j )
1792  matrix_.erase( j, i );
1793 }
1795 //*************************************************************************************************
1796 
1797 
1798 //*************************************************************************************************
1810 template< typename MT // Type of the adapted sparse matrix
1811  , bool SO > // Storage order of the adapted sparse matrix
1813  SymmetricMatrix<MT,SO,false,false>::erase( size_t i, Iterator pos )
1814 {
1815  if( pos == end( i ) )
1816  return pos;
1817 
1818  const size_t j( pos->index() );
1819 
1820  if( i == j )
1821  return Iterator( matrix_.erase( i, pos.base() ) );
1822 
1823  if( SO ) {
1824  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1825  matrix_.erase( j, matrix_.find( i, j ) );
1826  return Iterator( matrix_.erase( i, pos.base() ) );
1827  }
1828  else {
1829  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1830  matrix_.erase( j, matrix_.find( j, i ) );
1831  return Iterator( matrix_.erase( i, pos.base() ) );
1832  }
1833 }
1835 //*************************************************************************************************
1836 
1837 
1838 //*************************************************************************************************
1852 template< typename MT // Type of the adapted sparse matrix
1853  , bool SO > // Storage order of the adapted sparse matrix
1855  SymmetricMatrix<MT,SO,false,false>::erase( size_t i, Iterator first, Iterator last )
1856 {
1857  for( Iterator it=first; it!=last; ++it )
1858  {
1859  const size_t j( it->index() );
1860 
1861  if( i == j )
1862  continue;
1863 
1864  if( SO ) {
1865  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1866  matrix_.erase( i, j );
1867  }
1868  else {
1869  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1870  matrix_.erase( j, i );
1871  }
1872  }
1873 
1874  return Iterator( matrix_.erase( i, first.base(), last.base() ) );
1875 }
1877 //*************************************************************************************************
1878 
1879 
1880 //*************************************************************************************************
1895 template< typename MT // Type of the adapted sparse matrix
1896  , bool SO > // Storage order of the adapted sparse matrix
1897 void SymmetricMatrix<MT,SO,false,false>::resize( size_t n, bool preserve )
1898 {
1900 
1901  UNUSED_PARAMETER( preserve );
1902 
1903  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1904 
1905  matrix_.resize( n, n, true );
1906 }
1908 //*************************************************************************************************
1909 
1910 
1911 //*************************************************************************************************
1922 template< typename MT // Type of the adapted sparse matrix
1923  , bool SO > // Storage order of the adapted sparse matrix
1924 inline void SymmetricMatrix<MT,SO,false,false>::reserve( size_t nonzeros )
1925 {
1926  matrix_.reserve( nonzeros );
1927 }
1929 //*************************************************************************************************
1930 
1931 
1932 //*************************************************************************************************
1946 template< typename MT // Type of the adapted sparse matrix
1947  , bool SO > // Storage order of the adapted sparse matrix
1948 inline void SymmetricMatrix<MT,SO,false,false>::reserve( size_t i, size_t nonzeros )
1949 {
1950  matrix_.reserve( i, nonzeros );
1951 }
1953 //*************************************************************************************************
1954 
1955 
1956 //*************************************************************************************************
1967 template< typename MT // Type of the adapted sparse matrix
1968  , bool SO > // Storage order of the adapted sparse matrix
1969 inline void SymmetricMatrix<MT,SO,false,false>::trim()
1970 {
1971  matrix_.trim();
1972 }
1974 //*************************************************************************************************
1975 
1976 
1977 //*************************************************************************************************
1989 template< typename MT // Type of the adapted sparse matrix
1990  , bool SO > // Storage order of the adapted sparse matrix
1991 inline void SymmetricMatrix<MT,SO,false,false>::trim( size_t i )
1992 {
1993  matrix_.trim( i );
1994 }
1996 //*************************************************************************************************
1997 
1998 
1999 //*************************************************************************************************
2005 template< typename MT // Type of the adapted sparse matrix
2006  , bool SO > // Storage order of the adapted sparse matrix
2007 inline SymmetricMatrix<MT,SO,false,false>& SymmetricMatrix<MT,SO,false,false>::transpose()
2008 {
2009  return *this;
2010 }
2012 //*************************************************************************************************
2013 
2014 
2015 //*************************************************************************************************
2021 template< typename MT // Type of the adapted sparse matrix
2022  , bool SO > // Storage order of the adapted sparse matrix
2023 inline SymmetricMatrix<MT,SO,false,false>& SymmetricMatrix<MT,SO,false,false>::ctranspose()
2024 {
2025  for( size_t i=0UL; i<rows(); ++i ) {
2026  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
2027  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
2028  conjugate( *element->value() );
2029  }
2030 
2031  return *this;
2032 }
2034 //*************************************************************************************************
2035 
2036 
2037 //*************************************************************************************************
2044 template< typename MT // Type of the adapted sparse matrix
2045  , bool SO > // Storage order of the adapted sparse matrix
2046 template< typename Other > // Data type of the scalar value
2047 inline SymmetricMatrix<MT,SO,false,false>&
2048  SymmetricMatrix<MT,SO,false,false>::scale( const Other& scalar )
2049 {
2050  for( size_t i=0UL; i<rows(); ++i ) {
2051  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
2052  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
2053  ( *element->value() ).scale( scalar );
2054  }
2055 
2056  return *this;
2057 }
2059 //*************************************************************************************************
2060 
2061 
2062 //*************************************************************************************************
2069 template< typename MT // Type of the adapted sparse matrix
2070  , bool SO > // Storage order of the adapted sparse matrix
2071 template< typename Other > // Data type of the scalar value
2072 inline SymmetricMatrix<MT,SO,false,false>&
2073  SymmetricMatrix<MT,SO,false,false>::scaleDiagonal( Other scalar )
2074 {
2075  matrix_.scaleDiagonal( scalar );
2076  return *this;
2077 }
2079 //*************************************************************************************************
2080 
2081 
2082 //*************************************************************************************************
2090 template< typename MT // Type of the adapted sparse matrix
2091  , bool SO > // Storage order of the adapted sparse matrix
2092 inline void SymmetricMatrix<MT,SO,false,false>::swap( SymmetricMatrix& m ) /* throw() */
2093 {
2094  using std::swap;
2095 
2096  swap( matrix_, m.matrix_ );
2097 }
2099 //*************************************************************************************************
2100 
2101 
2102 
2103 
2104 //=================================================================================================
2105 //
2106 // LOOKUP FUNCTIONS
2107 //
2108 //=================================================================================================
2109 
2110 //*************************************************************************************************
2126 template< typename MT // Type of the adapted sparse matrix
2127  , bool SO > // Storage order of the adapted sparse matrix
2129  SymmetricMatrix<MT,SO,false,false>::find( size_t i, size_t j )
2130 {
2131  return Iterator( matrix_.find( i, j ) );
2132 }
2134 //*************************************************************************************************
2135 
2136 
2137 //*************************************************************************************************
2153 template< typename MT // Type of the adapted sparse matrix
2154  , bool SO > // Storage order of the adapted sparse matrix
2156  SymmetricMatrix<MT,SO,false,false>::find( size_t i, size_t j ) const
2157 {
2158  return ConstIterator( matrix_.find( i, j ) );
2159 }
2161 //*************************************************************************************************
2162 
2163 
2164 //*************************************************************************************************
2180 template< typename MT // Type of the adapted sparse matrix
2181  , bool SO > // Storage order of the adapted sparse matrix
2183  SymmetricMatrix<MT,SO,false,false>::lowerBound( size_t i, size_t j )
2184 {
2185  return Iterator( matrix_.lowerBound( i, j ) );
2186 }
2188 //*************************************************************************************************
2189 
2190 
2191 //*************************************************************************************************
2207 template< typename MT // Type of the adapted sparse matrix
2208  , bool SO > // Storage order of the adapted sparse matrix
2210  SymmetricMatrix<MT,SO,false,false>::lowerBound( size_t i, size_t j ) const
2211 {
2212  return ConstIterator( matrix_.lowerBound( i, j ) );
2213 }
2215 //*************************************************************************************************
2216 
2217 
2218 //*************************************************************************************************
2234 template< typename MT // Type of the adapted sparse matrix
2235  , bool SO > // Storage order of the adapted sparse matrix
2237  SymmetricMatrix<MT,SO,false,false>::upperBound( size_t i, size_t j )
2238 {
2239  return Iterator( matrix_.upperBound( i, j ) );
2240 }
2242 //*************************************************************************************************
2243 
2244 
2245 //*************************************************************************************************
2261 template< typename MT // Type of the adapted sparse matrix
2262  , bool SO > // Storage order of the adapted sparse matrix
2264  SymmetricMatrix<MT,SO,false,false>::upperBound( size_t i, size_t j ) const
2265 {
2266  return ConstIterator( matrix_.upperBound( i, j ) );
2267 }
2269 //*************************************************************************************************
2270 
2271 
2272 
2273 
2274 //=================================================================================================
2275 //
2276 // LOW-LEVEL UTILITY FUNCTIONS
2277 //
2278 //=================================================================================================
2279 
2280 //*************************************************************************************************
2335 template< typename MT // Type of the adapted sparse matrix
2336  , bool SO > // Storage order of the adapted sparse matrix
2337 inline void SymmetricMatrix<MT,SO,false,false>::append( size_t i, size_t j, const ElementType& value, bool check )
2338 {
2339  SharedValue<ET> shared( value );
2340 
2341  matrix_.append( i, j, shared, check );
2342  if( i != j && ( !check || !isDefault( value ) ) )
2343  matrix_.insert( j, i, shared );
2344 }
2346 //*************************************************************************************************
2347 
2348 
2349 //*************************************************************************************************
2363 template< typename MT // Type of the adapted sparse matrix
2364  , bool SO > // Storage order of the adapted sparse matrix
2365 inline void SymmetricMatrix<MT,SO,false,false>::finalize( size_t i )
2366 {
2367  matrix_.trim( i );
2368 }
2370 //*************************************************************************************************
2371 
2372 
2373 
2374 
2375 //=================================================================================================
2376 //
2377 // DEBUGGING FUNCTIONS
2378 //
2379 //=================================================================================================
2380 
2381 //*************************************************************************************************
2391 template< typename MT // Type of the adapted dense matrix
2392  , bool SO > // Storage order of the adapted dense matrix
2394 {
2395  using blaze::isIntact;
2396 
2397  return ( isIntact( matrix_ ) && isSymmetric( matrix_ ) );
2398 }
2400 //*************************************************************************************************
2401 
2402 
2403 
2404 
2405 //=================================================================================================
2406 //
2407 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2408 //
2409 //=================================================================================================
2410 
2411 //*************************************************************************************************
2422 template< typename MT // Type of the adapted sparse matrix
2423  , bool SO > // Storage order of the adapted sparse matrix
2424 template< typename Other > // Data type of the foreign expression
2425 inline bool SymmetricMatrix<MT,SO,false,false>::canAlias( const Other* alias ) const
2426 {
2427  return matrix_.canAlias( alias );
2428 }
2430 //*************************************************************************************************
2431 
2432 
2433 //*************************************************************************************************
2444 template< typename MT // Type of the adapted sparse matrix
2445  , bool SO > // Storage order of the adapted sparse matrix
2446 template< typename Other > // Data type of the foreign expression
2447 inline bool SymmetricMatrix<MT,SO,false,false>::isAliased( const Other* alias ) const
2448 {
2449  return matrix_.isAliased( alias );
2450 }
2452 //*************************************************************************************************
2453 
2454 
2455 //*************************************************************************************************
2466 template< typename MT // Type of the adapted sparse matrix
2467  , bool SO > // Storage order of the adapted sparse matrix
2468 inline bool SymmetricMatrix<MT,SO,false,false>::canSMPAssign() const
2469 {
2470  return matrix_.canSMPAssign();
2471 }
2473 //*************************************************************************************************
2474 
2475 
2476 //*************************************************************************************************
2488 template< typename MT // Type of the adapted sparse matrix
2489  , bool SO > // Storage order of the adapted sparse matrix
2490 template< typename MT2 > // Type of the right-hand side dense matrix
2491 void SymmetricMatrix<MT,SO,false,false>::assign( DenseMatrix<MT2,SO>& rhs )
2492 {
2494 
2495  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2496  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2497 
2498  std::vector<size_t> nonzeros( rows(), 0UL );
2499  size_t sum( 0UL );
2500 
2501  for( size_t i=0UL; i<rows(); ++i ) {
2502  nonzeros[i] = (~rhs).nonZeros(i);
2503  sum += nonzeros[i];
2504  }
2505 
2506  matrix_.reserve( sum );
2507  for( size_t i=0UL; i<rows(); ++i ) {
2508  matrix_.reserve( i, nonzeros[i] );
2509  }
2510 
2511  for( size_t i=0UL; i<rows(); ++i ) {
2512  for( size_t j=i; j<columns(); ++j ) {
2513  if( !isDefault( (~rhs)(i,j) ) ) {
2514  SharedValue<ET> shared;
2515  move( *shared, (~rhs)(i,j) );
2516  matrix_.append( i, j, shared, false );
2517  if( i != j )
2518  matrix_.append( j, i, shared, false );
2519  }
2520  }
2521  }
2522 }
2524 //*************************************************************************************************
2525 
2526 
2527 //*************************************************************************************************
2539 template< typename MT // Type of the adapted sparse matrix
2540  , bool SO > // Storage order of the adapted sparse matrix
2541 template< typename MT2 > // Type of the right-hand side dense matrix
2542 void SymmetricMatrix<MT,SO,false,false>::assign( const DenseMatrix<MT2,SO>& rhs )
2543 {
2545 
2546  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2547  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2548 
2549  std::vector<size_t> nonzeros( rows(), 0UL );
2550  size_t sum( 0UL );
2551 
2552  for( size_t i=0UL; i<rows(); ++i ) {
2553  nonzeros[i] = (~rhs).nonZeros(i);
2554  sum += nonzeros[i];
2555  }
2556 
2557  matrix_.reserve( sum );
2558  for( size_t i=0UL; i<rows(); ++i ) {
2559  matrix_.reserve( i, nonzeros[i] );
2560  }
2561 
2562  for( size_t i=0UL; i<rows(); ++i ) {
2563  for( size_t j=i; j<columns(); ++j ) {
2564  if( !isDefault( (~rhs)(i,j) ) ) {
2565  const SharedValue<ET> shared( (~rhs)(i,j) );
2566  matrix_.append( i, j, shared, false );
2567  if( i != j )
2568  matrix_.append( j, i, shared, false );
2569  }
2570  }
2571  }
2572 }
2574 //*************************************************************************************************
2575 
2576 
2577 //*************************************************************************************************
2589 template< typename MT // Type of the adapted sparse matrix
2590  , bool SO > // Storage order of the adapted sparse matrix
2591 template< typename MT2 > // Type of the right-hand side sparse matrix
2592 void SymmetricMatrix<MT,SO,false,false>::assign( SparseMatrix<MT2,SO>& rhs )
2593 {
2595 
2596  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2597  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2598 
2599  std::vector<size_t> nonzeros( rows(), 0UL );
2600  size_t sum( 0UL );
2601 
2602  for( size_t i=0UL; i<rows(); ++i ) {
2603  nonzeros[i] = (~rhs).nonZeros(i);
2604  sum += nonzeros[i];
2605  }
2606 
2607  matrix_.reserve( sum );
2608  for( size_t i=0UL; i<rows(); ++i ) {
2609  matrix_.reserve( i, nonzeros[i] );
2610  }
2611 
2612  for( size_t i=0UL; i<rows(); ++i ) {
2613  for( typename MT2::Iterator it=(~rhs).lowerBound(i,i); it!=(~rhs).end(i); ++it ) {
2614  if( !isDefault( it->value() ) ) {
2615  SharedValue<ET> shared;
2616  move( *shared, it->value() );
2617  matrix_.append( i, it->index(), shared, false );
2618  if( i != it->index() )
2619  matrix_.append( it->index(), i, shared, false );
2620  }
2621  }
2622  }
2623 }
2625 //*************************************************************************************************
2626 
2627 
2628 //*************************************************************************************************
2640 template< typename MT // Type of the adapted sparse matrix
2641  , bool SO > // Storage order of the adapted sparse matrix
2642 template< typename MT2 > // Type of the right-hand side sparse matrix
2643 void SymmetricMatrix<MT,SO,false,false>::assign( const SparseMatrix<MT2,SO>& rhs )
2644 {
2646 
2647  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2648  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2649 
2650  std::vector<size_t> nonzeros( rows(), 0UL );
2651  size_t sum( 0UL );
2652 
2653  for( size_t i=0UL; i<rows(); ++i ) {
2654  nonzeros[i] = (~rhs).nonZeros(i);
2655  sum += nonzeros[i];
2656  }
2657 
2658  matrix_.reserve( sum );
2659  for( size_t i=0UL; i<rows(); ++i ) {
2660  matrix_.reserve( i, nonzeros[i] );
2661  }
2662 
2663  for( size_t i=0UL; i<rows(); ++i ) {
2664  for( typename MT2::ConstIterator it=(~rhs).lowerBound(i,i); it!=(~rhs).end(i); ++it ) {
2665  if( !isDefault( it->value() ) ) {
2666  const SharedValue<ET> shared( it->value() );
2667  matrix_.append( i, it->index(), shared, false );
2668  if( i != it->index() )
2669  matrix_.append( it->index(), i, shared, false );
2670  }
2671  }
2672  }
2673 }
2675 //*************************************************************************************************
2676 
2677 } // namespace blaze
2678 
2679 #endif
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:116
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
Constraint on the data type.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
Constraint on the data type.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the Rows type trait.
Header file for the UNUSED_PARAMETER function template.
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7820
Header file for the subtraction trait.
Header file for basic type definitions.
BLAZE_ALWAYS_INLINE bool isSquare(const Matrix< MT, SO > &matrix)
Checks if the given matrix is a square matrix.
Definition: Matrix.h:603
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:229
void move(CompressedMatrix< Type, SO > &dst, CompressedMatrix< Type, SO > &src)
Moving the contents of one compressed matrix to another.
Definition: CompressedMatrix.h:5016
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:292
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:250
#define BLAZE_CONSTRAINT_MUST_BE_MATRIX_WITH_STORAGE_ORDER(T, SO)
Constraint on the data type.In case the given data type T is not a dense or sparse matrix type and in...
Definition: StorageOrder.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:118
Constraint on the data type.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:697
Constraint on the data type.
Header file for the SharedValue class.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:340
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:4926
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:584
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2582
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:116
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:378
Constraint on the data type.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2584
Header file for the implementation of the base template of the SymmetricMatrix.
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
Constraint on the data type.
Constraint on the data type.
Header file for the SparseMatrix base class.
Header file for utility functions for sparse matrices.
Header file for the IsSquare type trait.
Constraint on the data type.
bool isDefault(const CompressedMatrix< Type, SO > &m)
Returns whether the given compressed matrix is in default state.
Definition: CompressedMatrix.h:4953
Header file for the multiplication trait.
Header file for the IsSymmetric type trait.
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
Compile time assertion.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b)
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:4998
bool isIntact(const CompressedMatrix< Type, SO > &m)
Returns whether the invariants of the given compressed matrix are intact.
Definition: CompressedMatrix.h:4980
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:116
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
Header file for the Columns type trait.
BLAZE_ALWAYS_INLINE void conjugate(T &a)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Constraint on the data type.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc)
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:642
Header file for the SparseElement base class.
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2585
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UPPER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a upper triangular matrix type...
Definition: Upper.h:118
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:187
#define BLAZE_CONSTRAINT_MUST_NOT_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is a numeric (integral or floating point) d...
Definition: Numeric.h:118
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:532
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2586
Header file for the RemoveAdaptor type trait.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2590
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:527
Header file for the NonNumericProxy class.
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2587
Header file for run time assertion macros.
Header file for the addition trait.
Constraint on the data type.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_LOWER_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower triangular matrix type...
Definition: Lower.h:118
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:116
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2591
Header file for the isDefault shim.
Constraint on the data type.
Constraint on the data type.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b)
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:256
BLAZE_ALWAYS_INLINE int16_t sum(const simd_int16_t &a)
Returns the sum of all elements in the 16-bit integral intrinsic vector.
Definition: Reduction.h:63
Header file for the move shim.
#define BLAZE_CONSTRAINT_MUST_BE_RESIZABLE(T)
Constraint on the data type.In case the given data type T is not resizable, i.e. does not have a 'res...
Definition: Resizable.h:79
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:944
Header file for the IsComputation type trait class.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_EXPRESSION_TYPE(T)
Constraint on the data type.In case the given data type T is an expression (i.e. a type derived from ...
Definition: Expression.h:118
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2583
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:324
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:237
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2589
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type, a compilation error is created.
Definition: Hermitian.h:116
Header file for exception macros.
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:143
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:558