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 <stdexcept>
46 #include <vector>
59 #include <blaze/math/shims/Clear.h>
61 #include <blaze/math/shims/Move.h>
72 #include <blaze/util/Assert.h>
78 #include <blaze/util/EnableIf.h>
79 #include <blaze/util/mpl/If.h>
82 #include <blaze/util/Types.h>
83 #include <blaze/util/Unused.h>
84 
85 
86 namespace blaze {
87 
88 //=================================================================================================
89 //
90 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES WITH NON-NUMERIC ELEMENT TYPE
91 //
92 //=================================================================================================
93 
94 //*************************************************************************************************
102 template< typename MT // Type of the adapted sparse matrix
103  , bool SO > // Storage order of the adapted sparse matrix
104 class SymmetricMatrix<MT,SO,false,false>
105  : public SparseMatrix< SymmetricMatrix<MT,SO,false,false>, SO >
106 {
107  private:
108  //**Type definitions****************************************************************************
109  typedef typename MT::OppositeType OT;
110  typedef typename MT::TransposeType TT;
111  typedef typename MT::ElementType ET;
112 
114  typedef typename MT::template Rebind< SharedValue<ET> >::Other MatrixType;
115  //**********************************************************************************************
116 
117  public:
118  //**Type definitions****************************************************************************
119  typedef SymmetricMatrix<MT,SO,false,false> This;
120  typedef This ResultType;
121  typedef SymmetricMatrix<OT,!SO,false,false> OppositeType;
122  typedef SymmetricMatrix<TT,!SO,false,false> TransposeType;
123  typedef ET ElementType;
124  typedef typename MT::ReturnType ReturnType;
125  typedef const This& CompositeType;
126  typedef NonNumericProxy<MatrixType> Reference;
127  typedef typename MT::ConstReference ConstReference;
128  //**********************************************************************************************
129 
130  //**Rebind struct definition********************************************************************
133  template< typename ET > // Data type of the other matrix
134  struct Rebind {
136  typedef SymmetricMatrix< typename MT::template Rebind<ET>::Other > Other;
137  };
138  //**********************************************************************************************
139 
140  //**SharedElement class definition**************************************************************
143  template< typename IteratorType > // Type of the sparse matrix iterator
144  class SharedElement : private SparseElement
145  {
146  public:
147  //**Type definitions*************************************************************************
148  typedef ET ValueType;
149  typedef size_t IndexType;
150  typedef ValueType& Reference;
151  typedef const ValueType& ConstReference;
152  typedef SharedElement* Pointer;
153  typedef const SharedElement* ConstPointer;
154  //*******************************************************************************************
155 
156  //**Constructor******************************************************************************
161  inline SharedElement( IteratorType pos )
162  : pos_( pos ) // Iterator to the current sparse symmetric matrix element
163  {}
164  //*******************************************************************************************
165 
166  //**Assignment operator**********************************************************************
172  template< typename T > inline SharedElement& operator=( const T& v ) {
173  *pos_->value() = v;
174  return *this;
175  }
176  //*******************************************************************************************
177 
178  //**Addition assignment operator*************************************************************
184  template< typename T > inline SharedElement& operator+=( const T& v ) {
185  *pos_->value() += v;
186  return *this;
187  }
188  //*******************************************************************************************
189 
190  //**Subtraction assignment operator**********************************************************
196  template< typename T > inline SharedElement& operator-=( const T& v ) {
197  *pos_->value() -= v;
198  return *this;
199  }
200  //*******************************************************************************************
201 
202  //**Multiplication assignment operator*******************************************************
208  template< typename T > inline SharedElement& operator*=( const T& v ) {
209  *pos_->value() *= v;
210  return *this;
211  }
212  //*******************************************************************************************
213 
214  //**Division assignment operator*************************************************************
220  template< typename T > inline SharedElement& operator/=( const T& v ) {
221  *pos_->value() /= v;
222  return *this;
223  }
224  //*******************************************************************************************
225 
226  //**Element access operator******************************************************************
231  inline Pointer operator->() {
232  return this;
233  }
234  //*******************************************************************************************
235 
236  //**Element access operator******************************************************************
241  inline ConstPointer operator->() const {
242  return this;
243  }
244  //*******************************************************************************************
245 
246  //**Value function***************************************************************************
251  inline Reference value() {
252  return *pos_->value();
253  }
254  //*******************************************************************************************
255 
256  //**Value function***************************************************************************
261  inline ConstReference value() const {
262  return *pos_->value();
263  }
264  //*******************************************************************************************
265 
266  //**Index function***************************************************************************
271  inline IndexType index() const {
272  return pos_->index();
273  }
274  //*******************************************************************************************
275 
276  private:
277  //**Member variables*************************************************************************
278  IteratorType pos_;
279  //*******************************************************************************************
280  };
281  //**********************************************************************************************
282 
283  //**SharedIterator class definition*************************************************************
286  template< typename SparseElementType // Type of the underlying sparse elements.
287  , typename IteratorType > // Type of the sparse matrix iterator
288  class SharedIterator
289  {
290  public:
291  //**Type definitions*************************************************************************
292  typedef std::forward_iterator_tag IteratorCategory;
293  typedef SparseElementType ValueType;
294  typedef SparseElementType PointerType;
295  typedef SparseElementType ReferenceType;
296  typedef ptrdiff_t DifferenceType;
297 
298  // STL iterator requirements
299  typedef IteratorCategory iterator_category;
300  typedef ValueType value_type;
301  typedef PointerType pointer;
302  typedef ReferenceType reference;
303  typedef DifferenceType difference_type;
304  //*******************************************************************************************
305 
306  //**Default constructor**********************************************************************
309  inline SharedIterator()
310  : pos_() // Iterator to the current sparse symmetric matrix element
311  {}
312  //*******************************************************************************************
313 
314  //**Constructor******************************************************************************
319  inline SharedIterator( IteratorType pos )
320  : pos_( pos ) // Iterator to the current sparse symmetric matrix element
321  {}
322  //*******************************************************************************************
323 
324  //**Constructor******************************************************************************
329  template< typename SparseElementType2, typename IteratorType2 >
330  inline SharedIterator( const SharedIterator<SparseElementType2,IteratorType2>& it )
331  : pos_( it.pos_ ) // Iterator to the current sparse symmetric matrix element
332  {}
333  //*******************************************************************************************
334 
335  //**Prefix increment operator****************************************************************
340  inline SharedIterator& operator++() {
341  ++pos_;
342  return *this;
343  }
344  //*******************************************************************************************
345 
346  //**Postfix increment operator***************************************************************
351  inline const SharedIterator operator++( int ) {
352  const SharedIterator tmp( *this );
353  ++(*this);
354  return tmp;
355  }
356  //*******************************************************************************************
357 
358  //**Element access operator******************************************************************
363  inline ReferenceType operator*() const {
364  return ReferenceType( pos_ );
365  }
366  //*******************************************************************************************
367 
368  //**Element access operator******************************************************************
373  inline PointerType operator->() const {
374  return PointerType( pos_ );
375  }
376  //*******************************************************************************************
377 
378  //**Equality operator************************************************************************
384  inline bool operator==( const SharedIterator& rhs ) const {
385  return pos_ == rhs.pos_;
386  }
387  //*******************************************************************************************
388 
389  //**Inequality operator**********************************************************************
395  inline bool operator!=( const SharedIterator& rhs ) const {
396  return !( *this == rhs );
397  }
398  //*******************************************************************************************
399 
400  //**Subtraction operator*********************************************************************
406  inline DifferenceType operator-( const SharedIterator& rhs ) const {
407  return pos_ - rhs.pos_;
408  }
409  //*******************************************************************************************
410 
411  //**Base function****************************************************************************
416  inline IteratorType base() const {
417  return pos_;
418  }
419  //*******************************************************************************************
420 
421  private:
422  //**Member variables*************************************************************************
423  IteratorType pos_;
424  //*******************************************************************************************
425 
426  //**Friend declarations**********************************************************************
427  template< typename SparseElementType2, typename IteratorType2 > friend class SharedIterator;
428  //*******************************************************************************************
429  };
430  //**********************************************************************************************
431 
432  //**Type definitions****************************************************************************
434  typedef SharedIterator< SharedElement< typename MatrixType::Iterator >
435  , typename MatrixType::Iterator
436  > Iterator;
437 
439  typedef SharedIterator< const SharedElement< typename MatrixType::ConstIterator >
440  , typename MatrixType::ConstIterator
441  > ConstIterator;
442  //**********************************************************************************************
443 
444  //**Compilation flags***************************************************************************
446  enum { smpAssignable = 0 };
447  //**********************************************************************************************
448 
449  //**Constructors********************************************************************************
452  explicit inline SymmetricMatrix();
453  explicit inline SymmetricMatrix( size_t n );
454  explicit inline SymmetricMatrix( size_t n, size_t nonzeros );
455  explicit inline SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros );
456 
457  inline SymmetricMatrix( const SymmetricMatrix& m );
458  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
459  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
461  //**********************************************************************************************
462 
463  //**Destructor**********************************************************************************
464  // No explicitly declared destructor.
465  //**********************************************************************************************
466 
467  //**Data access functions***********************************************************************
470  inline Reference operator()( size_t i, size_t j );
471  inline ConstReference operator()( size_t i, size_t j ) const;
472  inline Iterator begin ( size_t i );
473  inline ConstIterator begin ( size_t i ) const;
474  inline ConstIterator cbegin( size_t i ) const;
475  inline Iterator end ( size_t i );
476  inline ConstIterator end ( size_t i ) const;
477  inline ConstIterator cend ( size_t i ) const;
479  //**********************************************************************************************
480 
481  //**Assignment operators************************************************************************
484  inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
485 
486  template< typename MT2 >
487  inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
488  operator=( const Matrix<MT2,SO>& rhs );
489 
490  template< typename MT2 >
491  inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
492  operator=( const Matrix<MT2,SO>& rhs );
493 
494  template< typename MT2 >
495  inline SymmetricMatrix& operator=( const Matrix<MT2,!SO>& rhs );
496 
497  template< typename MT2 >
498  inline SymmetricMatrix& operator+=( const Matrix<MT2,SO>& rhs );
499 
500  template< typename MT2 >
501  inline SymmetricMatrix& operator+=( const Matrix<MT2,!SO>& rhs );
502 
503  template< typename MT2 >
504  inline SymmetricMatrix& operator-=( const Matrix<MT2,SO>& rhs );
505 
506  template< typename MT2 >
507  inline SymmetricMatrix& operator-=( const Matrix<MT2,!SO>& rhs );
508 
509  template< typename MT2, bool SO2 >
510  inline SymmetricMatrix& operator*=( const Matrix<MT2,SO2>& rhs );
511 
512  template< typename Other >
513  inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix >::Type&
514  operator*=( Other rhs );
515 
516  template< typename Other >
517  inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix >::Type&
518  operator/=( Other rhs );
520  //**********************************************************************************************
521 
522  //**Utility functions***************************************************************************
525  inline size_t rows() const;
526  inline size_t columns() const;
527  inline size_t capacity() const;
528  inline size_t capacity( size_t i ) const;
529  inline size_t nonZeros() const;
530  inline size_t nonZeros( size_t i ) const;
531  inline void reset();
532  inline void reset( size_t i );
533  inline void clear();
534  inline Iterator set( size_t i, size_t j, const ElementType& value );
535  inline Iterator insert( size_t i, size_t j, const ElementType& value );
536  inline void erase( size_t i, size_t j );
537  inline Iterator erase( size_t i, Iterator pos );
538  inline Iterator erase( size_t i, Iterator first, Iterator last );
539  inline void resize ( size_t n, bool preserve=true );
540  inline void reserve( size_t nonzeros );
541  inline void reserve( size_t i, size_t nonzeros );
542  inline void trim();
543  inline void trim( size_t i );
544  inline SymmetricMatrix& transpose();
545  template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
546  template< typename Other > inline SymmetricMatrix& scaleDiagonal( Other scale );
547  inline void swap( SymmetricMatrix& m ) /* throw() */;
549  //**********************************************************************************************
550 
551  //**Lookup functions****************************************************************************
554  inline Iterator find ( size_t i, size_t j );
555  inline ConstIterator find ( size_t i, size_t j ) const;
556  inline Iterator lowerBound( size_t i, size_t j );
557  inline ConstIterator lowerBound( size_t i, size_t j ) const;
558  inline Iterator upperBound( size_t i, size_t j );
559  inline ConstIterator upperBound( size_t i, size_t j ) const;
561  //**********************************************************************************************
562 
563  //**Low-level utility functions*****************************************************************
566  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
567  inline void finalize( size_t i );
569  //**********************************************************************************************
570 
571  public:
572  //**Expression template evaluation functions****************************************************
575  template< typename Other > inline bool canAlias ( const Other* alias ) const;
576  template< typename Other > inline bool isAliased( const Other* alias ) const;
577 
578  inline bool canSMPAssign() const;
580  //**********************************************************************************************
581 
582  private:
583  //**Expression template evaluation functions****************************************************
586  template< typename MT2 > void assign( DenseMatrix<MT2,SO>& rhs );
587  template< typename MT2 > void assign( const DenseMatrix<MT2,SO>& rhs );
588  template< typename MT2 > void assign( SparseMatrix<MT2,SO>& rhs );
589  template< typename MT2 > void assign( const SparseMatrix<MT2,SO>& rhs );
591  //**********************************************************************************************
592 
593  //**Member variables****************************************************************************
596  MatrixType matrix_;
597 
598  //**********************************************************************************************
599 
600  //**Friend declarations*************************************************************************
601  template< typename MT2, bool SO2, bool DF2, bool NF2 >
602  friend bool isDefault( const SymmetricMatrix<MT2,SO2,DF2,NF2>& m );
603  //**********************************************************************************************
604 
605  //**Compile time checks*************************************************************************
618  BLAZE_STATIC_ASSERT( IsResizable<MT>::value || IsSquare<MT>::value );
619  //**********************************************************************************************
620 };
622 //*************************************************************************************************
623 
624 
625 
626 
627 //=================================================================================================
628 //
629 // CONSTRUCTORS
630 //
631 //=================================================================================================
632 
633 //*************************************************************************************************
637 template< typename MT // Type of the adapted sparse matrix
638  , bool SO > // Storage order of the adapted sparse matrix
639 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix()
640  : matrix_() // The adapted sparse matrix
641 {
642  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
643 }
645 //*************************************************************************************************
646 
647 
648 //*************************************************************************************************
656 template< typename MT // Type of the adapted sparse matrix
657  , bool SO > // Storage order of the adapted sparse matrix
658 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n )
659  : matrix_( n, n ) // The adapted sparse matrix
660 {
662 
663  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
664 }
666 //*************************************************************************************************
667 
668 
669 //*************************************************************************************************
678 template< typename MT // Type of the adapted sparse matrix
679  , bool SO > // Storage order of the adapted sparse matrix
680 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n, size_t nonzeros )
681  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
682 {
684 
685  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
686 }
688 //*************************************************************************************************
689 
690 
691 //*************************************************************************************************
702 template< typename MT // Type of the adapted sparse matrix
703  , bool SO > // Storage order of the adapted sparse matrix
704 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
705  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
706 {
708 
709  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
710 }
712 //*************************************************************************************************
713 
714 
715 //*************************************************************************************************
721 template< typename MT // Type of the adapted sparse matrix
722  , bool SO > // Storage order of the adapted sparse matrix
723 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const SymmetricMatrix& m )
724  : matrix_() // The adapted sparse matrix
725 {
726  using blaze::resize;
727 
728  resize( matrix_, m.rows(), m.columns() );
729  assign( m );
730 
731  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
732 }
734 //*************************************************************************************************
735 
736 
737 //*************************************************************************************************
747 template< typename MT // Type of the adapted sparse matrix
748  , bool SO > // Storage order of the adapted sparse matrix
749 template< typename MT2 > // Type of the foreign matrix
750 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const Matrix<MT2,SO>& m )
751  : matrix_() // The adapted sparse matrix
752 {
753  using blaze::resize;
754 
755  typedef typename RemoveAdaptor<typename MT2::ResultType>::Type RT;
756  typedef typename If< IsComputation<MT2>, RT, const MT2& >::Type Tmp;
757 
758  Tmp tmp( ~m );
759 
760  if( !IsSymmetric<MT2>::value && !isSymmetric( tmp ) )
761  throw std::invalid_argument( "Invalid setup of symmetric matrix" );
762 
763  resize( matrix_, tmp.rows(), tmp.columns() );
764  assign( tmp );
765 
766  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
767 }
769 //*************************************************************************************************
770 
771 
772 //*************************************************************************************************
782 template< typename MT // Type of the adapted sparse matrix
783  , bool SO > // Storage order of the adapted sparse matrix
784 template< typename MT2 > // Type of the foreign matrix
785 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
786  : matrix_() // The adapted sparse matrix
787 {
788  using blaze::resize;
789 
790  typedef typename RemoveAdaptor<typename MT2::ResultType>::Type RT;
791  typedef typename If< IsComputation<MT2>, RT, const MT2& >::Type Tmp;
792 
793  Tmp tmp( ~m );
794 
795  if( !IsSymmetric<MT2>::value && !isSymmetric( tmp ) )
796  throw std::invalid_argument( "Invalid setup of symmetric matrix" );
797 
798  resize( matrix_, tmp.rows(), tmp.columns() );
799  assign( trans( tmp ) );
800 
801  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
802 }
804 //*************************************************************************************************
805 
806 
807 
808 
809 //=================================================================================================
810 //
811 // DATA ACCESS FUNCTIONS
812 //
813 //=================================================================================================
814 
815 //*************************************************************************************************
827 template< typename MT // Type of the adapted sparse matrix
828  , bool SO > // Storage order of the adapted sparse matrix
830  SymmetricMatrix<MT,SO,false,false>::operator()( size_t i, size_t j )
831 {
832  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
833  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
834 
835  return Reference( matrix_, i, j );
836 }
838 //*************************************************************************************************
839 
840 
841 //*************************************************************************************************
853 template< typename MT // Type of the adapted sparse matrix
854  , bool SO > // Storage order of the adapted sparse matrix
856  SymmetricMatrix<MT,SO,false,false>::operator()( size_t i, size_t j ) const
857 {
858  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
859  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
860 
861  return *matrix_(i,j);
862 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
879 template< typename MT // Type of the adapted sparse matrix
880  , bool SO > // Storage order of the adapted sparse matrix
883 {
884  return Iterator( matrix_.begin(i) );
885 }
887 //*************************************************************************************************
888 
889 
890 //*************************************************************************************************
902 template< typename MT // Type of the adapted sparse matrix
903  , bool SO > // Storage order of the adapted sparse matrix
906 {
907  return ConstIterator( matrix_.begin(i) );
908 }
910 //*************************************************************************************************
911 
912 
913 //*************************************************************************************************
925 template< typename MT // Type of the adapted sparse matrix
926  , bool SO > // Storage order of the adapted sparse matrix
929 {
930  return ConstIterator( matrix_.cbegin(i) );
931 }
933 //*************************************************************************************************
934 
935 
936 //*************************************************************************************************
948 template< typename MT // Type of the adapted sparse matrix
949  , bool SO > // Storage order of the adapted sparse matrix
952 {
953  return Iterator( matrix_.end(i) );
954 }
956 //*************************************************************************************************
957 
958 
959 //*************************************************************************************************
971 template< typename MT // Type of the adapted sparse matrix
972  , bool SO > // Storage order of the adapted sparse matrix
975 {
976  return ConstIterator( matrix_.end(i) );
977 }
979 //*************************************************************************************************
980 
981 
982 //*************************************************************************************************
994 template< typename MT // Type of the adapted sparse matrix
995  , bool SO > // Storage order of the adapted sparse matrix
998 {
999  return ConstIterator( matrix_.cend(i) );
1000 }
1002 //*************************************************************************************************
1003 
1004 
1005 
1006 
1007 //=================================================================================================
1008 //
1009 // ASSIGNMENT OPERATORS
1010 //
1011 //=================================================================================================
1012 
1013 //*************************************************************************************************
1023 template< typename MT // Type of the adapted sparse matrix
1024  , bool SO > // Storage order of the adapted sparse matrix
1025 inline SymmetricMatrix<MT,SO,false,false>&
1026  SymmetricMatrix<MT,SO,false,false>::operator=( const SymmetricMatrix& rhs )
1027 {
1028  using blaze::resize;
1029 
1030  if( &rhs == this ) return *this;
1031 
1032  resize( matrix_, rhs.rows(), rhs.columns() );
1033  reset();
1034  assign( rhs );
1035 
1036  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1037 
1038  return *this;
1039 }
1041 //*************************************************************************************************
1042 
1043 
1044 //*************************************************************************************************
1058 template< typename MT // Type of the adapted sparse matrix
1059  , bool SO > // Storage order of the adapted sparse matrix
1060 template< typename MT2 > // Type of the right-hand side matrix
1061 inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,false>& >::Type
1062  SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1063 {
1064  using blaze::resize;
1065 
1066  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) )
1067  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1068 
1069  if( (~rhs).canAlias( this ) ) {
1070  SymmetricMatrix tmp( ~rhs );
1071  swap( tmp );
1072  }
1073  else {
1074  resize( matrix_, (~rhs).rows(), (~rhs).columns() );
1075  reset();
1076  assign( ~rhs );
1077  }
1078 
1079  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1080 
1081  return *this;
1082 }
1084 //*************************************************************************************************
1085 
1086 
1087 //*************************************************************************************************
1101 template< typename MT // Type of the adapted sparse matrix
1102  , bool SO > // Storage order of the adapted sparse matrix
1103 template< typename MT2 > // Type of the right-hand side matrix
1104 inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,false>& >::Type
1105  SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1106 {
1107  using blaze::resize;
1108 
1109  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) )
1110  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1111 
1112  typename MT2::ResultType tmp( ~rhs );
1113 
1114  if( !IsSymmetric<MT2>::value && !isSymmetric( tmp ) )
1115  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1116 
1117  resize( matrix_, tmp.rows(), tmp.columns() );
1118  reset();
1119  assign( tmp );
1120 
1121  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1122 
1123  return *this;
1124 }
1126 //*************************************************************************************************
1127 
1128 
1129 //*************************************************************************************************
1143 template< typename MT // Type of the adapted sparse matrix
1144  , bool SO > // Storage order of the adapted sparse matrix
1145 template< typename MT2 > // Type of the right-hand side matrix
1146 inline SymmetricMatrix<MT,SO,false,false>&
1147  SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,!SO>& rhs )
1148 {
1149  return this->operator=( trans( ~rhs ) );
1150 }
1152 //*************************************************************************************************
1153 
1154 
1155 //*************************************************************************************************
1168 template< typename MT // Type of the adapted sparse matrix
1169  , bool SO > // Storage order of the adapted sparse matrix
1170 template< typename MT2 > // Type of the right-hand side matrix
1171 inline SymmetricMatrix<MT,SO,false,false>&
1172  SymmetricMatrix<MT,SO,false,false>::operator+=( const Matrix<MT2,SO>& rhs )
1173 {
1174  using blaze::resize;
1175 
1176  typedef typename AddTrait<MT,typename MT2::ResultType>::Type Tmp;
1177 
1178  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) )
1179  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1180 
1181  Tmp tmp( (*this) + ~rhs );
1182 
1183  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) )
1184  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1185 
1186  resize( matrix_, tmp.rows(), tmp.columns() );
1187  reset();
1188  assign( tmp );
1189 
1190  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1191 
1192  return *this;
1193 }
1195 //*************************************************************************************************
1196 
1197 
1198 //*************************************************************************************************
1212 template< typename MT // Type of the adapted sparse matrix
1213  , bool SO > // Storage order of the adapted sparse matrix
1214 template< typename MT2 > // Type of the right-hand side matrix
1215 inline SymmetricMatrix<MT,SO,false,false>&
1216  SymmetricMatrix<MT,SO,false,false>::operator+=( const Matrix<MT2,!SO>& rhs )
1217 {
1218  return this->operator+=( trans( ~rhs ) );
1219 }
1221 //*************************************************************************************************
1222 
1223 
1224 //*************************************************************************************************
1237 template< typename MT // Type of the adapted sparse matrix
1238  , bool SO > // Storage order of the adapted sparse matrix
1239 template< typename MT2 > // Type of the right-hand side matrix
1240 inline SymmetricMatrix<MT,SO,false,false>&
1241  SymmetricMatrix<MT,SO,false,false>::operator-=( const Matrix<MT2,SO>& rhs )
1242 {
1243  using blaze::resize;
1244 
1245  typedef typename SubTrait<MT,typename MT2::ResultType>::Type Tmp;
1246 
1247  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) )
1248  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1249 
1250  Tmp tmp( (*this) - ~rhs );
1251 
1252  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) )
1253  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1254 
1255  resize( matrix_, tmp.rows(), tmp.columns() );
1256  reset();
1257  assign( tmp );
1258 
1259  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1260 
1261  return *this;
1262 }
1264 //*************************************************************************************************
1265 
1266 
1267 //*************************************************************************************************
1281 template< typename MT // Type of the adapted sparse matrix
1282  , bool SO > // Storage order of the adapted sparse matrix
1283 template< typename MT2 > // Type of the right-hand side matrix
1284 inline SymmetricMatrix<MT,SO,false,false>&
1285  SymmetricMatrix<MT,SO,false,false>::operator-=( const Matrix<MT2,!SO>& rhs )
1286 {
1287  return this->operator-=( trans( ~rhs ) );
1288 }
1290 //*************************************************************************************************
1291 
1292 
1293 //*************************************************************************************************
1305 template< typename MT // Type of the adapted sparse matrix
1306  , bool SO > // Storage order of the adapted sparse matrix
1307 template< typename MT2 // Type of the right-hand side matrix
1308  , bool SO2 > // Storage order of the right-hand side matrix
1309 inline SymmetricMatrix<MT,SO,false,false>&
1310  SymmetricMatrix<MT,SO,false,false>::operator*=( const Matrix<MT2,SO2>& rhs )
1311 {
1312  using blaze::resize;
1313 
1314  typedef typename MultTrait<MT,typename MT2::ResultType>::Type Tmp;
1315 
1316  if( matrix_.rows() != (~rhs).columns() )
1317  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1318 
1319  Tmp tmp( (*this) * ~rhs );
1320 
1321  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) )
1322  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1323 
1324  resize( matrix_, tmp.rows(), tmp.columns() );
1325  reset();
1326  assign( tmp );
1327 
1328  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1329 
1330  return *this;
1331 }
1333 //*************************************************************************************************
1334 
1335 
1336 //*************************************************************************************************
1344 template< typename MT // Type of the adapted sparse matrix
1345  , bool SO > // Storage order of the adapted sparse matrix
1346 template< typename Other > // Data type of the right-hand side scalar
1347 inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,false> >::Type&
1348  SymmetricMatrix<MT,SO,false,false>::operator*=( Other rhs )
1349 {
1350  for( size_t i=0UL; i<rows(); ++i ) {
1351  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
1352  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
1353  *element->value() *= rhs;
1354  }
1355 
1356  return *this;
1357 }
1359 //*************************************************************************************************
1360 
1361 
1362 //*************************************************************************************************
1370 template< typename MT // Type of the adapted sparse matrix
1371  , bool SO > // Storage order of the adapted sparse matrix
1372 template< typename Other > // Data type of the right-hand side scalar
1373 inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,false> >::Type&
1374  SymmetricMatrix<MT,SO,false,false>::operator/=( Other rhs )
1375 {
1376  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1377 
1378  for( size_t i=0UL; i<rows(); ++i ) {
1379  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
1380  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
1381  *element->value() /= rhs;
1382  }
1383 
1384  return *this;
1385 }
1387 //*************************************************************************************************
1388 
1389 
1390 
1391 
1392 //=================================================================================================
1393 //
1394 // UTILITY FUNCTIONS
1395 //
1396 //=================================================================================================
1397 
1398 //*************************************************************************************************
1404 template< typename MT // Type of the adapted sparse matrix
1405  , bool SO > // Storage order of the adapted sparse matrix
1406 inline size_t SymmetricMatrix<MT,SO,false,false>::rows() const
1407 {
1408  return matrix_.rows();
1409 }
1411 //*************************************************************************************************
1412 
1413 
1414 //*************************************************************************************************
1420 template< typename MT // Type of the adapted sparse matrix
1421  , bool SO > // Storage order of the adapted sparse matrix
1422 inline size_t SymmetricMatrix<MT,SO,false,false>::columns() const
1423 {
1424  return matrix_.columns();
1425 }
1427 //*************************************************************************************************
1428 
1429 
1430 //*************************************************************************************************
1436 template< typename MT // Type of the adapted sparse matrix
1437  , bool SO > // Storage order of the adapted sparse matrix
1439 {
1440  return matrix_.capacity();
1441 }
1443 //*************************************************************************************************
1444 
1445 
1446 //*************************************************************************************************
1457 template< typename MT // Type of the adapted sparse matrix
1458  , bool SO > // Storage order of the adapted sparse matrix
1459 inline size_t SymmetricMatrix<MT,SO,false,false>::capacity( size_t i ) const
1460 {
1461  return matrix_.capacity(i);
1462 }
1464 //*************************************************************************************************
1465 
1466 
1467 //*************************************************************************************************
1473 template< typename MT // Type of the adapted sparse matrix
1474  , bool SO > // Storage order of the adapted sparse matrix
1476 {
1477  return matrix_.nonZeros();
1478 }
1480 //*************************************************************************************************
1481 
1482 
1483 //*************************************************************************************************
1495 template< typename MT // Type of the adapted sparse matrix
1496  , bool SO > // Storage order of the adapted sparse matrix
1497 inline size_t SymmetricMatrix<MT,SO,false,false>::nonZeros( size_t i ) const
1498 {
1499  return matrix_.nonZeros(i);
1500 }
1502 //*************************************************************************************************
1503 
1504 
1505 //*************************************************************************************************
1511 template< typename MT // Type of the adapted sparse matrix
1512  , bool SO > // Storage order of the adapted sparse matrix
1514 {
1515  matrix_.reset();
1516 }
1518 //*************************************************************************************************
1519 
1520 
1521 //*************************************************************************************************
1561 template< typename MT // Type of the adapted sparse matrix
1562  , bool SO > // Storage order of the adapted sparse matrix
1563 inline void SymmetricMatrix<MT,SO,false,false>::reset( size_t i )
1564 {
1565  for( typename MatrixType::Iterator it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1566  {
1567  const size_t j( it->index() );
1568 
1569  if( i == j )
1570  continue;
1571 
1572  if( SO ) {
1573  const typename MatrixType::Iterator pos( matrix_.find( i, j ) );
1574  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1575  matrix_.erase( j, pos );
1576  }
1577  else {
1578  const typename MatrixType::Iterator pos( matrix_.find( j, i ) );
1579  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1580  matrix_.erase( j, pos );
1581  }
1582  }
1583 
1584  matrix_.reset( i );
1585 }
1587 //*************************************************************************************************
1588 
1589 
1590 //*************************************************************************************************
1598 template< typename MT // Type of the adapted sparse matrix
1599  , bool SO > // Storage order of the adapted sparse matrix
1601 {
1602  using blaze::clear;
1603 
1604  clear( matrix_ );
1605 }
1607 //*************************************************************************************************
1608 
1609 
1610 //*************************************************************************************************
1624 template< typename MT // Type of the adapted sparse matrix
1625  , bool SO > // Storage order of the adapted sparse matrix
1627  SymmetricMatrix<MT,SO,false,false>::set( size_t i, size_t j, const ElementType& value )
1628 {
1629  SharedValue<ET> shared( value );
1630 
1631  if( i != j )
1632  matrix_.set( j, i, shared );
1633 
1634  return Iterator( matrix_.set( i, j, shared ) );
1635 }
1637 //*************************************************************************************************
1638 
1639 
1640 //*************************************************************************************************
1655 template< typename MT // Type of the adapted sparse matrix
1656  , bool SO > // Storage order of the adapted sparse matrix
1658  SymmetricMatrix<MT,SO,false,false>::insert( size_t i, size_t j, const ElementType& value )
1659 {
1660  SharedValue<ET> shared( value );
1661 
1662  if( i != j )
1663  matrix_.insert( j, i, shared );
1664 
1665  return Iterator( matrix_.insert( i, j, shared ) );
1666 }
1668 //*************************************************************************************************
1669 
1670 
1671 //*************************************************************************************************
1681 template< typename MT // Type of the adapted sparse matrix
1682  , bool SO > // Storage order of the adapted sparse matrix
1683 inline void SymmetricMatrix<MT,SO,false,false>::erase( size_t i, size_t j )
1684 {
1685  matrix_.erase( i, j );
1686  if( i != j )
1687  matrix_.erase( j, i );
1688 }
1690 //*************************************************************************************************
1691 
1692 
1693 //*************************************************************************************************
1705 template< typename MT // Type of the adapted sparse matrix
1706  , bool SO > // Storage order of the adapted sparse matrix
1708  SymmetricMatrix<MT,SO,false,false>::erase( size_t i, Iterator pos )
1709 {
1710  if( pos == end( i ) )
1711  return pos;
1712 
1713  const size_t j( pos->index() );
1714 
1715  if( i == j )
1716  return Iterator( matrix_.erase( i, pos.base() ) );
1717 
1718  if( SO ) {
1719  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1720  matrix_.erase( j, matrix_.find( i, j ) );
1721  return Iterator( matrix_.erase( i, pos.base() ) );
1722  }
1723  else {
1724  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1725  matrix_.erase( j, matrix_.find( j, i ) );
1726  return Iterator( matrix_.erase( i, pos.base() ) );
1727  }
1728 }
1730 //*************************************************************************************************
1731 
1732 
1733 //*************************************************************************************************
1747 template< typename MT // Type of the adapted sparse matrix
1748  , bool SO > // Storage order of the adapted sparse matrix
1750  SymmetricMatrix<MT,SO,false,false>::erase( size_t i, Iterator first, Iterator last )
1751 {
1752  for( Iterator it=first; it!=last; ++it )
1753  {
1754  const size_t j( it->index() );
1755 
1756  if( i == j )
1757  continue;
1758 
1759  if( SO ) {
1760  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1761  matrix_.erase( i, j );
1762  }
1763  else {
1764  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1765  matrix_.erase( j, i );
1766  }
1767  }
1768 
1769  return Iterator( matrix_.erase( i, first.base(), last.base() ) );
1770 }
1772 //*************************************************************************************************
1773 
1774 
1775 //*************************************************************************************************
1790 template< typename MT // Type of the adapted sparse matrix
1791  , bool SO > // Storage order of the adapted sparse matrix
1792 void SymmetricMatrix<MT,SO,false,false>::resize( size_t n, bool preserve )
1793 {
1795 
1796  UNUSED_PARAMETER( preserve );
1797 
1798  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1799 
1800  matrix_.resize( n, n, true );
1801 }
1803 //*************************************************************************************************
1804 
1805 
1806 //*************************************************************************************************
1817 template< typename MT // Type of the adapted sparse matrix
1818  , bool SO > // Storage order of the adapted sparse matrix
1819 inline void SymmetricMatrix<MT,SO,false,false>::reserve( size_t nonzeros )
1820 {
1821  matrix_.reserve( nonzeros );
1822 }
1824 //*************************************************************************************************
1825 
1826 
1827 //*************************************************************************************************
1841 template< typename MT // Type of the adapted sparse matrix
1842  , bool SO > // Storage order of the adapted sparse matrix
1843 inline void SymmetricMatrix<MT,SO,false,false>::reserve( size_t i, size_t nonzeros )
1844 {
1845  matrix_.reserve( i, nonzeros );
1846 }
1848 //*************************************************************************************************
1849 
1850 
1851 //*************************************************************************************************
1862 template< typename MT // Type of the adapted sparse matrix
1863  , bool SO > // Storage order of the adapted sparse matrix
1864 inline void SymmetricMatrix<MT,SO,false,false>::trim()
1865 {
1866  matrix_.trim();
1867 }
1869 //*************************************************************************************************
1870 
1871 
1872 //*************************************************************************************************
1884 template< typename MT // Type of the adapted sparse matrix
1885  , bool SO > // Storage order of the adapted sparse matrix
1886 inline void SymmetricMatrix<MT,SO,false,false>::trim( size_t i )
1887 {
1888  matrix_.trim( i );
1889 }
1891 //*************************************************************************************************
1892 
1893 
1894 //*************************************************************************************************
1900 template< typename MT // Type of the adapted sparse matrix
1901  , bool SO > // Storage order of the adapted sparse matrix
1902 inline SymmetricMatrix<MT,SO,false,false>& SymmetricMatrix<MT,SO,false,false>::transpose()
1903 {
1904  return *this;
1905 }
1907 //*************************************************************************************************
1908 
1909 
1910 //*************************************************************************************************
1917 template< typename MT // Type of the adapted sparse matrix
1918  , bool SO > // Storage order of the adapted sparse matrix
1919 template< typename Other > // Data type of the scalar value
1920 inline SymmetricMatrix<MT,SO,false,false>&
1921  SymmetricMatrix<MT,SO,false,false>::scale( const Other& scalar )
1922 {
1923  for( size_t i=0UL; i<rows(); ++i ) {
1924  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
1925  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
1926  ( *element->value() ).scale( scalar );
1927  }
1928 
1929  return *this;
1930 }
1932 //*************************************************************************************************
1933 
1934 
1935 //*************************************************************************************************
1942 template< typename MT // Type of the adapted sparse matrix
1943  , bool SO > // Storage order of the adapted sparse matrix
1944 template< typename Other > // Data type of the scalar value
1945 inline SymmetricMatrix<MT,SO,false,false>&
1946  SymmetricMatrix<MT,SO,false,false>::scaleDiagonal( Other scalar )
1947 {
1948  matrix_.scaleDiagonal( scalar );
1949  return *this;
1950 }
1952 //*************************************************************************************************
1953 
1954 
1955 //*************************************************************************************************
1963 template< typename MT // Type of the adapted sparse matrix
1964  , bool SO > // Storage order of the adapted sparse matrix
1965 inline void SymmetricMatrix<MT,SO,false,false>::swap( SymmetricMatrix& m ) /* throw() */
1966 {
1967  using std::swap;
1968 
1969  swap( matrix_, m.matrix_ );
1970 }
1972 //*************************************************************************************************
1973 
1974 
1975 
1976 
1977 //=================================================================================================
1978 //
1979 // LOOKUP FUNCTIONS
1980 //
1981 //=================================================================================================
1982 
1983 //*************************************************************************************************
1999 template< typename MT // Type of the adapted sparse matrix
2000  , bool SO > // Storage order of the adapted sparse matrix
2002  SymmetricMatrix<MT,SO,false,false>::find( size_t i, size_t j )
2003 {
2004  return Iterator( matrix_.find( i, j ) );
2005 }
2007 //*************************************************************************************************
2008 
2009 
2010 //*************************************************************************************************
2026 template< typename MT // Type of the adapted sparse matrix
2027  , bool SO > // Storage order of the adapted sparse matrix
2029  SymmetricMatrix<MT,SO,false,false>::find( size_t i, size_t j ) const
2030 {
2031  return ConstIterator( matrix_.find( i, j ) );
2032 }
2034 //*************************************************************************************************
2035 
2036 
2037 //*************************************************************************************************
2053 template< typename MT // Type of the adapted sparse matrix
2054  , bool SO > // Storage order of the adapted sparse matrix
2056  SymmetricMatrix<MT,SO,false,false>::lowerBound( size_t i, size_t j )
2057 {
2058  return Iterator( matrix_.lowerBound( i, j ) );
2059 }
2061 //*************************************************************************************************
2062 
2063 
2064 //*************************************************************************************************
2080 template< typename MT // Type of the adapted sparse matrix
2081  , bool SO > // Storage order of the adapted sparse matrix
2083  SymmetricMatrix<MT,SO,false,false>::lowerBound( size_t i, size_t j ) const
2084 {
2085  return ConstIterator( matrix_.lowerBound( i, j ) );
2086 }
2088 //*************************************************************************************************
2089 
2090 
2091 //*************************************************************************************************
2107 template< typename MT // Type of the adapted sparse matrix
2108  , bool SO > // Storage order of the adapted sparse matrix
2110  SymmetricMatrix<MT,SO,false,false>::upperBound( size_t i, size_t j )
2111 {
2112  return Iterator( matrix_.upperBound( i, j ) );
2113 }
2115 //*************************************************************************************************
2116 
2117 
2118 //*************************************************************************************************
2134 template< typename MT // Type of the adapted sparse matrix
2135  , bool SO > // Storage order of the adapted sparse matrix
2137  SymmetricMatrix<MT,SO,false,false>::upperBound( size_t i, size_t j ) const
2138 {
2139  return ConstIterator( matrix_.upperBound( i, j ) );
2140 }
2142 //*************************************************************************************************
2143 
2144 
2145 
2146 
2147 //=================================================================================================
2148 //
2149 // LOW-LEVEL UTILITY FUNCTIONS
2150 //
2151 //=================================================================================================
2152 
2153 //*************************************************************************************************
2208 template< typename MT // Type of the adapted sparse matrix
2209  , bool SO > // Storage order of the adapted sparse matrix
2210 inline void SymmetricMatrix<MT,SO,false,false>::append( size_t i, size_t j, const ElementType& value, bool check )
2211 {
2212  SharedValue<ET> shared( value );
2213 
2214  matrix_.append( i, j, shared, check );
2215  if( i != j && ( !check || !isDefault( value ) ) )
2216  matrix_.insert( j, i, shared );
2217 }
2219 //*************************************************************************************************
2220 
2221 
2222 //*************************************************************************************************
2236 template< typename MT // Type of the adapted sparse matrix
2237  , bool SO > // Storage order of the adapted sparse matrix
2238 inline void SymmetricMatrix<MT,SO,false,false>::finalize( size_t i )
2239 {
2240  matrix_.trim( i );
2241 }
2243 //*************************************************************************************************
2244 
2245 
2246 
2247 
2248 //=================================================================================================
2249 //
2250 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2251 //
2252 //=================================================================================================
2253 
2254 //*************************************************************************************************
2265 template< typename MT // Type of the adapted sparse matrix
2266  , bool SO > // Storage order of the adapted sparse matrix
2267 template< typename Other > // Data type of the foreign expression
2268 inline bool SymmetricMatrix<MT,SO,false,false>::canAlias( const Other* alias ) const
2269 {
2270  return matrix_.canAlias( alias );
2271 }
2273 //*************************************************************************************************
2274 
2275 
2276 //*************************************************************************************************
2287 template< typename MT // Type of the adapted sparse matrix
2288  , bool SO > // Storage order of the adapted sparse matrix
2289 template< typename Other > // Data type of the foreign expression
2290 inline bool SymmetricMatrix<MT,SO,false,false>::isAliased( const Other* alias ) const
2291 {
2292  return matrix_.isAliased( alias );
2293 }
2295 //*************************************************************************************************
2296 
2297 
2298 //*************************************************************************************************
2309 template< typename MT // Type of the adapted sparse matrix
2310  , bool SO > // Storage order of the adapted sparse matrix
2311 inline bool SymmetricMatrix<MT,SO,false,false>::canSMPAssign() const
2312 {
2313  return matrix_.canSMPAssign();
2314 }
2316 //*************************************************************************************************
2317 
2318 
2319 //*************************************************************************************************
2331 template< typename MT // Type of the adapted sparse matrix
2332  , bool SO > // Storage order of the adapted sparse matrix
2333 template< typename MT2 > // Type of the right-hand side dense matrix
2334 void SymmetricMatrix<MT,SO,false,false>::assign( DenseMatrix<MT2,SO>& rhs )
2335 {
2337 
2338  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2339  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2340 
2341  std::vector<size_t> nonzeros( rows(), 0UL );
2342  size_t sum( 0UL );
2343 
2344  for( size_t i=0UL; i<rows(); ++i ) {
2345  nonzeros[i] = (~rhs).nonZeros(i);
2346  sum += nonzeros[i];
2347  }
2348 
2349  matrix_.reserve( sum );
2350  for( size_t i=0UL; i<rows(); ++i ) {
2351  matrix_.reserve( i, nonzeros[i] );
2352  }
2353 
2354  for( size_t i=0UL; i<rows(); ++i ) {
2355  for( size_t j=i; j<columns(); ++j ) {
2356  if( !isDefault( (~rhs)(i,j) ) ) {
2357  SharedValue<ET> shared;
2358  move( *shared, (~rhs)(i,j) );
2359  matrix_.append( i, j, shared, false );
2360  if( i != j )
2361  matrix_.append( j, i, shared, false );
2362  }
2363  }
2364  }
2365 }
2367 //*************************************************************************************************
2368 
2369 
2370 //*************************************************************************************************
2382 template< typename MT // Type of the adapted sparse matrix
2383  , bool SO > // Storage order of the adapted sparse matrix
2384 template< typename MT2 > // Type of the right-hand side dense matrix
2385 void SymmetricMatrix<MT,SO,false,false>::assign( const DenseMatrix<MT2,SO>& rhs )
2386 {
2388 
2389  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2390  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2391 
2392  std::vector<size_t> nonzeros( rows(), 0UL );
2393  size_t sum( 0UL );
2394 
2395  for( size_t i=0UL; i<rows(); ++i ) {
2396  nonzeros[i] = (~rhs).nonZeros(i);
2397  sum += nonzeros[i];
2398  }
2399 
2400  matrix_.reserve( sum );
2401  for( size_t i=0UL; i<rows(); ++i ) {
2402  matrix_.reserve( i, nonzeros[i] );
2403  }
2404 
2405  for( size_t i=0UL; i<rows(); ++i ) {
2406  for( size_t j=i; j<columns(); ++j ) {
2407  if( !isDefault( (~rhs)(i,j) ) ) {
2408  const SharedValue<ET> shared( (~rhs)(i,j) );
2409  matrix_.append( i, j, shared, false );
2410  if( i != j )
2411  matrix_.append( j, i, shared, false );
2412  }
2413  }
2414  }
2415 }
2417 //*************************************************************************************************
2418 
2419 
2420 //*************************************************************************************************
2432 template< typename MT // Type of the adapted sparse matrix
2433  , bool SO > // Storage order of the adapted sparse matrix
2434 template< typename MT2 > // Type of the right-hand side sparse matrix
2435 void SymmetricMatrix<MT,SO,false,false>::assign( SparseMatrix<MT2,SO>& rhs )
2436 {
2438 
2439  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2440  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2441 
2442  std::vector<size_t> nonzeros( rows(), 0UL );
2443  size_t sum( 0UL );
2444 
2445  for( size_t i=0UL; i<rows(); ++i ) {
2446  nonzeros[i] = (~rhs).nonZeros(i);
2447  sum += nonzeros[i];
2448  }
2449 
2450  matrix_.reserve( sum );
2451  for( size_t i=0UL; i<rows(); ++i ) {
2452  matrix_.reserve( i, nonzeros[i] );
2453  }
2454 
2455  for( size_t i=0UL; i<rows(); ++i ) {
2456  for( typename MT2::Iterator it=(~rhs).lowerBound(i,i); it!=(~rhs).end(i); ++it ) {
2457  if( !isDefault( it->value() ) ) {
2458  SharedValue<ET> shared;
2459  move( *shared, it->value() );
2460  matrix_.append( i, it->index(), shared, false );
2461  if( i != it->index() )
2462  matrix_.append( it->index(), i, shared, false );
2463  }
2464  }
2465  }
2466 }
2468 //*************************************************************************************************
2469 
2470 
2471 //*************************************************************************************************
2483 template< typename MT // Type of the adapted sparse matrix
2484  , bool SO > // Storage order of the adapted sparse matrix
2485 template< typename MT2 > // Type of the right-hand side sparse matrix
2486 void SymmetricMatrix<MT,SO,false,false>::assign( const SparseMatrix<MT2,SO>& rhs )
2487 {
2489 
2490  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2491  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2492 
2493  std::vector<size_t> nonzeros( rows(), 0UL );
2494  size_t sum( 0UL );
2495 
2496  for( size_t i=0UL; i<rows(); ++i ) {
2497  nonzeros[i] = (~rhs).nonZeros(i);
2498  sum += nonzeros[i];
2499  }
2500 
2501  matrix_.reserve( sum );
2502  for( size_t i=0UL; i<rows(); ++i ) {
2503  matrix_.reserve( i, nonzeros[i] );
2504  }
2505 
2506  for( size_t i=0UL; i<rows(); ++i ) {
2507  for( typename MT2::ConstIterator it=(~rhs).lowerBound(i,i); it!=(~rhs).end(i); ++it ) {
2508  if( !isDefault( it->value() ) ) {
2509  const SharedValue<ET> shared( it->value() );
2510  matrix_.append( i, it->index(), shared, false );
2511  if( i != it->index() )
2512  matrix_.append( it->index(), i, shared, false );
2513  }
2514  }
2515  }
2516 }
2518 //*************************************************************************************************
2519 
2520 } // namespace blaze
2521 
2522 #endif
BLAZE_ALWAYS_INLINE int16_t sum(const sse_int16_t &a)
Returns the sum of all elements in the 16-bit integral intrinsic vector.
Definition: Reduction.h:63
#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
Constraint on the data type.
Constraint on the data type.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, 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 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:8247
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:902
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:237
void move(CompressedMatrix< Type, SO > &dst, CompressedMatrix< Type, SO > &src)
Moving the contents of one compressed matrix to another.
Definition: CompressedMatrix.h:4825
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:300
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:258
#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:242
#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:692
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:821
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2507
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:348
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
void clear(CompressedMatrix< Type, SO > &m)
Clearing the given compressed matrix.
Definition: CompressedMatrix.h:4762
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2501
#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:386
Constraint on the data type.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:2503
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:861
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:4789
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:4807
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2511
#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
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
Constraint on the data type.
Header file for the SparseElement base class.
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2504
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:195
#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:535
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2505
Header file for the RemoveAdaptor type trait.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2509
Header file for the EnableIf class template.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:841
Header file for the NonNumericProxy class.
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:2506
Header file for run time assertion macros.
Header file for the addition trait.
Constraint on the data type.
Constraint on the data type.
const DenseIterator< Type > operator-(const DenseIterator< Type > &it, ptrdiff_t inc)
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:585
#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:2510
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:200
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, sse_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
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:937
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:2502
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2508
#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
Header file for the IsResizable type trait.
#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