All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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>
73 #include <blaze/util/Assert.h>
79 #include <blaze/util/EnableIf.h>
80 #include <blaze/util/mpl/If.h>
83 #include <blaze/util/Types.h>
84 #include <blaze/util/Unused.h>
85 
86 
87 namespace blaze {
88 
89 //=================================================================================================
90 //
91 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES WITH NON-NUMERIC ELEMENT TYPE
92 //
93 //=================================================================================================
94 
95 //*************************************************************************************************
103 template< typename MT // Type of the adapted sparse matrix
104  , bool SO > // Storage order of the adapted sparse matrix
105 class SymmetricMatrix<MT,SO,false,false>
106  : public SparseMatrix< SymmetricMatrix<MT,SO,false,false>, SO >
107 {
108  private:
109  //**Type definitions****************************************************************************
110  typedef typename MT::OppositeType OT;
111  typedef typename MT::TransposeType TT;
112  typedef typename MT::ElementType ET;
113 
115  typedef typename MT::template Rebind< SharedValue<ET> >::Other MatrixType;
116  //**********************************************************************************************
117 
118  public:
119  //**Type definitions****************************************************************************
120  typedef SymmetricMatrix<MT,SO,false,false> This;
121  typedef This ResultType;
122  typedef SymmetricMatrix<OT,!SO,false,false> OppositeType;
123  typedef SymmetricMatrix<TT,!SO,false,false> TransposeType;
124  typedef ET ElementType;
125  typedef typename MT::ReturnType ReturnType;
126  typedef const This& CompositeType;
127  typedef NonNumericProxy<MatrixType> Reference;
128  typedef typename MT::ConstReference ConstReference;
129  //**********************************************************************************************
130 
131  //**Rebind struct definition********************************************************************
134  template< typename ET > // Data type of the other matrix
135  struct Rebind {
137  typedef SymmetricMatrix< typename MT::template Rebind<ET>::Other > Other;
138  };
139  //**********************************************************************************************
140 
141  //**SharedElement class definition**************************************************************
144  template< typename IteratorType > // Type of the sparse matrix iterator
145  class SharedElement : private SparseElement
146  {
147  public:
148  //**Type definitions*************************************************************************
149  typedef ET ValueType;
150  typedef size_t IndexType;
151  typedef ValueType& Reference;
152  typedef const ValueType& ConstReference;
153  typedef SharedElement* Pointer;
154  typedef const SharedElement* ConstPointer;
155  //*******************************************************************************************
156 
157  //**Constructor******************************************************************************
162  inline SharedElement( IteratorType pos )
163  : pos_( pos ) // Iterator to the current sparse symmetric matrix element
164  {}
165  //*******************************************************************************************
166 
167  //**Assignment operator**********************************************************************
173  template< typename T > inline SharedElement& operator=( const T& v ) {
174  *pos_->value() = v;
175  return *this;
176  }
177  //*******************************************************************************************
178 
179  //**Addition assignment operator*************************************************************
185  template< typename T > inline SharedElement& operator+=( const T& v ) {
186  *pos_->value() += v;
187  return *this;
188  }
189  //*******************************************************************************************
190 
191  //**Subtraction assignment operator**********************************************************
197  template< typename T > inline SharedElement& operator-=( const T& v ) {
198  *pos_->value() -= v;
199  return *this;
200  }
201  //*******************************************************************************************
202 
203  //**Multiplication assignment operator*******************************************************
209  template< typename T > inline SharedElement& operator*=( const T& v ) {
210  *pos_->value() *= v;
211  return *this;
212  }
213  //*******************************************************************************************
214 
215  //**Division assignment operator*************************************************************
221  template< typename T > inline SharedElement& operator/=( const T& v ) {
222  *pos_->value() /= v;
223  return *this;
224  }
225  //*******************************************************************************************
226 
227  //**Element access operator******************************************************************
232  inline Pointer operator->() {
233  return this;
234  }
235  //*******************************************************************************************
236 
237  //**Element access operator******************************************************************
242  inline ConstPointer operator->() const {
243  return this;
244  }
245  //*******************************************************************************************
246 
247  //**Value function***************************************************************************
252  inline Reference value() {
253  return *pos_->value();
254  }
255  //*******************************************************************************************
256 
257  //**Value function***************************************************************************
262  inline ConstReference value() const {
263  return *pos_->value();
264  }
265  //*******************************************************************************************
266 
267  //**Index function***************************************************************************
272  inline IndexType index() const {
273  return pos_->index();
274  }
275  //*******************************************************************************************
276 
277  private:
278  //**Member variables*************************************************************************
279  IteratorType pos_;
280  //*******************************************************************************************
281  };
282  //**********************************************************************************************
283 
284  //**SharedIterator class definition*************************************************************
287  template< typename SparseElementType // Type of the underlying sparse elements.
288  , typename IteratorType > // Type of the sparse matrix iterator
289  class SharedIterator
290  {
291  public:
292  //**Type definitions*************************************************************************
293  typedef std::forward_iterator_tag IteratorCategory;
294  typedef SparseElementType ValueType;
295  typedef SparseElementType PointerType;
296  typedef SparseElementType ReferenceType;
297  typedef ptrdiff_t DifferenceType;
298 
299  // STL iterator requirements
300  typedef IteratorCategory iterator_category;
301  typedef ValueType value_type;
302  typedef PointerType pointer;
303  typedef ReferenceType reference;
304  typedef DifferenceType difference_type;
305  //*******************************************************************************************
306 
307  //**Default constructor**********************************************************************
310  inline SharedIterator()
311  : pos_() // Iterator to the current sparse symmetric matrix element
312  {}
313  //*******************************************************************************************
314 
315  //**Constructor******************************************************************************
320  inline SharedIterator( IteratorType pos )
321  : pos_( pos ) // Iterator to the current sparse symmetric matrix element
322  {}
323  //*******************************************************************************************
324 
325  //**Constructor******************************************************************************
330  template< typename SparseElementType2, typename IteratorType2 >
331  inline SharedIterator( const SharedIterator<SparseElementType2,IteratorType2>& it )
332  : pos_( it.pos_ ) // Iterator to the current sparse symmetric matrix element
333  {}
334  //*******************************************************************************************
335 
336  //**Prefix increment operator****************************************************************
341  inline SharedIterator& operator++() {
342  ++pos_;
343  return *this;
344  }
345  //*******************************************************************************************
346 
347  //**Postfix increment operator***************************************************************
352  inline const SharedIterator operator++( int ) {
353  const SharedIterator tmp( *this );
354  ++(*this);
355  return tmp;
356  }
357  //*******************************************************************************************
358 
359  //**Element access operator******************************************************************
364  inline ReferenceType operator*() const {
365  return ReferenceType( pos_ );
366  }
367  //*******************************************************************************************
368 
369  //**Element access operator******************************************************************
374  inline PointerType operator->() const {
375  return PointerType( pos_ );
376  }
377  //*******************************************************************************************
378 
379  //**Equality operator************************************************************************
385  inline bool operator==( const SharedIterator& rhs ) const {
386  return pos_ == rhs.pos_;
387  }
388  //*******************************************************************************************
389 
390  //**Inequality operator**********************************************************************
396  inline bool operator!=( const SharedIterator& rhs ) const {
397  return !( *this == rhs );
398  }
399  //*******************************************************************************************
400 
401  //**Subtraction operator*********************************************************************
407  inline DifferenceType operator-( const SharedIterator& rhs ) const {
408  return pos_ - rhs.pos_;
409  }
410  //*******************************************************************************************
411 
412  //**Base function****************************************************************************
417  inline IteratorType base() const {
418  return pos_;
419  }
420  //*******************************************************************************************
421 
422  private:
423  //**Member variables*************************************************************************
424  IteratorType pos_;
425  //*******************************************************************************************
426 
427  //**Friend declarations**********************************************************************
428  template< typename SparseElementType2, typename IteratorType2 > friend class SharedIterator;
429  //*******************************************************************************************
430  };
431  //**********************************************************************************************
432 
433  //**Type definitions****************************************************************************
435  typedef SharedIterator< SharedElement< typename MatrixType::Iterator >
436  , typename MatrixType::Iterator
437  > Iterator;
438 
440  typedef SharedIterator< const SharedElement< typename MatrixType::ConstIterator >
441  , typename MatrixType::ConstIterator
442  > ConstIterator;
443  //**********************************************************************************************
444 
445  //**Compilation flags***************************************************************************
447  enum { smpAssignable = 0 };
448  //**********************************************************************************************
449 
450  //**Constructors********************************************************************************
453  explicit inline SymmetricMatrix();
454  explicit inline SymmetricMatrix( size_t n );
455  explicit inline SymmetricMatrix( size_t n, size_t nonzeros );
456  explicit inline SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros );
457 
458  inline SymmetricMatrix( const SymmetricMatrix& m );
459  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
460  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
462  //**********************************************************************************************
463 
464  //**Destructor**********************************************************************************
465  // No explicitly declared destructor.
466  //**********************************************************************************************
467 
468  //**Data access functions***********************************************************************
471  inline Reference operator()( size_t i, size_t j );
472  inline ConstReference operator()( size_t i, size_t j ) const;
473  inline Iterator begin ( size_t i );
474  inline ConstIterator begin ( size_t i ) const;
475  inline ConstIterator cbegin( size_t i ) const;
476  inline Iterator end ( size_t i );
477  inline ConstIterator end ( size_t i ) const;
478  inline ConstIterator cend ( size_t i ) const;
480  //**********************************************************************************************
481 
482  //**Assignment operators************************************************************************
485  inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
486 
487  template< typename MT2 >
488  inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
489  operator=( const Matrix<MT2,SO>& rhs );
490 
491  template< typename MT2 >
492  inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
493  operator=( const Matrix<MT2,SO>& rhs );
494 
495  template< typename MT2 >
496  inline SymmetricMatrix& operator=( const Matrix<MT2,!SO>& rhs );
497 
498  template< typename MT2 >
499  inline SymmetricMatrix& operator+=( const Matrix<MT2,SO>& rhs );
500 
501  template< typename MT2 >
502  inline SymmetricMatrix& operator+=( const Matrix<MT2,!SO>& rhs );
503 
504  template< typename MT2 >
505  inline SymmetricMatrix& operator-=( const Matrix<MT2,SO>& rhs );
506 
507  template< typename MT2 >
508  inline SymmetricMatrix& operator-=( const Matrix<MT2,!SO>& rhs );
509 
510  template< typename MT2, bool SO2 >
511  inline SymmetricMatrix& operator*=( const Matrix<MT2,SO2>& rhs );
512 
513  template< typename Other >
514  inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix >::Type&
515  operator*=( Other rhs );
516 
517  template< typename Other >
518  inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix >::Type&
519  operator/=( Other rhs );
521  //**********************************************************************************************
522 
523  //**Utility functions***************************************************************************
526  inline size_t rows() const;
527  inline size_t columns() const;
528  inline size_t capacity() const;
529  inline size_t capacity( size_t i ) const;
530  inline size_t nonZeros() const;
531  inline size_t nonZeros( size_t i ) const;
532  inline void reset();
533  inline void reset( size_t i );
534  inline void clear();
535  inline Iterator set( size_t i, size_t j, const ElementType& value );
536  inline Iterator insert( size_t i, size_t j, const ElementType& value );
537  inline void erase( size_t i, size_t j );
538  inline Iterator erase( size_t i, Iterator pos );
539  inline Iterator erase( size_t i, Iterator first, Iterator last );
540  inline void resize ( size_t n, bool preserve=true );
541  inline void reserve( size_t nonzeros );
542  inline void reserve( size_t i, size_t nonzeros );
543  inline void trim();
544  inline void trim( size_t i );
545  inline SymmetricMatrix& transpose();
546  template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
547  template< typename Other > inline SymmetricMatrix& scaleDiagonal( Other scale );
548  inline void swap( SymmetricMatrix& m ) /* throw() */;
550  //**********************************************************************************************
551 
552  //**Lookup functions****************************************************************************
555  inline Iterator find ( size_t i, size_t j );
556  inline ConstIterator find ( size_t i, size_t j ) const;
557  inline Iterator lowerBound( size_t i, size_t j );
558  inline ConstIterator lowerBound( size_t i, size_t j ) const;
559  inline Iterator upperBound( size_t i, size_t j );
560  inline ConstIterator upperBound( size_t i, size_t j ) const;
562  //**********************************************************************************************
563 
564  //**Low-level utility functions*****************************************************************
567  inline void append ( size_t i, size_t j, const ElementType& value, bool check=false );
568  inline void finalize( size_t i );
570  //**********************************************************************************************
571 
572  public:
573  //**Expression template evaluation functions****************************************************
576  template< typename Other > inline bool canAlias ( const Other* alias ) const;
577  template< typename Other > inline bool isAliased( const Other* alias ) const;
578 
579  inline bool canSMPAssign() const;
581  //**********************************************************************************************
582 
583  private:
584  //**Expression template evaluation functions****************************************************
587  template< typename MT2 > void assign( DenseMatrix<MT2,SO>& rhs );
588  template< typename MT2 > void assign( const DenseMatrix<MT2,SO>& rhs );
589  template< typename MT2 > void assign( SparseMatrix<MT2,SO>& rhs );
590  template< typename MT2 > void assign( const SparseMatrix<MT2,SO>& rhs );
592  //**********************************************************************************************
593 
594  //**Member variables****************************************************************************
597  MatrixType matrix_;
598 
599  //**********************************************************************************************
600 
601  //**Friend declarations*************************************************************************
602  template< typename MT2, bool SO2, bool DF2, bool NF2 >
603  friend bool isDefault( const SymmetricMatrix<MT2,SO2,DF2,NF2>& m );
604  //**********************************************************************************************
605 
606  //**Compile time checks*************************************************************************
619  BLAZE_STATIC_ASSERT( IsResizable<MT>::value || IsSquare<MT>::value );
620  //**********************************************************************************************
621 };
623 //*************************************************************************************************
624 
625 
626 
627 
628 //=================================================================================================
629 //
630 // CONSTRUCTORS
631 //
632 //=================================================================================================
633 
634 //*************************************************************************************************
638 template< typename MT // Type of the adapted sparse matrix
639  , bool SO > // Storage order of the adapted sparse matrix
640 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix()
641  : matrix_() // The adapted sparse matrix
642 {
643  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
644 }
646 //*************************************************************************************************
647 
648 
649 //*************************************************************************************************
657 template< typename MT // Type of the adapted sparse matrix
658  , bool SO > // Storage order of the adapted sparse matrix
659 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n )
660  : matrix_( n, n ) // The adapted sparse matrix
661 {
663 
664  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
665 }
667 //*************************************************************************************************
668 
669 
670 //*************************************************************************************************
679 template< typename MT // Type of the adapted sparse matrix
680  , bool SO > // Storage order of the adapted sparse matrix
681 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n, size_t nonzeros )
682  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
683 {
685 
686  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
687 }
689 //*************************************************************************************************
690 
691 
692 //*************************************************************************************************
701 template< typename MT // Type of the adapted sparse matrix
702  , bool SO > // Storage order of the adapted sparse matrix
703 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( size_t n, const std::vector<size_t>& nonzeros )
704  : matrix_( n, n, nonzeros ) // The adapted sparse matrix
705 {
707 
708  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
709 }
711 //*************************************************************************************************
712 
713 
714 //*************************************************************************************************
720 template< typename MT // Type of the adapted sparse matrix
721  , bool SO > // Storage order of the adapted sparse matrix
722 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const SymmetricMatrix& m )
723  : matrix_() // The adapted sparse matrix
724 {
725  using blaze::resize;
726 
727  resize( matrix_, m.rows(), m.columns() );
728  assign( m );
729 
730  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
731 }
733 //*************************************************************************************************
734 
735 
736 //*************************************************************************************************
746 template< typename MT // Type of the adapted sparse matrix
747  , bool SO > // Storage order of the adapted sparse matrix
748 template< typename MT2 > // Type of the foreign matrix
749 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const Matrix<MT2,SO>& m )
750  : matrix_() // The adapted sparse matrix
751 {
752  using blaze::resize;
753 
754  typedef typename RemoveAdaptor<typename MT2::ResultType>::Type RT;
755  typedef typename If< IsComputation<MT2>, RT, const MT2& >::Type Tmp;
756 
757  if( IsLower<MT2>::value || IsUpper<MT2>::value )
758  throw std::invalid_argument( "Invalid setup of symmetric matrix" );
759 
760  Tmp tmp( ~m );
761 
762  if( !IsSymmetric<MT2>::value && !isSymmetric( tmp ) )
763  throw std::invalid_argument( "Invalid setup of symmetric matrix" );
764 
765  resize( matrix_, tmp.rows(), tmp.columns() );
766  assign( tmp );
767 
768  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
769 }
771 //*************************************************************************************************
772 
773 
774 //*************************************************************************************************
784 template< typename MT // Type of the adapted sparse matrix
785  , bool SO > // Storage order of the adapted sparse matrix
786 template< typename MT2 > // Type of the foreign matrix
787 inline SymmetricMatrix<MT,SO,false,false>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
788  : matrix_() // The adapted sparse matrix
789 {
790  using blaze::resize;
791 
792  typedef typename RemoveAdaptor<typename MT2::ResultType>::Type RT;
793  typedef typename If< IsComputation<MT2>, RT, const MT2& >::Type Tmp;
794 
795  if( IsLower<MT2>::value || IsUpper<MT2>::value )
796  throw std::invalid_argument( "Invalid setup of symmetric matrix" );
797 
798  Tmp tmp( ~m );
799 
800  if( !IsSymmetric<MT2>::value && !isSymmetric( tmp ) )
801  throw std::invalid_argument( "Invalid setup of symmetric matrix" );
802 
803  resize( matrix_, tmp.rows(), tmp.columns() );
804  assign( trans( tmp ) );
805 
806  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
807 }
809 //*************************************************************************************************
810 
811 
812 
813 
814 //=================================================================================================
815 //
816 // DATA ACCESS FUNCTIONS
817 //
818 //=================================================================================================
819 
820 //*************************************************************************************************
832 template< typename MT // Type of the adapted sparse matrix
833  , bool SO > // Storage order of the adapted sparse matrix
835  SymmetricMatrix<MT,SO,false,false>::operator()( size_t i, size_t j )
836 {
837  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
838  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
839 
840  return Reference( matrix_, i, j );
841 }
843 //*************************************************************************************************
844 
845 
846 //*************************************************************************************************
858 template< typename MT // Type of the adapted sparse matrix
859  , bool SO > // Storage order of the adapted sparse matrix
861  SymmetricMatrix<MT,SO,false,false>::operator()( size_t i, size_t j ) const
862 {
863  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
864  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
865 
866  return *matrix_(i,j);
867 }
869 //*************************************************************************************************
870 
871 
872 //*************************************************************************************************
884 template< typename MT // Type of the adapted sparse matrix
885  , bool SO > // Storage order of the adapted sparse matrix
888 {
889  return Iterator( matrix_.begin(i) );
890 }
892 //*************************************************************************************************
893 
894 
895 //*************************************************************************************************
907 template< typename MT // Type of the adapted sparse matrix
908  , bool SO > // Storage order of the adapted sparse matrix
911 {
912  return ConstIterator( matrix_.begin(i) );
913 }
915 //*************************************************************************************************
916 
917 
918 //*************************************************************************************************
930 template< typename MT // Type of the adapted sparse matrix
931  , bool SO > // Storage order of the adapted sparse matrix
934 {
935  return ConstIterator( matrix_.cbegin(i) );
936 }
938 //*************************************************************************************************
939 
940 
941 //*************************************************************************************************
953 template< typename MT // Type of the adapted sparse matrix
954  , bool SO > // Storage order of the adapted sparse matrix
957 {
958  return Iterator( matrix_.end(i) );
959 }
961 //*************************************************************************************************
962 
963 
964 //*************************************************************************************************
976 template< typename MT // Type of the adapted sparse matrix
977  , bool SO > // Storage order of the adapted sparse matrix
980 {
981  return ConstIterator( matrix_.end(i) );
982 }
984 //*************************************************************************************************
985 
986 
987 //*************************************************************************************************
999 template< typename MT // Type of the adapted sparse matrix
1000  , bool SO > // Storage order of the adapted sparse matrix
1003 {
1004  return ConstIterator( matrix_.cend(i) );
1005 }
1007 //*************************************************************************************************
1008 
1009 
1010 
1011 
1012 //=================================================================================================
1013 //
1014 // ASSIGNMENT OPERATORS
1015 //
1016 //=================================================================================================
1017 
1018 //*************************************************************************************************
1028 template< typename MT // Type of the adapted sparse matrix
1029  , bool SO > // Storage order of the adapted sparse matrix
1030 inline SymmetricMatrix<MT,SO,false,false>&
1031  SymmetricMatrix<MT,SO,false,false>::operator=( const SymmetricMatrix& rhs )
1032 {
1033  using blaze::resize;
1034 
1035  if( &rhs == this ) return *this;
1036 
1037  resize( matrix_, rhs.rows(), rhs.columns() );
1038  reset();
1039  assign( rhs );
1040 
1041  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1042 
1043  return *this;
1044 }
1046 //*************************************************************************************************
1047 
1048 
1049 //*************************************************************************************************
1063 template< typename MT // Type of the adapted sparse matrix
1064  , bool SO > // Storage order of the adapted sparse matrix
1065 template< typename MT2 > // Type of the right-hand side matrix
1066 inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,false>& >::Type
1067  SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1068 {
1069  using blaze::resize;
1070 
1071  if( IsLower<MT2>::value || IsUpper<MT2>::value ||
1072  ( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) ) )
1073  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1074 
1075  if( (~rhs).canAlias( this ) ) {
1076  SymmetricMatrix tmp( ~rhs );
1077  swap( tmp );
1078  }
1079  else {
1080  resize( matrix_, (~rhs).rows(), (~rhs).columns() );
1081  reset();
1082  assign( ~rhs );
1083  }
1084 
1085  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1086 
1087  return *this;
1088 }
1090 //*************************************************************************************************
1091 
1092 
1093 //*************************************************************************************************
1107 template< typename MT // Type of the adapted sparse matrix
1108  , bool SO > // Storage order of the adapted sparse matrix
1109 template< typename MT2 > // Type of the right-hand side matrix
1110 inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,false,false>& >::Type
1111  SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,SO>& rhs )
1112 {
1113  using blaze::resize;
1114 
1115  if( IsLower<MT2>::value || IsUpper<MT2>::value || !isSquare( ~rhs ) )
1116  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1117 
1118  typename MT2::ResultType tmp( ~rhs );
1119 
1120  if( !IsSymmetric<MT2>::value && !isSymmetric( tmp ) )
1121  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1122 
1123  resize( matrix_, tmp.rows(), tmp.columns() );
1124  reset();
1125  assign( tmp );
1126 
1127  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix 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 SymmetricMatrix<MT,SO,false,false>&
1153  SymmetricMatrix<MT,SO,false,false>::operator=( const Matrix<MT2,!SO>& rhs )
1154 {
1155  return this->operator=( trans( ~rhs ) );
1156 }
1158 //*************************************************************************************************
1159 
1160 
1161 //*************************************************************************************************
1174 template< typename MT // Type of the adapted sparse matrix
1175  , bool SO > // Storage order of the adapted sparse matrix
1176 template< typename MT2 > // Type of the right-hand side matrix
1177 inline SymmetricMatrix<MT,SO,false,false>&
1178  SymmetricMatrix<MT,SO,false,false>::operator+=( const Matrix<MT2,SO>& rhs )
1179 {
1180  using blaze::resize;
1181 
1182  typedef typename AddTrait<MT,typename MT2::ResultType>::Type Tmp;
1183 
1184  if( IsLower<MT2>::value || IsUpper<MT2>::value || !isSquare( ~rhs ) )
1185  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1186 
1187  Tmp tmp( (*this) + ~rhs );
1188 
1189  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) )
1190  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1191 
1192  resize( matrix_, tmp.rows(), tmp.columns() );
1193  reset();
1194  assign( tmp );
1195 
1196  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1197 
1198  return *this;
1199 }
1201 //*************************************************************************************************
1202 
1203 
1204 //*************************************************************************************************
1218 template< typename MT // Type of the adapted sparse matrix
1219  , bool SO > // Storage order of the adapted sparse matrix
1220 template< typename MT2 > // Type of the right-hand side matrix
1221 inline SymmetricMatrix<MT,SO,false,false>&
1222  SymmetricMatrix<MT,SO,false,false>::operator+=( const Matrix<MT2,!SO>& rhs )
1223 {
1224  return this->operator+=( trans( ~rhs ) );
1225 }
1227 //*************************************************************************************************
1228 
1229 
1230 //*************************************************************************************************
1243 template< typename MT // Type of the adapted sparse matrix
1244  , bool SO > // Storage order of the adapted sparse matrix
1245 template< typename MT2 > // Type of the right-hand side matrix
1246 inline SymmetricMatrix<MT,SO,false,false>&
1247  SymmetricMatrix<MT,SO,false,false>::operator-=( const Matrix<MT2,SO>& rhs )
1248 {
1249  using blaze::resize;
1250 
1251  typedef typename SubTrait<MT,typename MT2::ResultType>::Type Tmp;
1252 
1253  if( IsLower<MT2>::value || IsUpper<MT2>::value || !isSquare( ~rhs ) )
1254  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1255 
1256  Tmp tmp( (*this) - ~rhs );
1257 
1258  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) )
1259  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1260 
1261  resize( matrix_, tmp.rows(), tmp.columns() );
1262  reset();
1263  assign( tmp );
1264 
1265  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1266 
1267  return *this;
1268 }
1270 //*************************************************************************************************
1271 
1272 
1273 //*************************************************************************************************
1287 template< typename MT // Type of the adapted sparse matrix
1288  , bool SO > // Storage order of the adapted sparse matrix
1289 template< typename MT2 > // Type of the right-hand side matrix
1290 inline SymmetricMatrix<MT,SO,false,false>&
1291  SymmetricMatrix<MT,SO,false,false>::operator-=( const Matrix<MT2,!SO>& rhs )
1292 {
1293  return this->operator-=( trans( ~rhs ) );
1294 }
1296 //*************************************************************************************************
1297 
1298 
1299 //*************************************************************************************************
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  , bool SO2 > // Storage order of the right-hand side matrix
1315 inline SymmetricMatrix<MT,SO,false,false>&
1316  SymmetricMatrix<MT,SO,false,false>::operator*=( const Matrix<MT2,SO2>& rhs )
1317 {
1318  using blaze::resize;
1319 
1320  typedef typename MultTrait<MT,typename MT2::ResultType>::Type Tmp;
1321 
1322  if( matrix_.rows() != (~rhs).columns() )
1323  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1324 
1325  Tmp tmp( (*this) * ~rhs );
1326 
1327  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) )
1328  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1329 
1330  resize( matrix_, tmp.rows(), tmp.columns() );
1331  reset();
1332  assign( tmp );
1333 
1334  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1335 
1336  return *this;
1337 }
1339 //*************************************************************************************************
1340 
1341 
1342 //*************************************************************************************************
1350 template< typename MT // Type of the adapted sparse matrix
1351  , bool SO > // Storage order of the adapted sparse matrix
1352 template< typename Other > // Data type of the right-hand side scalar
1353 inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,false> >::Type&
1354  SymmetricMatrix<MT,SO,false,false>::operator*=( Other rhs )
1355 {
1356  for( size_t i=0UL; i<rows(); ++i ) {
1357  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
1358  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
1359  *element->value() *= rhs;
1360  }
1361 
1362  return *this;
1363 }
1365 //*************************************************************************************************
1366 
1367 
1368 //*************************************************************************************************
1376 template< typename MT // Type of the adapted sparse matrix
1377  , bool SO > // Storage order of the adapted sparse matrix
1378 template< typename Other > // Data type of the right-hand side scalar
1379 inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix<MT,SO,false,false> >::Type&
1380  SymmetricMatrix<MT,SO,false,false>::operator/=( Other rhs )
1381 {
1382  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1383 
1384  for( size_t i=0UL; i<rows(); ++i ) {
1385  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
1386  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
1387  *element->value() /= rhs;
1388  }
1389 
1390  return *this;
1391 }
1393 //*************************************************************************************************
1394 
1395 
1396 
1397 
1398 //=================================================================================================
1399 //
1400 // UTILITY FUNCTIONS
1401 //
1402 //=================================================================================================
1403 
1404 //*************************************************************************************************
1410 template< typename MT // Type of the adapted sparse matrix
1411  , bool SO > // Storage order of the adapted sparse matrix
1412 inline size_t SymmetricMatrix<MT,SO,false,false>::rows() const
1413 {
1414  return matrix_.rows();
1415 }
1417 //*************************************************************************************************
1418 
1419 
1420 //*************************************************************************************************
1426 template< typename MT // Type of the adapted sparse matrix
1427  , bool SO > // Storage order of the adapted sparse matrix
1428 inline size_t SymmetricMatrix<MT,SO,false,false>::columns() const
1429 {
1430  return matrix_.columns();
1431 }
1433 //*************************************************************************************************
1434 
1435 
1436 //*************************************************************************************************
1442 template< typename MT // Type of the adapted sparse matrix
1443  , bool SO > // Storage order of the adapted sparse matrix
1445 {
1446  return matrix_.capacity();
1447 }
1449 //*************************************************************************************************
1450 
1451 
1452 //*************************************************************************************************
1463 template< typename MT // Type of the adapted sparse matrix
1464  , bool SO > // Storage order of the adapted sparse matrix
1465 inline size_t SymmetricMatrix<MT,SO,false,false>::capacity( size_t i ) const
1466 {
1467  return matrix_.capacity(i);
1468 }
1470 //*************************************************************************************************
1471 
1472 
1473 //*************************************************************************************************
1479 template< typename MT // Type of the adapted sparse matrix
1480  , bool SO > // Storage order of the adapted sparse matrix
1482 {
1483  return matrix_.nonZeros();
1484 }
1486 //*************************************************************************************************
1487 
1488 
1489 //*************************************************************************************************
1501 template< typename MT // Type of the adapted sparse matrix
1502  , bool SO > // Storage order of the adapted sparse matrix
1503 inline size_t SymmetricMatrix<MT,SO,false,false>::nonZeros( size_t i ) const
1504 {
1505  return matrix_.nonZeros(i);
1506 }
1508 //*************************************************************************************************
1509 
1510 
1511 //*************************************************************************************************
1517 template< typename MT // Type of the adapted sparse matrix
1518  , bool SO > // Storage order of the adapted sparse matrix
1520 {
1521  matrix_.reset();
1522 }
1524 //*************************************************************************************************
1525 
1526 
1527 //*************************************************************************************************
1567 template< typename MT // Type of the adapted sparse matrix
1568  , bool SO > // Storage order of the adapted sparse matrix
1569 inline void SymmetricMatrix<MT,SO,false,false>::reset( size_t i )
1570 {
1571  for( typename MatrixType::Iterator it=matrix_.begin(i); it!=matrix_.end(i); ++it )
1572  {
1573  const size_t j( it->index() );
1574 
1575  if( i == j )
1576  continue;
1577 
1578  if( SO ) {
1579  const typename MatrixType::Iterator pos( matrix_.find( i, j ) );
1580  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1581  matrix_.erase( j, pos );
1582  }
1583  else {
1584  const typename MatrixType::Iterator pos( matrix_.find( j, i ) );
1585  BLAZE_INTERNAL_ASSERT( pos != matrix_.end( j ), "Missing element detected" );
1586  matrix_.erase( j, pos );
1587  }
1588  }
1589 
1590  matrix_.reset( i );
1591 }
1593 //*************************************************************************************************
1594 
1595 
1596 //*************************************************************************************************
1604 template< typename MT // Type of the adapted sparse matrix
1605  , bool SO > // Storage order of the adapted sparse matrix
1607 {
1608  using blaze::clear;
1609 
1610  clear( matrix_ );
1611 }
1613 //*************************************************************************************************
1614 
1615 
1616 //*************************************************************************************************
1630 template< typename MT // Type of the adapted sparse matrix
1631  , bool SO > // Storage order of the adapted sparse matrix
1633  SymmetricMatrix<MT,SO,false,false>::set( size_t i, size_t j, const ElementType& value )
1634 {
1635  SharedValue<ET> shared( value );
1636 
1637  if( i != j )
1638  matrix_.set( j, i, shared );
1639 
1640  return Iterator( matrix_.set( i, j, shared ) );
1641 }
1643 //*************************************************************************************************
1644 
1645 
1646 //*************************************************************************************************
1661 template< typename MT // Type of the adapted sparse matrix
1662  , bool SO > // Storage order of the adapted sparse matrix
1664  SymmetricMatrix<MT,SO,false,false>::insert( size_t i, size_t j, const ElementType& value )
1665 {
1666  SharedValue<ET> shared( value );
1667 
1668  if( i != j )
1669  matrix_.insert( j, i, shared );
1670 
1671  return Iterator( matrix_.insert( i, j, shared ) );
1672 }
1674 //*************************************************************************************************
1675 
1676 
1677 //*************************************************************************************************
1687 template< typename MT // Type of the adapted sparse matrix
1688  , bool SO > // Storage order of the adapted sparse matrix
1689 inline void SymmetricMatrix<MT,SO,false,false>::erase( size_t i, size_t j )
1690 {
1691  matrix_.erase( i, j );
1692  if( i != j )
1693  matrix_.erase( j, i );
1694 }
1696 //*************************************************************************************************
1697 
1698 
1699 //*************************************************************************************************
1711 template< typename MT // Type of the adapted sparse matrix
1712  , bool SO > // Storage order of the adapted sparse matrix
1714  SymmetricMatrix<MT,SO,false,false>::erase( size_t i, Iterator pos )
1715 {
1716  if( pos == end( i ) )
1717  return pos;
1718 
1719  const size_t j( pos->index() );
1720 
1721  if( i == j )
1722  return Iterator( matrix_.erase( i, pos.base() ) );
1723 
1724  if( SO ) {
1725  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1726  matrix_.erase( j, matrix_.find( i, j ) );
1727  return Iterator( matrix_.erase( i, pos.base() ) );
1728  }
1729  else {
1730  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1731  matrix_.erase( j, matrix_.find( j, i ) );
1732  return Iterator( matrix_.erase( i, pos.base() ) );
1733  }
1734 }
1736 //*************************************************************************************************
1737 
1738 
1739 //*************************************************************************************************
1753 template< typename MT // Type of the adapted sparse matrix
1754  , bool SO > // Storage order of the adapted sparse matrix
1756  SymmetricMatrix<MT,SO,false,false>::erase( size_t i, Iterator first, Iterator last )
1757 {
1758  for( Iterator it=first; it!=last; ++it )
1759  {
1760  const size_t j( it->index() );
1761 
1762  if( i == j )
1763  continue;
1764 
1765  if( SO ) {
1766  BLAZE_INTERNAL_ASSERT( matrix_.find( i, j ) != matrix_.end( j ), "Missing element detected" );
1767  matrix_.erase( i, j );
1768  }
1769  else {
1770  BLAZE_INTERNAL_ASSERT( matrix_.find( j, i ) != matrix_.end( j ), "Missing element detected" );
1771  matrix_.erase( j, i );
1772  }
1773  }
1774 
1775  return Iterator( matrix_.erase( i, first.base(), last.base() ) );
1776 }
1778 //*************************************************************************************************
1779 
1780 
1781 //*************************************************************************************************
1796 template< typename MT // Type of the adapted sparse matrix
1797  , bool SO > // Storage order of the adapted sparse matrix
1798 void SymmetricMatrix<MT,SO,false,false>::resize( size_t n, bool preserve )
1799 {
1801 
1802  UNUSED_PARAMETER( preserve );
1803 
1804  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1805 
1806  matrix_.resize( n, n, true );
1807 }
1809 //*************************************************************************************************
1810 
1811 
1812 //*************************************************************************************************
1823 template< typename MT // Type of the adapted sparse matrix
1824  , bool SO > // Storage order of the adapted sparse matrix
1825 inline void SymmetricMatrix<MT,SO,false,false>::reserve( size_t nonzeros )
1826 {
1827  matrix_.reserve( nonzeros );
1828 }
1830 //*************************************************************************************************
1831 
1832 
1833 //*************************************************************************************************
1847 template< typename MT // Type of the adapted sparse matrix
1848  , bool SO > // Storage order of the adapted sparse matrix
1849 inline void SymmetricMatrix<MT,SO,false,false>::reserve( size_t i, size_t nonzeros )
1850 {
1851  matrix_.reserve( i, nonzeros );
1852 }
1854 //*************************************************************************************************
1855 
1856 
1857 //*************************************************************************************************
1868 template< typename MT // Type of the adapted sparse matrix
1869  , bool SO > // Storage order of the adapted sparse matrix
1870 inline void SymmetricMatrix<MT,SO,false,false>::trim()
1871 {
1872  matrix_.trim();
1873 }
1875 //*************************************************************************************************
1876 
1877 
1878 //*************************************************************************************************
1890 template< typename MT // Type of the adapted sparse matrix
1891  , bool SO > // Storage order of the adapted sparse matrix
1892 inline void SymmetricMatrix<MT,SO,false,false>::trim( size_t i )
1893 {
1894  matrix_.trim( i );
1895 }
1897 //*************************************************************************************************
1898 
1899 
1900 //*************************************************************************************************
1906 template< typename MT // Type of the adapted sparse matrix
1907  , bool SO > // Storage order of the adapted sparse matrix
1908 inline SymmetricMatrix<MT,SO,false,false>& SymmetricMatrix<MT,SO,false,false>::transpose()
1909 {
1910  return *this;
1911 }
1913 //*************************************************************************************************
1914 
1915 
1916 //*************************************************************************************************
1923 template< typename MT // Type of the adapted sparse matrix
1924  , bool SO > // Storage order of the adapted sparse matrix
1925 template< typename Other > // Data type of the scalar value
1926 inline SymmetricMatrix<MT,SO,false,false>&
1927  SymmetricMatrix<MT,SO,false,false>::scale( const Other& scalar )
1928 {
1929  for( size_t i=0UL; i<rows(); ++i ) {
1930  const typename MatrixType::Iterator last( matrix_.upperBound(i,i) );
1931  for( typename MatrixType::Iterator element=matrix_.begin(i); element!=last; ++element )
1932  ( *element->value() ).scale( scalar );
1933  }
1934 
1935  return *this;
1936 }
1938 //*************************************************************************************************
1939 
1940 
1941 //*************************************************************************************************
1948 template< typename MT // Type of the adapted sparse matrix
1949  , bool SO > // Storage order of the adapted sparse matrix
1950 template< typename Other > // Data type of the scalar value
1951 inline SymmetricMatrix<MT,SO,false,false>&
1952  SymmetricMatrix<MT,SO,false,false>::scaleDiagonal( Other scalar )
1953 {
1954  matrix_.scaleDiagonal( scalar );
1955  return *this;
1956 }
1958 //*************************************************************************************************
1959 
1960 
1961 //*************************************************************************************************
1969 template< typename MT // Type of the adapted sparse matrix
1970  , bool SO > // Storage order of the adapted sparse matrix
1971 inline void SymmetricMatrix<MT,SO,false,false>::swap( SymmetricMatrix& m ) /* throw() */
1972 {
1973  using std::swap;
1974 
1975  swap( matrix_, m.matrix_ );
1976 }
1978 //*************************************************************************************************
1979 
1980 
1981 
1982 
1983 //=================================================================================================
1984 //
1985 // LOOKUP FUNCTIONS
1986 //
1987 //=================================================================================================
1988 
1989 //*************************************************************************************************
2005 template< typename MT // Type of the adapted sparse matrix
2006  , bool SO > // Storage order of the adapted sparse matrix
2008  SymmetricMatrix<MT,SO,false,false>::find( size_t i, size_t j )
2009 {
2010  return Iterator( matrix_.find( i, j ) );
2011 }
2013 //*************************************************************************************************
2014 
2015 
2016 //*************************************************************************************************
2032 template< typename MT // Type of the adapted sparse matrix
2033  , bool SO > // Storage order of the adapted sparse matrix
2035  SymmetricMatrix<MT,SO,false,false>::find( size_t i, size_t j ) const
2036 {
2037  return ConstIterator( matrix_.find( i, j ) );
2038 }
2040 //*************************************************************************************************
2041 
2042 
2043 //*************************************************************************************************
2059 template< typename MT // Type of the adapted sparse matrix
2060  , bool SO > // Storage order of the adapted sparse matrix
2062  SymmetricMatrix<MT,SO,false,false>::lowerBound( size_t i, size_t j )
2063 {
2064  return Iterator( matrix_.lowerBound( i, j ) );
2065 }
2067 //*************************************************************************************************
2068 
2069 
2070 //*************************************************************************************************
2086 template< typename MT // Type of the adapted sparse matrix
2087  , bool SO > // Storage order of the adapted sparse matrix
2089  SymmetricMatrix<MT,SO,false,false>::lowerBound( size_t i, size_t j ) const
2090 {
2091  return ConstIterator( matrix_.lowerBound( i, j ) );
2092 }
2094 //*************************************************************************************************
2095 
2096 
2097 //*************************************************************************************************
2113 template< typename MT // Type of the adapted sparse matrix
2114  , bool SO > // Storage order of the adapted sparse matrix
2116  SymmetricMatrix<MT,SO,false,false>::upperBound( size_t i, size_t j )
2117 {
2118  return Iterator( matrix_.upperBound( i, j ) );
2119 }
2121 //*************************************************************************************************
2122 
2123 
2124 //*************************************************************************************************
2140 template< typename MT // Type of the adapted sparse matrix
2141  , bool SO > // Storage order of the adapted sparse matrix
2143  SymmetricMatrix<MT,SO,false,false>::upperBound( size_t i, size_t j ) const
2144 {
2145  return ConstIterator( matrix_.upperBound( i, j ) );
2146 }
2148 //*************************************************************************************************
2149 
2150 
2151 
2152 
2153 //=================================================================================================
2154 //
2155 // LOW-LEVEL UTILITY FUNCTIONS
2156 //
2157 //=================================================================================================
2158 
2159 //*************************************************************************************************
2214 template< typename MT // Type of the adapted sparse matrix
2215  , bool SO > // Storage order of the adapted sparse matrix
2216 inline void SymmetricMatrix<MT,SO,false,false>::append( size_t i, size_t j, const ElementType& value, bool check )
2217 {
2218  SharedValue<ET> shared( value );
2219 
2220  matrix_.append( i, j, shared, check );
2221  if( i != j && ( !check || !isDefault( value ) ) )
2222  matrix_.insert( j, i, shared );
2223 }
2225 //*************************************************************************************************
2226 
2227 
2228 //*************************************************************************************************
2242 template< typename MT // Type of the adapted sparse matrix
2243  , bool SO > // Storage order of the adapted sparse matrix
2244 inline void SymmetricMatrix<MT,SO,false,false>::finalize( size_t i )
2245 {
2246  matrix_.trim( i );
2247 }
2249 //*************************************************************************************************
2250 
2251 
2252 
2253 
2254 //=================================================================================================
2255 //
2256 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2257 //
2258 //=================================================================================================
2259 
2260 //*************************************************************************************************
2271 template< typename MT // Type of the adapted sparse matrix
2272  , bool SO > // Storage order of the adapted sparse matrix
2273 template< typename Other > // Data type of the foreign expression
2274 inline bool SymmetricMatrix<MT,SO,false,false>::canAlias( const Other* alias ) const
2275 {
2276  return matrix_.canAlias( alias );
2277 }
2279 //*************************************************************************************************
2280 
2281 
2282 //*************************************************************************************************
2293 template< typename MT // Type of the adapted sparse matrix
2294  , bool SO > // Storage order of the adapted sparse matrix
2295 template< typename Other > // Data type of the foreign expression
2296 inline bool SymmetricMatrix<MT,SO,false,false>::isAliased( const Other* alias ) const
2297 {
2298  return matrix_.isAliased( alias );
2299 }
2301 //*************************************************************************************************
2302 
2303 
2304 //*************************************************************************************************
2315 template< typename MT // Type of the adapted sparse matrix
2316  , bool SO > // Storage order of the adapted sparse matrix
2317 inline bool SymmetricMatrix<MT,SO,false,false>::canSMPAssign() const
2318 {
2319  return matrix_.canSMPAssign();
2320 }
2322 //*************************************************************************************************
2323 
2324 
2325 //*************************************************************************************************
2337 template< typename MT // Type of the adapted sparse matrix
2338  , bool SO > // Storage order of the adapted sparse matrix
2339 template< typename MT2 > // Type of the right-hand side dense matrix
2340 void SymmetricMatrix<MT,SO,false,false>::assign( DenseMatrix<MT2,SO>& rhs )
2341 {
2343 
2344  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2345  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2346 
2347  std::vector<size_t> nonzeros( rows(), 0UL );
2348  size_t sum( 0UL );
2349 
2350  for( size_t i=0UL; i<rows(); ++i ) {
2351  nonzeros[i] = (~rhs).nonZeros(i);
2352  sum += nonzeros[i];
2353  }
2354 
2355  matrix_.reserve( sum );
2356  for( size_t i=0UL; i<rows(); ++i ) {
2357  matrix_.reserve( i, nonzeros[i] );
2358  }
2359 
2360  for( size_t i=0UL; i<rows(); ++i ) {
2361  for( size_t j=i; j<columns(); ++j ) {
2362  if( !isDefault( (~rhs)(i,j) ) ) {
2363  SharedValue<ET> shared;
2364  move( *shared, (~rhs)(i,j) );
2365  matrix_.append( i, j, shared, false );
2366  if( i != j )
2367  matrix_.append( j, i, shared, false );
2368  }
2369  }
2370  }
2371 }
2373 //*************************************************************************************************
2374 
2375 
2376 //*************************************************************************************************
2388 template< typename MT // Type of the adapted sparse matrix
2389  , bool SO > // Storage order of the adapted sparse matrix
2390 template< typename MT2 > // Type of the right-hand side dense matrix
2391 void SymmetricMatrix<MT,SO,false,false>::assign( const DenseMatrix<MT2,SO>& rhs )
2392 {
2394 
2395  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2396  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2397 
2398  std::vector<size_t> nonzeros( rows(), 0UL );
2399  size_t sum( 0UL );
2400 
2401  for( size_t i=0UL; i<rows(); ++i ) {
2402  nonzeros[i] = (~rhs).nonZeros(i);
2403  sum += nonzeros[i];
2404  }
2405 
2406  matrix_.reserve( sum );
2407  for( size_t i=0UL; i<rows(); ++i ) {
2408  matrix_.reserve( i, nonzeros[i] );
2409  }
2410 
2411  for( size_t i=0UL; i<rows(); ++i ) {
2412  for( size_t j=i; j<columns(); ++j ) {
2413  if( !isDefault( (~rhs)(i,j) ) ) {
2414  const SharedValue<ET> shared( (~rhs)(i,j) );
2415  matrix_.append( i, j, shared, false );
2416  if( i != j )
2417  matrix_.append( j, i, shared, false );
2418  }
2419  }
2420  }
2421 }
2423 //*************************************************************************************************
2424 
2425 
2426 //*************************************************************************************************
2438 template< typename MT // Type of the adapted sparse matrix
2439  , bool SO > // Storage order of the adapted sparse matrix
2440 template< typename MT2 > // Type of the right-hand side sparse matrix
2441 void SymmetricMatrix<MT,SO,false,false>::assign( SparseMatrix<MT2,SO>& rhs )
2442 {
2444 
2445  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2446  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2447 
2448  std::vector<size_t> nonzeros( rows(), 0UL );
2449  size_t sum( 0UL );
2450 
2451  for( size_t i=0UL; i<rows(); ++i ) {
2452  nonzeros[i] = (~rhs).nonZeros(i);
2453  sum += nonzeros[i];
2454  }
2455 
2456  matrix_.reserve( sum );
2457  for( size_t i=0UL; i<rows(); ++i ) {
2458  matrix_.reserve( i, nonzeros[i] );
2459  }
2460 
2461  for( size_t i=0UL; i<rows(); ++i ) {
2462  for( typename MT2::Iterator it=(~rhs).lowerBound(i,i); it!=(~rhs).end(i); ++it ) {
2463  if( !isDefault( it->value() ) ) {
2464  SharedValue<ET> shared;
2465  move( *shared, it->value() );
2466  matrix_.append( i, it->index(), shared, false );
2467  if( i != it->index() )
2468  matrix_.append( it->index(), i, shared, false );
2469  }
2470  }
2471  }
2472 }
2474 //*************************************************************************************************
2475 
2476 
2477 //*************************************************************************************************
2489 template< typename MT // Type of the adapted sparse matrix
2490  , bool SO > // Storage order of the adapted sparse matrix
2491 template< typename MT2 > // Type of the right-hand side sparse matrix
2492 void SymmetricMatrix<MT,SO,false,false>::assign( const SparseMatrix<MT2,SO>& rhs )
2493 {
2495 
2496  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2497  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2498 
2499  std::vector<size_t> nonzeros( rows(), 0UL );
2500  size_t sum( 0UL );
2501 
2502  for( size_t i=0UL; i<rows(); ++i ) {
2503  nonzeros[i] = (~rhs).nonZeros(i);
2504  sum += nonzeros[i];
2505  }
2506 
2507  matrix_.reserve( sum );
2508  for( size_t i=0UL; i<rows(); ++i ) {
2509  matrix_.reserve( i, nonzeros[i] );
2510  }
2511 
2512  for( size_t i=0UL; i<rows(); ++i ) {
2513  for( typename MT2::ConstIterator it=(~rhs).lowerBound(i,i); it!=(~rhs).end(i); ++it ) {
2514  if( !isDefault( it->value() ) ) {
2515  const SharedValue<ET> shared( it->value() );
2516  matrix_.append( i, it->index(), shared, false );
2517  if( i != it->index() )
2518  matrix_.append( it->index(), i, shared, false );
2519  }
2520  }
2521  }
2522 }
2524 //*************************************************************************************************
2525 
2526 } // namespace blaze
2527 
2528 #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.
void swap(SymmetricMatrix< MT, SO, DF, NF > &a, SymmetricMatrix< MT, SO, DF, NF > &b)
Swapping the contents of two matrices.
Definition: SymmetricMatrix.h:195
#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:4838
Header file for the subtraction trait.
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:4772
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:731
Constraint on the data type.
Header file for the SharedValue class.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2478
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:4709
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:2472
#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:2474
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:4736
Header file for the multiplication trait.
Header file for the IsSymmetric type trait.
Header file for the clear shim.
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:4754
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2482
#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
BLAZE_ALWAYS_INLINE void clear(const NonNumericProxy< MT > &proxy)
Clearing the represented element.
Definition: NonNumericProxy.h:854
Constraint on the data type.
Header file for the IsLower type trait.
Header file for the SparseElement base class.
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2475
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:2476
Header file for the RemoveAdaptor type trait.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2480
Header file for the EnableIf class template.
Header file for the NonNumericProxy class.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE EnableIf< IsIntegral< T >, Set< T, sizeof(T)> >::Type::Type set(T value)
Sets all values in the vector to the given integral value.
Definition: Set.h:211
#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:2477
Header file for run time assertion macros.
Header file for the addition trait.
Constraint on the data type.
Constraint on the data type.
Header file for the implementation of the base template of the SymmetricMatrix.
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:2481
Header file for the isDefault shim.
BLAZE_ALWAYS_INLINE bool isDefault(const NonNumericProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: NonNumericProxy.h:874
Constraint on the data type.
Constraint on the data type.
BLAZE_ALWAYS_INLINE void reset(const NonNumericProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: NonNumericProxy.h:833
#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:932
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:2473
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
Header file for basic type definitions.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2479
Header file for the IsUpper type trait.
#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