DenseNonNumeric.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_DENSENONNUMERIC_H_
36 #define _BLAZE_MATH_ADAPTORS_SYMMETRICMATRIX_DENSENONNUMERIC_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <iterator>
45 #include <stdexcept>
57 #include <blaze/math/shims/Clear.h>
59 #include <blaze/math/shims/Move.h>
69 #include <blaze/util/Assert.h>
75 #include <blaze/util/DisableIf.h>
76 #include <blaze/util/EnableIf.h>
77 #include <blaze/util/mpl/If.h>
79 #include <blaze/util/Types.h>
82 #include <blaze/util/Unused.h>
83 
84 
85 namespace blaze {
86 
87 //=================================================================================================
88 //
89 // CLASS TEMPLATE SPECIALIZATION FOR DENSE MATRICES WITH NON-NUMERIC ELEMENT TYPE
90 //
91 //=================================================================================================
92 
93 //*************************************************************************************************
101 template< typename MT // Type of the adapted dense matrix
102  , bool SO > // Storage order of the adapted dense matrix
103 class SymmetricMatrix<MT,SO,true,false>
104  : public DenseMatrix< SymmetricMatrix<MT,SO,true,false>, SO >
105 {
106  private:
107  //**Type definitions****************************************************************************
108  typedef typename MT::OppositeType OT;
109  typedef typename MT::TransposeType TT;
110  typedef typename MT::ElementType ET;
111  //**********************************************************************************************
112 
113  public:
114  //**Type definitions****************************************************************************
115  typedef SymmetricMatrix<MT,SO,true,false> This;
116  typedef This ResultType;
117  typedef SymmetricMatrix<OT,!SO,true,false> OppositeType;
118  typedef SymmetricMatrix<TT,!SO,true,false> TransposeType;
119  typedef ET ElementType;
120  typedef typename MT::ReturnType ReturnType;
121  typedef const This& CompositeType;
122  typedef typename MT::Reference Reference;
123  typedef typename MT::ConstReference ConstReference;
124  typedef typename MT::Pointer Pointer;
125  typedef typename MT::ConstPointer ConstPointer;
126  //**********************************************************************************************
127 
128  //**Rebind struct definition********************************************************************
131  template< typename ET > // Data type of the other matrix
132  struct Rebind {
134  typedef SymmetricMatrix< typename MT::template Rebind<ET>::Other > Other;
135  };
136  //**********************************************************************************************
137 
138  //**MatrixIterator class definition*************************************************************
141  template< typename MatrixType > // Type of the adapted dense matrix
142  class MatrixIterator
143  {
144  public:
145  //**Type definitions*************************************************************************
147  typedef typename IfTrue< IsConst<MatrixType>::value
148  , typename MatrixType::ConstReference
149  , typename MatrixType::Reference >::Type Reference;
150 
151  typedef std::random_access_iterator_tag IteratorCategory;
152  typedef RemoveReference<Reference> ValueType;
153  typedef ValueType* PointerType;
154  typedef Reference ReferenceType;
155  typedef ptrdiff_t DifferenceType;
156 
157  // STL iterator requirements
158  typedef IteratorCategory iterator_category;
159  typedef ValueType value_type;
160  typedef PointerType pointer;
161  typedef ReferenceType reference;
162  typedef DifferenceType difference_type;
163  //*******************************************************************************************
164 
165  //**Constructor******************************************************************************
168  inline MatrixIterator()
169  : matrix_( NULL ) // Reference to the adapted dense matrix
170  , row_ ( 0UL ) // The current row index of the iterator
171  , column_( 0UL ) // The current column index of the iterator
172  {}
173  //*******************************************************************************************
174 
175  //**Constructor******************************************************************************
182  inline MatrixIterator( MatrixType& matrix, size_t row, size_t column )
183  : matrix_( &matrix ) // Reference to the adapted dense matrix
184  , row_ ( row ) // The current row index of the iterator
185  , column_( column ) // The current column index of the iterator
186  {}
187  //*******************************************************************************************
188 
189  //**Conversion constructor*******************************************************************
194  template< typename MatrixType2 >
195  inline MatrixIterator( const MatrixIterator<MatrixType2>& it )
196  : matrix_( it.matrix_ ) // Reference to the adapted dense matrix
197  , row_ ( it.row_ ) // The current row index of the iterator
198  , column_( it.column_ ) // The current column index of the iterator
199  {}
200  //*******************************************************************************************
201 
202  //**Addition assignment operator*************************************************************
208  inline MatrixIterator& operator+=( size_t inc ) {
209  ( SO )?( row_ += inc ):( column_ += inc );
210  return *this;
211  }
212  //*******************************************************************************************
213 
214  //**Subtraction assignment operator**********************************************************
220  inline MatrixIterator& operator-=( size_t dec ) {
221  ( SO )?( row_ -= dec ):( column_ -= dec );
222  return *this;
223  }
224  //*******************************************************************************************
225 
226  //**Prefix increment operator****************************************************************
231  inline MatrixIterator& operator++() {
232  ( SO )?( ++row_ ):( ++column_ );
233  return *this;
234  }
235  //*******************************************************************************************
236 
237  //**Postfix increment operator***************************************************************
242  inline const MatrixIterator operator++( int ) {
243  const MatrixIterator tmp( *this );
244  ++(*this);
245  return tmp;
246  }
247  //*******************************************************************************************
248 
249  //**Prefix decrement operator****************************************************************
254  inline MatrixIterator& operator--() {
255  ( SO )?( --row_ ):( --column_ );
256  return *this;
257  }
258  //*******************************************************************************************
259 
260  //**Postfix decrement operator***************************************************************
265  inline const MatrixIterator operator--( int ) {
266  const MatrixIterator tmp( *this );
267  --(*this);
268  return tmp;
269  }
270  //*******************************************************************************************
271 
272  //**Element access operator******************************************************************
277  inline ReferenceType operator*() const {
278  if( ( SO && row_ < column_ ) || ( !SO && row_ > column_ ) )
279  return (*matrix_)(row_,column_);
280  else
281  return (*matrix_)(column_,row_);
282  }
283  //*******************************************************************************************
284 
285  //**Element access operator******************************************************************
290  inline PointerType operator->() const {
291  if( ( SO && row_ < column_ ) || ( !SO && row_ > column_ ) )
292  return &(*matrix_)(row_,column_);
293  else
294  return &(*matrix_)(column_,row_);
295  }
296  //*******************************************************************************************
297 
298  //**Equality operator************************************************************************
304  template< typename MatrixType2 >
305  inline bool operator==( const MatrixIterator<MatrixType2>& rhs ) const {
306  return ( SO )?( row_ == rhs.row_ ):( column_ == rhs.column_ );
307  }
308  //*******************************************************************************************
309 
310  //**Inequality operator**********************************************************************
316  template< typename MatrixType2 >
317  inline bool operator!=( const MatrixIterator<MatrixType2>& rhs ) const {
318  return ( SO )?( row_ != rhs.row_ ):( column_ != rhs.column_ );
319  }
320  //*******************************************************************************************
321 
322  //**Less-than operator***********************************************************************
328  template< typename MatrixType2 >
329  inline bool operator<( const MatrixIterator<MatrixType2>& rhs ) const {
330  return ( SO )?( row_ < rhs.row_ ):( column_ < rhs.column_ );
331  return ( column_ < rhs.column_ );
332  }
333  //*******************************************************************************************
334 
335  //**Greater-than operator********************************************************************
341  template< typename MatrixType2 >
342  inline bool operator>( const MatrixIterator<MatrixType2>& rhs ) const {
343  return ( SO )?( row_ > rhs.row_ ):( column_ > rhs.column_ );
344  return ( column_ > rhs.column_ );
345  }
346  //*******************************************************************************************
347 
348  //**Less-or-equal-than operator**************************************************************
354  template< typename MatrixType2 >
355  inline bool operator<=( const MatrixIterator<MatrixType2>& rhs ) const {
356  return ( SO )?( row_ <= rhs.row_ ):( column_ <= rhs.column_ );
357  }
358  //*******************************************************************************************
359 
360  //**Greater-or-equal-than operator***********************************************************
366  template< typename MatrixType2 >
367  inline bool operator>=( const MatrixIterator<MatrixType2>& rhs ) const {
368  return ( SO )?( row_ >= rhs.row_ ):( column_ >= rhs.column_ );
369  }
370  //*******************************************************************************************
371 
372  //**Subtraction operator*********************************************************************
378  inline DifferenceType operator-( const MatrixIterator& rhs ) const {
379  return ( SO )?( row_ - rhs.row_ ):( column_ - rhs.column_ );
380  }
381  //*******************************************************************************************
382 
383  //**Addition operator************************************************************************
390  friend inline const MatrixIterator operator+( const MatrixIterator& it, size_t inc ) {
391  if( SO )
392  return MatrixIterator( *it.matrix_, it.row_ + inc, it.column_ );
393  else
394  return MatrixIterator( *it.matrix_, it.row_, it.column_ + inc );
395  }
396  //*******************************************************************************************
397 
398  //**Addition operator************************************************************************
405  friend inline const MatrixIterator operator+( size_t inc, const MatrixIterator& it ) {
406  if( SO )
407  return MatrixIterator( *it.matrix_, it.row_ + inc, it.column_ );
408  else
409  return MatrixIterator( *it.matrix_, it.row_, it.column_ + inc );
410  }
411  //*******************************************************************************************
412 
413  //**Subtraction operator*********************************************************************
420  friend inline const MatrixIterator operator-( const MatrixIterator& it, size_t dec ) {
421  if( SO )
422  return MatrixIterator( *it.matrix_, it.row_ - dec, it.column_ );
423  else
424  return MatrixIterator( *it.matrix_, it.row_, it.column_ - dec );
425  }
426  //*******************************************************************************************
427 
428  private:
429  //**Member variables*************************************************************************
430  MatrixType* matrix_;
431  size_t row_;
432  size_t column_;
433  //*******************************************************************************************
434 
435  //**Friend declarations**********************************************************************
436  template< typename MatrixType2 > friend class MatrixIterator;
437  //*******************************************************************************************
438  };
439  //**********************************************************************************************
440 
441  //**Type definitions****************************************************************************
442  typedef MatrixIterator<MT> Iterator;
443  typedef MatrixIterator<const MT> ConstIterator;
444  //**********************************************************************************************
445 
446  //**Compilation flags***************************************************************************
448  enum { vectorizable = 0 };
449 
451  enum { smpAssignable = MT::smpAssignable && !IsSMPAssignable<ET>::value };
452  //**********************************************************************************************
453 
454  //**Constructors********************************************************************************
457  explicit inline SymmetricMatrix();
458  explicit inline SymmetricMatrix( size_t n );
459 
460  inline SymmetricMatrix( const SymmetricMatrix& m );
461  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,SO>& m );
462  template< typename MT2 > inline SymmetricMatrix( const Matrix<MT2,!SO>& m );
464  //**********************************************************************************************
465 
466  //**Destructor**********************************************************************************
467  // No explicitly declared destructor.
468  //**********************************************************************************************
469 
470  //**Data access functions***********************************************************************
473  inline Reference operator()( size_t i, size_t j );
474  inline ConstReference operator()( size_t i, size_t j ) const;
475  inline ConstPointer data () const;
476  inline ConstPointer data ( size_t i ) const;
477  inline Iterator begin ( size_t i );
478  inline ConstIterator begin ( size_t i ) const;
479  inline ConstIterator cbegin( size_t i ) const;
480  inline Iterator end ( size_t i );
481  inline ConstIterator end ( size_t i ) const;
482  inline ConstIterator cend ( size_t i ) const;
484  //**********************************************************************************************
485 
486  //**Assignment operators************************************************************************
489  inline SymmetricMatrix& operator=( const SymmetricMatrix& rhs );
490 
491  template< typename MT2 >
492  inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
493  operator=( const Matrix<MT2,SO>& rhs );
494 
495  template< typename MT2 >
496  inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
497  operator=( const Matrix<MT2,SO>& rhs );
498 
499  template< typename MT2 >
500  inline SymmetricMatrix& operator=( const Matrix<MT2,!SO>& rhs );
501 
502  template< typename MT2 >
503  inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
504  operator+=( const Matrix<MT2,SO>& rhs );
505 
506  template< typename MT2 >
507  inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
508  operator+=( const Matrix<MT2,SO>& rhs );
509 
510  template< typename MT2 >
511  inline SymmetricMatrix& operator+=( const Matrix<MT2,!SO>& rhs );
512 
513  template< typename MT2 >
514  inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
515  operator-=( const Matrix<MT2,SO>& rhs );
516 
517  template< typename MT2 >
518  inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix& >::Type
519  operator-=( const Matrix<MT2,SO>& rhs );
520 
521  template< typename MT2 >
522  inline SymmetricMatrix& operator-=( const Matrix<MT2,!SO>& rhs );
523 
524  template< typename MT2, bool SO2 >
525  inline SymmetricMatrix& operator*=( const Matrix<MT2,SO2>& rhs );
526 
527  template< typename Other >
528  inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix >::Type&
529  operator*=( Other rhs );
530 
531  template< typename Other >
532  inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix >::Type&
533  operator/=( Other rhs );
535  //**********************************************************************************************
536 
537  //**Utility functions***************************************************************************
540  inline size_t rows() const;
541  inline size_t columns() const;
542  inline size_t spacing() const;
543  inline size_t capacity() const;
544  inline size_t capacity( size_t i ) const;
545  inline size_t nonZeros() const;
546  inline size_t nonZeros( size_t i ) const;
547  inline void reset();
548  inline void reset( size_t i );
549  inline void clear();
550  void resize ( size_t n, bool preserve=true );
551  inline void extend ( size_t n, bool preserve=true );
552  inline void reserve( size_t elements );
553  inline SymmetricMatrix& transpose();
554  template< typename Other > inline SymmetricMatrix& scale( const Other& scalar );
555  inline void swap( SymmetricMatrix& m ) /* throw() */;
557  //**********************************************************************************************
558 
559  private:
560  //**Utility functions***************************************************************************
563  inline bool isLowerOrUpper();
565  //**********************************************************************************************
566 
567  public:
568  //**Expression template evaluation functions****************************************************
571  template< typename Other > inline bool canAlias ( const Other* alias ) const;
572  template< typename Other > inline bool isAliased( const Other* alias ) const;
573 
574  inline bool isAligned () const;
575  inline bool canSMPAssign() const;
577  //**********************************************************************************************
578 
579  private:
580  //**Expression template evaluation functions****************************************************
583  template< typename MT2 > inline void assign ( DenseMatrix <MT2,SO>& rhs );
584  template< typename MT2 > inline void assign ( const DenseMatrix <MT2,SO>& rhs );
585  template< typename MT2 > inline void assign ( const SparseMatrix<MT2,SO>& rhs );
586  template< typename MT2 > inline void addAssign( const DenseMatrix <MT2,SO>& rhs );
587  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
588  template< typename MT2 > inline void subAssign( const DenseMatrix <MT2,SO>& rhs );
589  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
591  //**********************************************************************************************
592 
593  //**Member variables****************************************************************************
596  MT 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 dense matrix
638  , bool SO > // Storage order of the adapted dense matrix
639 inline SymmetricMatrix<MT,SO,true,false>::SymmetricMatrix()
640  : matrix_() // The adapted dense matrix
641 {
642  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
643 }
645 //*************************************************************************************************
646 
647 
648 //*************************************************************************************************
654 template< typename MT // Type of the adapted dense matrix
655  , bool SO > // Storage order of the adapted dense matrix
656 inline SymmetricMatrix<MT,SO,true,false>::SymmetricMatrix( size_t n )
657  : matrix_( n, n ) // The adapted dense matrix
658 {
660 
661  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
662 }
664 //*************************************************************************************************
665 
666 
667 //*************************************************************************************************
673 template< typename MT // Type of the adapted dense matrix
674  , bool SO > // Storage order of the adapted dense matrix
675 inline SymmetricMatrix<MT,SO,true,false>::SymmetricMatrix( const SymmetricMatrix& m )
676  : matrix_( m.matrix_ ) // The adapted dense matrix
677 {
678  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
679  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
680 }
682 //*************************************************************************************************
683 
684 
685 //*************************************************************************************************
695 template< typename MT // Type of the adapted dense matrix
696  , bool SO > // Storage order of the adapted dense matrix
697 template< typename MT2 > // Type of the foreign matrix
698 inline SymmetricMatrix<MT,SO,true,false>::SymmetricMatrix( const Matrix<MT2,SO>& m )
699  : matrix_() // The adapted dense matrix
700 {
701  using blaze::resize;
702 
703  typedef typename RemoveAdaptor<typename MT2::ResultType>::Type RT;
704  typedef typename If< IsComputation<MT2>, RT, const MT2& >::Type Tmp;
705 
706  if( IsSymmetric<MT2>::value ) {
707  resize( matrix_, (~m).rows(), (~m).columns() );
708  assign( ~m );
709  }
710  else {
711  Tmp tmp( ~m );
712 
713  if( !isSymmetric( tmp ) )
714  throw std::invalid_argument( "Invalid setup of symmetric matrix" );
715 
716  resize( matrix_, tmp.rows(), tmp.rows() );
717  assign( tmp );
718  }
719 
720  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
721  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
722 }
724 //*************************************************************************************************
725 
726 
727 //*************************************************************************************************
737 template< typename MT // Type of the adapted dense matrix
738  , bool SO > // Storage order of the adapted dense matrix
739 template< typename MT2 > // Type of the foreign matrix
740 inline SymmetricMatrix<MT,SO,true,false>::SymmetricMatrix( const Matrix<MT2,!SO>& m )
741  : matrix_() // The adapted dense matrix
742 {
743  using blaze::resize;
744 
745  typedef typename RemoveAdaptor<typename MT2::ResultType>::Type RT;
746  typedef typename If< IsComputation<MT2>, RT, const MT2& >::Type Tmp;
747 
748  if( IsSymmetric<MT2>::value ) {
749  resize( matrix_, (~m).rows(), (~m).columns() );
750  assign( trans( ~m ) );
751  }
752  else {
753  Tmp tmp( ~m );
754 
755  if( !isSymmetric( tmp ) )
756  throw std::invalid_argument( "Invalid setup of symmetric matrix" );
757 
758  resize( matrix_, tmp.rows(), tmp.rows() );
759  assign( trans( tmp ) );
760  }
761 
762  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
763  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
764 }
766 //*************************************************************************************************
767 
768 
769 
770 
771 //=================================================================================================
772 //
773 // DATA ACCESS FUNCTIONS
774 //
775 //=================================================================================================
776 
777 //*************************************************************************************************
789 template< typename MT // Type of the adapted dense matrix
790  , bool SO > // Storage order of the adapted dense matrix
792  SymmetricMatrix<MT,SO,true,false>::operator()( size_t i, size_t j )
793 {
794  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
795  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
796 
797  if( ( !SO && i > j ) || ( SO && i < j ) )
798  return matrix_(i,j);
799  else
800  return matrix_(j,i);
801 }
803 //*************************************************************************************************
804 
805 
806 //*************************************************************************************************
818 template< typename MT // Type of the adapted dense matrix
819  , bool SO > // Storage order of the adapted dense matrix
821  SymmetricMatrix<MT,SO,true,false>::operator()( size_t i, size_t j ) const
822 {
823  BLAZE_USER_ASSERT( i<rows() , "Invalid row access index" );
824  BLAZE_USER_ASSERT( j<columns(), "Invalid column access index" );
825 
826  if( ( !SO && i > j ) || ( SO && i < j ) )
827  return matrix_(i,j);
828  else
829  return matrix_(j,i);
830 }
832 //*************************************************************************************************
833 
834 
835 //*************************************************************************************************
849 template< typename MT // Type of the adapted dense matrix
850  , bool SO > // Storage order of the adapted dense matrix
851 inline typename SymmetricMatrix<MT,SO,true,false>::ConstPointer
852  SymmetricMatrix<MT,SO,true,false>::data() const
853 {
854  return matrix_.data();
855 }
857 //*************************************************************************************************
858 
859 
860 //*************************************************************************************************
871 template< typename MT // Type of the adapted dense matrix
872  , bool SO > // Storage order of the adapted dense matrix
873 inline typename SymmetricMatrix<MT,SO,true,false>::ConstPointer
874  SymmetricMatrix<MT,SO,true,false>::data( size_t i ) const
875 {
876  return matrix_.data(i);
877 }
879 //*************************************************************************************************
880 
881 
882 //*************************************************************************************************
894 template< typename MT // Type of the adapted dense matrix
895  , bool SO > // Storage order of the adapted dense matrix
898 {
899  if( SO )
900  return Iterator( matrix_, 0UL, i );
901  else
902  return Iterator( matrix_, i, 0UL );
903 }
905 //*************************************************************************************************
906 
907 
908 //*************************************************************************************************
920 template< typename MT // Type of the adapted dense matrix
921  , bool SO > // Storage order of the adapted dense matrix
924 {
925  if( SO )
926  return ConstIterator( matrix_, 0UL, i );
927  else
928  return ConstIterator( matrix_, i, 0UL );
929 }
931 //*************************************************************************************************
932 
933 
934 //*************************************************************************************************
946 template< typename MT // Type of the adapted dense matrix
947  , bool SO > // Storage order of the adapted dense matrix
950 {
951  if( SO )
952  return ConstIterator( matrix_, 0UL, i );
953  else
954  return ConstIterator( matrix_, i, 0UL );
955 }
957 //*************************************************************************************************
958 
959 
960 //*************************************************************************************************
972 template< typename MT // Type of the adapted dense matrix
973  , bool SO > // Storage order of the adapted dense matrix
976 {
977  if( SO )
978  return Iterator( matrix_, rows(), i );
979  else
980  return Iterator( matrix_, i, columns() );
981 }
983 //*************************************************************************************************
984 
985 
986 //*************************************************************************************************
998 template< typename MT // Type of the adapted dense matrix
999  , bool SO > // Storage order of the adapted dense matrix
1001  SymmetricMatrix<MT,SO,true,false>::end( size_t i ) const
1002 {
1003  if( SO )
1004  return ConstIterator( matrix_, rows(), i );
1005  else
1006  return ConstIterator( matrix_, i, columns() );
1007 }
1009 //*************************************************************************************************
1010 
1011 
1012 //*************************************************************************************************
1024 template< typename MT // Type of the adapted dense matrix
1025  , bool SO > // Storage order of the adapted dense matrix
1027  SymmetricMatrix<MT,SO,true,false>::cend( size_t i ) const
1028 {
1029  if( SO )
1030  return ConstIterator( matrix_, rows(), i );
1031  else
1032  return ConstIterator( matrix_, i, columns() );
1033 }
1035 //*************************************************************************************************
1036 
1037 
1038 
1039 
1040 //=================================================================================================
1041 //
1042 // ASSIGNMENT OPERATORS
1043 //
1044 //=================================================================================================
1045 
1046 //*************************************************************************************************
1056 template< typename MT // Type of the adapted dense matrix
1057  , bool SO > // Storage order of the adapted dense matrix
1058 inline SymmetricMatrix<MT,SO,true,false>&
1059  SymmetricMatrix<MT,SO,true,false>::operator=( const SymmetricMatrix& rhs )
1060 {
1061  using blaze::resize;
1062 
1063  if( &rhs == this ) return *this;
1064 
1065  resize( matrix_, rhs.rows(), rhs.columns() );
1066  assign( rhs );
1067 
1068  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1069  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
1070 
1071  return *this;
1072 }
1074 //*************************************************************************************************
1075 
1076 
1077 //*************************************************************************************************
1091 template< typename MT // Type of the adapted dense matrix
1092  , bool SO > // Storage order of the adapted dense matrix
1093 template< typename MT2 > // Type of the right-hand side matrix
1094 inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,true,false>& >::Type
1095  SymmetricMatrix<MT,SO,true,false>::operator=( const Matrix<MT2,SO>& rhs )
1096 {
1097  using blaze::resize;
1098 
1099  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) )
1100  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1101 
1102  if( (~rhs).isAliased( this ) ) {
1103  SymmetricMatrix tmp( ~rhs );
1104  swap( tmp );
1105  }
1106  else {
1107  resize( matrix_, (~rhs).rows(), (~rhs).columns() );
1108  if( IsSparseMatrix<MT2>::value )
1109  reset();
1110  assign( ~rhs );
1111  }
1112 
1113  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1114  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
1115 
1116  return *this;
1117 }
1119 //*************************************************************************************************
1120 
1121 
1122 //*************************************************************************************************
1136 template< typename MT // Type of the adapted dense matrix
1137  , bool SO > // Storage order of the adapted dense matrix
1138 template< typename MT2 > // Type of the right-hand side matrix
1139 inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,true,false>& >::Type
1140  SymmetricMatrix<MT,SO,true,false>::operator=( const Matrix<MT2,SO>& rhs )
1141 {
1142  using blaze::resize;
1143 
1144  typedef typename If< IsSymmetric<MT2>
1145  , typename MT2::CompositeType
1146  , typename MT2::ResultType >::Type Tmp;
1147 
1148  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) )
1149  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1150 
1151  Tmp tmp( ~rhs );
1152 
1153  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) )
1154  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1155 
1156  BLAZE_INTERNAL_ASSERT( !tmp.canAlias( this ), "Aliasing detected" );
1157 
1158  resize( matrix_, tmp.rows(), tmp.columns() );
1159  if( IsSparseMatrix<Tmp>::value )
1160  reset();
1161  assign( tmp );
1162 
1163  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1164  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
1165 
1166  return *this;
1167 }
1169 //*************************************************************************************************
1170 
1171 
1172 //*************************************************************************************************
1186 template< typename MT // Type of the adapted dense matrix
1187  , bool SO > // Storage order of the adapted dense matrix
1188 template< typename MT2 > // Type of the right-hand side matrix
1189 inline SymmetricMatrix<MT,SO,true,false>&
1190  SymmetricMatrix<MT,SO,true,false>::operator=( const Matrix<MT2,!SO>& rhs )
1191 {
1192  return this->operator=( trans( ~rhs ) );
1193 }
1195 //*************************************************************************************************
1196 
1197 
1198 //*************************************************************************************************
1211 template< typename MT // Type of the adapted dense matrix
1212  , bool SO > // Storage order of the adapted dense matrix
1213 template< typename MT2 > // Type of the right-hand side matrix
1214 inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,true,false>& >::Type
1215  SymmetricMatrix<MT,SO,true,false>::operator+=( const Matrix<MT2,SO>& rhs )
1216 {
1217  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) )
1218  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1219 
1220  addAssign( ~rhs );
1221 
1222  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1223  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
1224 
1225  return *this;
1226 }
1228 //*************************************************************************************************
1229 
1230 
1231 //*************************************************************************************************
1244 template< typename MT // Type of the adapted dense matrix
1245  , bool SO > // Storage order of the adapted dense matrix
1246 template< typename MT2 > // Type of the right-hand side matrix
1247 inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,true,false>& >::Type
1248  SymmetricMatrix<MT,SO,true,false>::operator+=( const Matrix<MT2,SO>& rhs )
1249 {
1250  typedef typename If< IsSymmetric<MT2>
1251  , typename MT2::CompositeType
1252  , typename MT2::ResultType >::Type Tmp;
1253 
1254  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) )
1255  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1256 
1257  Tmp tmp( ~rhs );
1258 
1259  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) )
1260  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1261 
1262  BLAZE_INTERNAL_ASSERT( !tmp.canAlias( this ), "Aliasing detected" );
1263 
1264  addAssign( tmp );
1265 
1266  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1267  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
1268 
1269  return *this;
1270 }
1272 //*************************************************************************************************
1273 
1274 
1275 //*************************************************************************************************
1289 template< typename MT // Type of the adapted dense matrix
1290  , bool SO > // Storage order of the adapted dense matrix
1291 template< typename MT2 > // Type of the right-hand side matrix
1292 inline SymmetricMatrix<MT,SO,true,false>&
1293  SymmetricMatrix<MT,SO,true,false>::operator+=( const Matrix<MT2,!SO>& rhs )
1294 {
1295  return this->operator+=( trans( ~rhs ) );
1296 }
1298 //*************************************************************************************************
1299 
1300 
1301 //*************************************************************************************************
1314 template< typename MT // Type of the adapted dense matrix
1315  , bool SO > // Storage order of the adapted dense matrix
1316 template< typename MT2 > // Type of the right-hand side matrix
1317 inline typename DisableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,true,false>& >::Type
1318  SymmetricMatrix<MT,SO,true,false>::operator-=( const Matrix<MT2,SO>& rhs )
1319 {
1320  if( !IsSymmetric<MT2>::value && !isSymmetric( ~rhs ) )
1321  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1322 
1323  subAssign( ~rhs );
1324 
1325  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1326  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
1327 
1328  return *this;
1329 }
1331 //*************************************************************************************************
1332 
1333 
1334 //*************************************************************************************************
1347 template< typename MT // Type of the adapted dense matrix
1348  , bool SO > // Storage order of the adapted dense matrix
1349 template< typename MT2 > // Type of the right-hand side matrix
1350 inline typename EnableIf< IsComputation<MT2>, SymmetricMatrix<MT,SO,true,false>& >::Type
1351  SymmetricMatrix<MT,SO,true,false>::operator-=( const Matrix<MT2,SO>& rhs )
1352 {
1353  typedef typename If< IsSymmetric<MT2>
1354  , typename MT2::CompositeType
1355  , typename MT2::ResultType >::Type Tmp;
1356 
1357  if( !IsSquare<MT2>::value && !isSquare( ~rhs ) )
1358  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1359 
1360  Tmp tmp( ~rhs );
1361 
1362  if( !IsSymmetric<Tmp>::value && !isSymmetric( tmp ) )
1363  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1364 
1365  BLAZE_INTERNAL_ASSERT( !tmp.canAlias( this ), "Aliasing detected" );
1366 
1367  subAssign( tmp );
1368 
1369  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1370  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
1371 
1372  return *this;
1373 }
1375 //*************************************************************************************************
1376 
1377 
1378 //*************************************************************************************************
1392 template< typename MT // Type of the adapted dense matrix
1393  , bool SO > // Storage order of the adapted dense matrix
1394 template< typename MT2 > // Type of the right-hand side matrix
1395 inline SymmetricMatrix<MT,SO,true,false>&
1396  SymmetricMatrix<MT,SO,true,false>::operator-=( const Matrix<MT2,!SO>& rhs )
1397 {
1398  return this->operator-=( trans( ~rhs ) );
1399 }
1401 //*************************************************************************************************
1402 
1403 
1404 //*************************************************************************************************
1416 template< typename MT // Type of the adapted dense matrix
1417  , bool SO > // Storage order of the adapted dense matrix
1418 template< typename MT2 // Type of the right-hand side matrix
1419  , bool SO2 > // Storage order of the right-hand side matrix
1420 inline SymmetricMatrix<MT,SO,true,false>&
1421  SymmetricMatrix<MT,SO,true,false>::operator*=( const Matrix<MT2,SO2>& rhs )
1422 {
1423  using blaze::resize;
1424 
1425  typedef typename MultTrait<MT,typename MT2::ResultType>::Type Tmp;
1426 
1428 
1429  if( matrix_.rows() != (~rhs).columns() )
1430  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1431 
1432  Tmp tmp( (*this) * ~rhs );
1433 
1434  if( !isSymmetric( tmp ) )
1435  throw std::invalid_argument( "Invalid assignment to symmetric matrix" );
1436 
1437  resize( matrix_, tmp.rows(), tmp.columns() );
1438  assign( tmp );
1439 
1440  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1441  BLAZE_INTERNAL_ASSERT( isLowerOrUpper() , "Broken invariant detected" );
1442 
1443  return *this;
1444 }
1446 //*************************************************************************************************
1447 
1448 
1449 //*************************************************************************************************
1457 template< typename MT // Type of the adapted dense matrix
1458  , bool SO > // Storage order of the adapted dense matrix
1459 template< typename Other > // Data type of the right-hand side scalar
1460 inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix<MT,SO,true,false> >::Type&
1461  SymmetricMatrix<MT,SO,true,false>::operator*=( Other rhs )
1462 {
1463  if( SO ) {
1464  for( size_t j=0UL; j<columns(); ++j )
1465  for( size_t i=0UL; i<=j; ++i )
1466  matrix_(i,j) *= rhs;
1467  }
1468  else {
1469  for( size_t i=0UL; i<rows(); ++i )
1470  for( size_t j=0UL; j<=i; ++j )
1471  matrix_(i,j) *= rhs;
1472  }
1473 
1474  return *this;
1475 }
1477 //*************************************************************************************************
1478 
1479 
1480 //*************************************************************************************************
1488 template< typename MT // Type of the adapted dense matrix
1489  , bool SO > // Storage order of the adapted dense matrix
1490 template< typename Other > // Data type of the right-hand side scalar
1491 inline typename EnableIf< IsNumeric<Other>, SymmetricMatrix<MT,SO,true,false> >::Type&
1492  SymmetricMatrix<MT,SO,true,false>::operator/=( Other rhs )
1493 {
1494  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1495 
1496  if( SO ) {
1497  for( size_t j=0UL; j<columns(); ++j )
1498  for( size_t i=0UL; i<=j; ++i )
1499  matrix_(i,j) /= rhs;
1500  }
1501  else {
1502  for( size_t i=0UL; i<rows(); ++i )
1503  for( size_t j=0UL; j<=i; ++j )
1504  matrix_(i,j) /= rhs;
1505  }
1506 
1507  return *this;
1508 }
1510 //*************************************************************************************************
1511 
1512 
1513 
1514 
1515 //=================================================================================================
1516 //
1517 // UTILITY FUNCTIONS
1518 //
1519 //=================================================================================================
1520 
1521 //*************************************************************************************************
1527 template< typename MT // Type of the adapted dense matrix
1528  , bool SO > // Storage order of the adapted dense matrix
1529 inline size_t SymmetricMatrix<MT,SO,true,false>::rows() const
1530 {
1531  return matrix_.rows();
1532 }
1534 //*************************************************************************************************
1535 
1536 
1537 //*************************************************************************************************
1543 template< typename MT // Type of the adapted dense matrix
1544  , bool SO > // Storage order of the adapted dense matrix
1545 inline size_t SymmetricMatrix<MT,SO,true,false>::columns() const
1546 {
1547  return matrix_.columns();
1548 }
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1565 template< typename MT // Type of the adapted dense matrix
1566  , bool SO > // Storage order of the adapted dense matrix
1567 inline size_t SymmetricMatrix<MT,SO,true,false>::spacing() const
1568 {
1569  return matrix_.spacing();
1570 }
1572 //*************************************************************************************************
1573 
1574 
1575 //*************************************************************************************************
1581 template< typename MT // Type of the adapted dense matrix
1582  , bool SO > // Storage order of the adapted dense matrix
1583 inline size_t SymmetricMatrix<MT,SO,true,false>::capacity() const
1584 {
1585  return matrix_.capacity();
1586 }
1588 //*************************************************************************************************
1589 
1590 
1591 //*************************************************************************************************
1602 template< typename MT // Type of the adapted dense matrix
1603  , bool SO > // Storage order of the adapted dense matrix
1604 inline size_t SymmetricMatrix<MT,SO,true,false>::capacity( size_t i ) const
1605 {
1606  return matrix_.capacity(i);
1607 }
1609 //*************************************************************************************************
1610 
1611 
1612 //*************************************************************************************************
1618 template< typename MT // Type of the adapted dense matrix
1619  , bool SO > // Storage order of the adapted dense matrix
1620 inline size_t SymmetricMatrix<MT,SO,true,false>::nonZeros() const
1621 {
1622  size_t nonzeros( 0UL );
1623 
1624  if( SO )
1625  {
1626  for( size_t j=0UL; j<columns(); ++j ) {
1627  for( size_t i=0UL; i<j; ++i ) {
1628  if( !isDefault( matrix_(i,j) ) )
1629  nonzeros += 2UL;
1630  }
1631  if( !isDefault( matrix_(j,j) ) )
1632  ++nonzeros;
1633  }
1634  }
1635  else
1636  {
1637  for( size_t i=0UL; i<rows(); ++i ) {
1638  for( size_t j=0UL; j<i; ++j ) {
1639  if( !isDefault( matrix_(i,j) ) )
1640  nonzeros += 2UL;
1641  }
1642  if( !isDefault( matrix_(i,i) ) )
1643  ++nonzeros;
1644  }
1645  }
1646 
1647  return nonzeros;
1648 }
1650 //*************************************************************************************************
1651 
1652 
1653 //*************************************************************************************************
1665 template< typename MT // Type of the adapted dense matrix
1666  , bool SO > // Storage order of the adapted dense matrix
1667 inline size_t SymmetricMatrix<MT,SO,true,false>::nonZeros( size_t i ) const
1668 {
1669  size_t nonzeros( 0UL );
1670 
1671  if( SO )
1672  {
1673  for( size_t j=0UL; j<i; ++j ) {
1674  if( !isDefault( matrix_(j,i) ) )
1675  ++nonzeros;
1676  }
1677  for( size_t j=i; j<rows(); ++j ) {
1678  if( !isDefault( matrix_(i,j) ) )
1679  ++nonzeros;
1680  }
1681  }
1682  else
1683  {
1684  for( size_t j=0UL; j<i; ++j ) {
1685  if( !isDefault( matrix_(i,j) ) )
1686  ++nonzeros;
1687  }
1688  for( size_t j=i; j<rows(); ++j ) {
1689  if( !isDefault( matrix_(j,i) ) )
1690  ++nonzeros;
1691  }
1692  }
1693 
1694  return nonzeros;
1695 }
1697 //*************************************************************************************************
1698 
1699 
1700 //*************************************************************************************************
1706 template< typename MT // Type of the adapted dense matrix
1707  , bool SO > // Storage order of the adapted dense matrix
1709 {
1710  using blaze::clear;
1711 
1712  if( SO ) {
1713  for( size_t j=0UL; j<columns(); ++j )
1714  for( size_t i=0UL; i<=j; ++i )
1715  clear( matrix_(i,j) );
1716  }
1717  else {
1718  for( size_t i=0UL; i<rows(); ++i )
1719  for( size_t j=0UL; j<=i; ++j )
1720  clear( matrix_(i,j) );
1721  }
1722 }
1724 //*************************************************************************************************
1725 
1726 
1727 //*************************************************************************************************
1767 template< typename MT // Type of the adapted dense matrix
1768  , bool SO > // Storage order of the adapted dense matrix
1769 inline void SymmetricMatrix<MT,SO,true,false>::reset( size_t i )
1770 {
1771  using blaze::clear;
1772 
1773  for( Iterator element=begin(i); element!=end(i); ++element )
1774  clear( *element );
1775 }
1777 //*************************************************************************************************
1778 
1779 
1780 //*************************************************************************************************
1792 template< typename MT // Type of the adapted dense matrix
1793  , bool SO > // Storage order of the adapted dense matrix
1795 {
1796  using blaze::clear;
1797 
1798  clear( matrix_ );
1799 }
1801 //*************************************************************************************************
1802 
1803 
1804 //*************************************************************************************************
1820 template< typename MT // Type of the adapted dense matrix
1821  , bool SO > // Storage order of the adapted dense matrix
1822 void SymmetricMatrix<MT,SO,true,false>::resize( size_t n, bool preserve )
1823 {
1825 
1826  UNUSED_PARAMETER( preserve );
1827 
1828  BLAZE_INTERNAL_ASSERT( isSquare( matrix_ ), "Non-square symmetric matrix detected" );
1829 
1830  const size_t oldsize( matrix_.rows() );
1831 
1832  matrix_.resize( n, n, true );
1833 
1834  if( n > oldsize ) {
1835  const size_t increment( n - oldsize );
1836  submatrix( matrix_, 0UL, oldsize, oldsize, increment ).reset();
1837  submatrix( matrix_, oldsize, 0UL, increment, n ).reset();
1838  }
1839 }
1841 //*************************************************************************************************
1842 
1843 
1844 //*************************************************************************************************
1857 template< typename MT // Type of the adapted dense matrix
1858  , bool SO > // Storage order of the adapted dense matrix
1859 inline void SymmetricMatrix<MT,SO,true,false>::extend( size_t n, bool preserve )
1860 {
1862 
1863  UNUSED_PARAMETER( preserve );
1864 
1865  resize( rows() + n, true );
1866 }
1868 //*************************************************************************************************
1869 
1870 
1871 //*************************************************************************************************
1881 template< typename MT // Type of the adapted dense matrix
1882  , bool SO > // Storage order of the adapted dense matrix
1883 inline void SymmetricMatrix<MT,SO,true,false>::reserve( size_t elements )
1884 {
1885  matrix_.reserve( elements );
1886 }
1888 //*************************************************************************************************
1889 
1890 
1891 //*************************************************************************************************
1897 template< typename MT // Type of the adapted dense matrix
1898  , bool SO > // Storage order of the adapted dense matrix
1899 inline SymmetricMatrix<MT,SO,true,false>& SymmetricMatrix<MT,SO,true,false>::transpose()
1900 {
1901  return *this;
1902 }
1904 //*************************************************************************************************
1905 
1906 
1907 //*************************************************************************************************
1914 template< typename MT // Type of the adapted dense matrix
1915  , bool SO > // Storage order of the adapted dense matrix
1916 template< typename Other > // Data type of the scalar value
1917 inline SymmetricMatrix<MT,SO,true,false>&
1918  SymmetricMatrix<MT,SO,true,false>::scale( const Other& scalar )
1919 {
1920  if( SO ) {
1921  for( size_t j=0UL; j<columns(); ++j )
1922  for( size_t i=0UL; i<=j; ++i )
1923  matrix_(i,j) *= scalar;
1924  }
1925  else {
1926  for( size_t i=0UL; i<rows(); ++i )
1927  for( size_t j=0UL; j<=i; ++j )
1928  matrix_(i,j) *= scalar;
1929  }
1930 
1931  return *this;
1932 }
1934 //*************************************************************************************************
1935 
1936 
1937 //*************************************************************************************************
1945 template< typename MT // Type of the adapted dense matrix
1946  , bool SO > // Storage order of the adapted dense matrix
1947 inline void SymmetricMatrix<MT,SO,true,false>::swap( SymmetricMatrix& m ) /* throw() */
1948 {
1949  using std::swap;
1950 
1951  swap( matrix_, m.matrix_ );
1952 }
1954 //*************************************************************************************************
1955 
1956 
1957 //*************************************************************************************************
1968 template< typename MT // Type of the adapted dense matrix
1969  , bool SO > // Storage order of the adapted dense matrix
1970 inline bool SymmetricMatrix<MT,SO,true,false>::isLowerOrUpper()
1971 {
1972  return ( SO ) ? ( isUpper( matrix_ ) ) : ( isLower( matrix_ ) );
1973 }
1975 //*************************************************************************************************
1976 
1977 
1978 
1979 
1980 //=================================================================================================
1981 //
1982 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1983 //
1984 //=================================================================================================
1985 
1986 //*************************************************************************************************
1997 template< typename MT // Type of the adapted dense matrix
1998  , bool SO > // Storage order of the adapted dense matrix
1999 template< typename Other > // Data type of the foreign expression
2000 inline bool SymmetricMatrix<MT,SO,true,false>::canAlias( const Other* alias ) const
2001 {
2002  return matrix_.canAlias( alias );
2003 }
2005 //*************************************************************************************************
2006 
2007 
2008 //*************************************************************************************************
2019 template< typename MT // Type of the adapted dense matrix
2020  , bool SO > // Storage order of the adapted dense matrix
2021 template< typename Other > // Data type of the foreign expression
2022 inline bool SymmetricMatrix<MT,SO,true,false>::isAliased( const Other* alias ) const
2023 {
2024  return matrix_.isAliased( alias );
2025 }
2027 //*************************************************************************************************
2028 
2029 
2030 //*************************************************************************************************
2040 template< typename MT // Type of the adapted dense matrix
2041  , bool SO > // Storage order of the adapted dense matrix
2042 inline bool SymmetricMatrix<MT,SO,true,false>::isAligned() const
2043 {
2044  return matrix_.isAligned();
2045 }
2047 //*************************************************************************************************
2048 
2049 
2050 //*************************************************************************************************
2061 template< typename MT // Type of the adapted dense matrix
2062  , bool SO > // Storage order of the adapted dense matrix
2063 inline bool SymmetricMatrix<MT,SO,true,false>::canSMPAssign() const
2064 {
2065  return matrix_.canSMPAssign();
2066 }
2068 //*************************************************************************************************
2069 
2070 
2071 //*************************************************************************************************
2083 template< typename MT // Type of the adapted dense matrix
2084  , bool SO > // Storage order of the adapted dense matrix
2085 template< typename MT2 > // Type of the right-hand side dense matrix
2086 inline void SymmetricMatrix<MT,SO,true,false>::assign( DenseMatrix<MT2,SO>& rhs )
2087 {
2088  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2089  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2090 
2091  if( SO ) {
2092  for( size_t j=0UL; j<columns(); ++j )
2093  for( size_t i=0UL; i<=j; ++i )
2094  move( matrix_(i,j), (~rhs)(i,j) );
2095  }
2096  else {
2097  for( size_t i=0UL; i<rows(); ++i )
2098  for( size_t j=0UL; j<=i; ++j )
2099  move( matrix_(i,j), (~rhs)(i,j) );
2100  }
2101 }
2103 //*************************************************************************************************
2104 
2105 
2106 //*************************************************************************************************
2118 template< typename MT // Type of the adapted dense matrix
2119  , bool SO > // Storage order of the adapted dense matrix
2120 template< typename MT2 > // Type of the right-hand side dense matrix
2121 inline void SymmetricMatrix<MT,SO,true,false>::assign( const DenseMatrix<MT2,SO>& rhs )
2122 {
2123  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2124  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2125 
2126  if( SO ) {
2127  for( size_t j=0UL; j<columns(); ++j )
2128  for( size_t i=0UL; i<=j; ++i )
2129  matrix_(i,j) = (~rhs)(i,j);
2130  }
2131  else {
2132  for( size_t i=0UL; i<rows(); ++i )
2133  for( size_t j=0UL; j<=i; ++j )
2134  matrix_(i,j) = (~rhs)(i,j);
2135  }
2136 }
2138 //*************************************************************************************************
2139 
2140 
2141 //*************************************************************************************************
2153 template< typename MT // Type of the adapted dense matrix
2154  , bool SO > // Storage order of the adapted dense matrix
2155 template< typename MT2 > // Type of the right-hand side sparse matrix
2156 inline void SymmetricMatrix<MT,SO,true,false>::assign( const SparseMatrix<MT2,SO>& rhs )
2157 {
2158  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2159  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2160 
2161  typedef typename MT2::ConstIterator ConstIterator;
2162 
2163  if( SO ) {
2164  for( size_t j=0UL; j<columns(); ++j ) {
2165  const ConstIterator last( (~rhs).upperBound(j,j) );
2166  for( ConstIterator element=(~rhs).begin(j); element!=last; ++element )
2167  matrix_(element->index(),j) = element->value();
2168  }
2169  }
2170  else {
2171  for( size_t i=0UL; i<rows(); ++i ) {
2172  const ConstIterator last( (~rhs).upperBound(i,i) );
2173  for( ConstIterator element=(~rhs).begin(i); element!=last; ++element )
2174  matrix_(i,element->index()) = element->value();
2175  }
2176  }
2177 }
2179 //*************************************************************************************************
2180 
2181 
2182 //*************************************************************************************************
2194 template< typename MT // Type of the adapted dense matrix
2195  , bool SO > // Storage order of the adapted dense matrix
2196 template< typename MT2 > // Type of the right-hand side dense matrix
2197 inline void SymmetricMatrix<MT,SO,true,false>::addAssign( const DenseMatrix<MT2,SO>& rhs )
2198 {
2199  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2200  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2201 
2202  if( SO ) {
2203  for( size_t j=0UL; j<columns(); ++j )
2204  for( size_t i=0UL; i<=j; ++i )
2205  matrix_(i,j) += (~rhs)(i,j);
2206  }
2207  else {
2208  for( size_t i=0UL; i<rows(); ++i )
2209  for( size_t j=0UL; j<=i; ++j )
2210  matrix_(i,j) += (~rhs)(i,j);
2211  }
2212 }
2214 //*************************************************************************************************
2215 
2216 
2217 //*************************************************************************************************
2229 template< typename MT // Type of the adapted dense matrix
2230  , bool SO > // Storage order of the adapted dense matrix
2231 template< typename MT2 > // Type of the right-hand side sparse matrix
2232 inline void SymmetricMatrix<MT,SO,true,false>::addAssign( const SparseMatrix<MT2,SO>& rhs )
2233 {
2234  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2235  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2236 
2237  typedef typename MT2::ConstIterator ConstIterator;
2238 
2239  if( SO ) {
2240  for( size_t j=0UL; j<columns(); ++j ) {
2241  const ConstIterator last( (~rhs).upperBound(j,j) );
2242  for( ConstIterator element=(~rhs).begin(j); element!=last; ++element )
2243  matrix_(element->index(),j) += element->value();
2244  }
2245  }
2246  else {
2247  for( size_t i=0UL; i<rows(); ++i ) {
2248  const ConstIterator last( (~rhs).upperBound(i,i) );
2249  for( ConstIterator element=(~rhs).begin(i); element!=last; ++element )
2250  matrix_(i,element->index()) += element->value();
2251  }
2252  }
2253 }
2255 //*************************************************************************************************
2256 
2257 
2258 //*************************************************************************************************
2270 template< typename MT // Type of the adapted dense matrix
2271  , bool SO > // Storage order of the adapted dense matrix
2272 template< typename MT2 > // Type of the right-hand side dense matrix
2273 inline void SymmetricMatrix<MT,SO,true,false>::subAssign( const DenseMatrix<MT2,SO>& rhs )
2274 {
2275  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2276  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2277 
2278  if( SO ) {
2279  for( size_t j=0UL; j<columns(); ++j )
2280  for( size_t i=0UL; i<=j; ++i )
2281  matrix_(i,j) -= (~rhs)(i,j);
2282  }
2283  else {
2284  for( size_t i=0UL; i<rows(); ++i )
2285  for( size_t j=0UL; j<=i; ++j )
2286  matrix_(i,j) -= (~rhs)(i,j);
2287  }
2288 }
2290 //*************************************************************************************************
2291 
2292 
2293 //*************************************************************************************************
2305 template< typename MT // Type of the adapted dense matrix
2306  , bool SO > // Storage order of the adapted dense matrix
2307 template< typename MT2 > // Type of the right-hand side sparse matrix
2308 inline void SymmetricMatrix<MT,SO,true,false>::subAssign( const SparseMatrix<MT2,SO>& rhs )
2309 {
2310  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2311  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2312 
2313  typedef typename MT2::ConstIterator ConstIterator;
2314 
2315  if( SO ) {
2316  for( size_t j=0UL; j<columns(); ++j ) {
2317  const ConstIterator last( (~rhs).upperBound(j,j) );
2318  for( ConstIterator element=(~rhs).begin(j); element!=last; ++element )
2319  matrix_(element->index(),j) -= element->value();
2320  }
2321  }
2322  else {
2323  for( size_t i=0UL; i<rows(); ++i ) {
2324  const ConstIterator last( (~rhs).upperBound(i,i) );
2325  for( ConstIterator element=(~rhs).begin(i); element!=last; ++element )
2326  matrix_(i,element->index()) -= element->value();
2327  }
2328  }
2329 }
2331 //*************************************************************************************************
2332 
2333 } // namespace blaze
2334 
2335 #endif
Header file for all restructuring submatrix functions.
#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.
#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 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
Header file for the IsSparseMatrix type trait.
#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_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:79
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.
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
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename ColumnExprTrait< MT >::Type >::Type column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:103
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:366
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2501
bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:442
#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 isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:964
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 IsSquare type trait.
Constraint on the data type.
Header file for the DenseSubmatrix class template.
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 DisableIf class template.
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
Header file for the DenseMatrix base class.
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.
const DenseIterator< Type > operator+(const DenseIterator< Type > &it, ptrdiff_t inc)
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:556
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2504
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1197
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.
Header file for all forward declarations for expression class templates.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2509
Header file for the EnableIf class template.
Header file for utility functions for dense matrices.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:841
Header file for the IsNumeric type trait.
const bool spacing
Adding an additional spacing line between two log messages.This setting gives the opportunity to add ...
Definition: Logging.h:70
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename RowExprTrait< MT >::Type >::Type row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:103
#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.
BLAZE_ALWAYS_INLINE void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:742
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.
Header file for the RemoveReference type trait.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b)
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:200
Header file for the move shim.
SubmatrixExprTrait< MT, unaligned >::Type submatrix(Matrix< MT, SO > &matrix, size_t row, size_t column, size_t m, size_t n)
Creating a view on a specific submatrix of the given matrix.
Definition: Submatrix.h:143
#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
BLAZE_ALWAYS_INLINE void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:849