DenseSubmatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_DENSESUBMATRIX_H_
36 #define _BLAZE_MATH_VIEWS_DENSESUBMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <stdexcept>
57 #include <blaze/math/Functions.h>
58 #include <blaze/math/Intrinsics.h>
59 #include <blaze/math/shims/Clear.h>
61 #include <blaze/math/shims/IsOne.h>
89 #include <blaze/system/CacheSize.h>
90 #include <blaze/system/Inline.h>
91 #include <blaze/system/Streaming.h>
94 #include <blaze/util/Assert.h>
98 #include <blaze/util/DisableIf.h>
99 #include <blaze/util/EnableIf.h>
101 #include <blaze/util/mpl/And.h>
102 #include <blaze/util/mpl/If.h>
103 #include <blaze/util/mpl/Or.h>
104 #include <blaze/util/StaticAssert.h>
105 #include <blaze/util/Template.h>
106 #include <blaze/util/Types.h>
113 #include <blaze/util/Unused.h>
114 
115 
116 namespace blaze {
117 
118 //=================================================================================================
119 //
120 // CLASS DEFINITION
121 //
122 //=================================================================================================
123 
124 //*************************************************************************************************
471 template< typename MT // Type of the dense matrix
472  , bool AF = unaligned // Alignment flag
473  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
474 class DenseSubmatrix : public DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO >
475  , private Submatrix
476 {
477  private:
478  //**Type definitions****************************************************************************
480  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
481 
484  //**********************************************************************************************
485 
486  //**********************************************************************************************
488 
494  enum { useConst = IsConst<MT>::value };
495  //**********************************************************************************************
496 
497  public:
498  //**Type definitions****************************************************************************
503  typedef typename MT::ElementType ElementType;
504  typedef typename IT::Type IntrinsicType;
505  typedef typename MT::ReturnType ReturnType;
506  typedef const DenseSubmatrix& CompositeType;
507 
510 
513 
515  typedef const ElementType* ConstPointer;
516 
519  //**********************************************************************************************
520 
521  //**SubmatrixIterator class definition**********************************************************
524  template< typename IteratorType > // Type of the dense matrix iterator
526  {
527  public:
528  //**Type definitions*************************************************************************
530  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
531 
533  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
534 
536  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
537 
539  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
540 
542  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
543 
544  // STL iterator requirements
545  typedef IteratorCategory iterator_category;
546  typedef ValueType value_type;
547  typedef PointerType pointer;
548  typedef ReferenceType reference;
549  typedef DifferenceType difference_type;
550  //*******************************************************************************************
551 
552  //**Constructor******************************************************************************
556  : iterator_ ( ) // Iterator to the current submatrix element
557  , final_ ( 0UL ) // The final iterator for intrinsic operations
558  , rest_ ( 0UL ) // The number of remaining elements beyond the final iterator
559  , isAligned_( false ) // Memory alignment flag
560  {}
561  //*******************************************************************************************
562 
563  //**Constructor******************************************************************************
571  inline SubmatrixIterator( IteratorType iterator, IteratorType finalIterator,
572  size_t remainingElements, bool isMemoryAligned )
573  : iterator_ ( iterator ) // Iterator to the current submatrix element
574  , final_ ( finalIterator ) // The final iterator for intrinsic operations
575  , rest_ ( remainingElements ) // The number of remaining elements beyond the final iterator
576  , isAligned_( isMemoryAligned ) // Memory alignment flag
577  {}
578  //*******************************************************************************************
579 
580  //**Constructor******************************************************************************
585  template< typename IteratorType2 >
587  : iterator_ ( it.base() ) // Iterator to the current submatrix element
588  , final_ ( it.final() ) // The final iterator for intrinsic operations
589  , rest_ ( it.rest() ) // The number of remaining elements beyond the final iterator
590  , isAligned_( it.isAligned() ) // Memory alignment flag
591  {}
592  //*******************************************************************************************
593 
594  //**Addition assignment operator*************************************************************
600  inline SubmatrixIterator& operator+=( size_t inc ) {
601  iterator_ += inc;
602  return *this;
603  }
604  //*******************************************************************************************
605 
606  //**Subtraction assignment operator**********************************************************
612  inline SubmatrixIterator& operator-=( size_t dec ) {
613  iterator_ -= dec;
614  return *this;
615  }
616  //*******************************************************************************************
617 
618  //**Prefix increment operator****************************************************************
624  ++iterator_;
625  return *this;
626  }
627  //*******************************************************************************************
628 
629  //**Postfix increment operator***************************************************************
634  inline const SubmatrixIterator operator++( int ) {
636  }
637  //*******************************************************************************************
638 
639  //**Prefix decrement operator****************************************************************
645  --iterator_;
646  return *this;
647  }
648  //*******************************************************************************************
649 
650  //**Postfix decrement operator***************************************************************
655  inline const SubmatrixIterator operator--( int ) {
657  }
658  //*******************************************************************************************
659 
660  //**Element access operator******************************************************************
665  inline ReferenceType operator*() const {
666  return *iterator_;
667  }
668  //*******************************************************************************************
669 
670  //**Load function****************************************************************************
680  inline IntrinsicType load() const {
681  return loadu();
682  }
683  //*******************************************************************************************
684 
685  //**Loadu function***************************************************************************
695  inline IntrinsicType loadu() const {
696  if( isAligned_ ) {
697  return iterator_.load();
698  }
699  else if( iterator_ != final_ ) {
700  return iterator_.loadu();
701  }
702  else {
704  for( size_t j=0UL; j<rest_; ++j )
705  array[j] = *(iterator_+j);
706  for( size_t j=rest_; j<IT::size; ++j )
707  array[j] = ElementType();
708  return blaze::load( array.data() );
709  }
710  }
711  //*******************************************************************************************
712 
713  //**Equality operator************************************************************************
719  inline bool operator==( const SubmatrixIterator& rhs ) const {
720  return iterator_ == rhs.iterator_;
721  }
722  //*******************************************************************************************
723 
724  //**Inequality operator**********************************************************************
730  inline bool operator!=( const SubmatrixIterator& rhs ) const {
731  return iterator_ != rhs.iterator_;
732  }
733  //*******************************************************************************************
734 
735  //**Less-than operator***********************************************************************
741  inline bool operator<( const SubmatrixIterator& rhs ) const {
742  return iterator_ < rhs.iterator_;
743  }
744  //*******************************************************************************************
745 
746  //**Greater-than operator********************************************************************
752  inline bool operator>( const SubmatrixIterator& rhs ) const {
753  return iterator_ > rhs.iterator_;
754  }
755  //*******************************************************************************************
756 
757  //**Less-or-equal-than operator**************************************************************
763  inline bool operator<=( const SubmatrixIterator& rhs ) const {
764  return iterator_ <= rhs.iterator_;
765  }
766  //*******************************************************************************************
767 
768  //**Greater-or-equal-than operator***********************************************************
774  inline bool operator>=( const SubmatrixIterator& rhs ) const {
775  return iterator_ >= rhs.iterator_;
776  }
777  //*******************************************************************************************
778 
779  //**Subtraction operator*********************************************************************
785  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
786  return iterator_ - rhs.iterator_;
787  }
788  //*******************************************************************************************
789 
790  //**Addition operator************************************************************************
797  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
798  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
799  }
800  //*******************************************************************************************
801 
802  //**Addition operator************************************************************************
809  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
810  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
811  }
812  //*******************************************************************************************
813 
814  //**Subtraction operator*********************************************************************
821  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
822  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.isAligned_ );
823  }
824  //*******************************************************************************************
825 
826  //**Base function****************************************************************************
831  inline IteratorType base() const {
832  return iterator_;
833  }
834  //*******************************************************************************************
835 
836  //**Final function***************************************************************************
841  inline IteratorType final() const {
842  return final_;
843  }
844  //*******************************************************************************************
845 
846  //**Rest function****************************************************************************
851  inline size_t rest() const {
852  return rest_;
853  }
854  //*******************************************************************************************
855 
856  //**IsAligned function***********************************************************************
861  inline bool isAligned() const {
862  return isAligned_;
863  }
864  //*******************************************************************************************
865 
866  private:
867  //**Member variables*************************************************************************
868  IteratorType iterator_;
869  IteratorType final_;
870  size_t rest_;
871  bool isAligned_;
872  //*******************************************************************************************
873  };
874  //**********************************************************************************************
875 
876  //**Type definitions****************************************************************************
879 
882  //**********************************************************************************************
883 
884  //**Compilation flags***************************************************************************
886  enum { vectorizable = MT::vectorizable };
887 
889  enum { smpAssignable = MT::smpAssignable };
890  //**********************************************************************************************
891 
892  //**Constructors********************************************************************************
895  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
896  // No explicitly declared copy constructor.
898  //**********************************************************************************************
899 
900  //**Destructor**********************************************************************************
901  // No explicitly declared destructor.
902  //**********************************************************************************************
903 
904  //**Data access functions***********************************************************************
907  inline Reference operator()( size_t i, size_t j );
908  inline ConstReference operator()( size_t i, size_t j ) const;
909  inline Pointer data ();
910  inline ConstPointer data () const;
911  inline Iterator begin ( size_t i );
912  inline ConstIterator begin ( size_t i ) const;
913  inline ConstIterator cbegin( size_t i ) const;
914  inline Iterator end ( size_t i );
915  inline ConstIterator end ( size_t i ) const;
916  inline ConstIterator cend ( size_t i ) const;
918  //**********************************************************************************************
919 
920  //**Assignment operators************************************************************************
923  inline DenseSubmatrix& operator=( const ElementType& rhs );
924  inline DenseSubmatrix& operator=( const DenseSubmatrix& rhs );
925 
926  template< typename MT2, bool SO2 >
927  inline DenseSubmatrix& operator=( const Matrix<MT2,SO2>& rhs );
928 
929  template< typename MT2, bool SO2 >
930  inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
931  operator+=( const Matrix<MT2,SO2>& rhs );
932 
933  template< typename MT2, bool SO2 >
934  inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
935  operator+=( const Matrix<MT2,SO2>& rhs );
936 
937  template< typename MT2, bool SO2 >
938  inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
939  operator-=( const Matrix<MT2,SO2>& rhs );
940 
941  template< typename MT2, bool SO2 >
942  inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
943  operator-=( const Matrix<MT2,SO2>& rhs );
944 
945  template< typename MT2, bool SO2 >
946  inline DenseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
947 
948  template< typename Other >
949  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
950  operator*=( Other rhs );
951 
952  template< typename Other >
953  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
954  operator/=( Other rhs );
956  //**********************************************************************************************
957 
958  //**Utility functions***************************************************************************
961  inline size_t rows() const;
962  inline size_t columns() const;
963  inline size_t spacing() const;
964  inline size_t capacity() const;
965  inline size_t capacity( size_t i ) const;
966  inline size_t nonZeros() const;
967  inline size_t nonZeros( size_t i ) const;
968  inline void reset();
969  inline void reset( size_t i );
970  inline DenseSubmatrix& transpose();
971  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
973  //**********************************************************************************************
974 
975  private:
976  //**********************************************************************************************
978  template< typename MT2 >
980  struct VectorizedAssign {
981  enum { value = vectorizable && MT2::vectorizable &&
982  IsSame<ElementType,typename MT2::ElementType>::value };
983  };
985  //**********************************************************************************************
986 
987  //**********************************************************************************************
989  template< typename MT2 >
991  struct VectorizedAddAssign {
992  enum { value = vectorizable && MT2::vectorizable &&
993  IsSame<ElementType,typename MT2::ElementType>::value &&
994  IntrinsicTrait<ElementType>::addition };
995  };
997  //**********************************************************************************************
998 
999  //**********************************************************************************************
1001  template< typename MT2 >
1003  struct VectorizedSubAssign {
1004  enum { value = vectorizable && MT2::vectorizable &&
1005  IsSame<ElementType,typename MT2::ElementType>::value &&
1006  IntrinsicTrait<ElementType>::subtraction };
1007  };
1009  //**********************************************************************************************
1010 
1011  public:
1012  //**Expression template evaluation functions****************************************************
1015  template< typename Other >
1016  inline bool canAlias( const Other* alias ) const;
1017 
1018  template< typename MT2, bool AF2, bool SO2 >
1019  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
1020 
1021  template< typename Other >
1022  inline bool isAliased( const Other* alias ) const;
1023 
1024  template< typename MT2, bool AF2, bool SO2 >
1025  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
1026 
1027  inline bool isAligned () const;
1028  inline bool canSMPAssign() const;
1029 
1030  inline IntrinsicType load ( size_t i, size_t j ) const;
1031  inline IntrinsicType loadu( size_t i, size_t j ) const;
1032 
1033  inline void store ( size_t i, size_t j, const IntrinsicType& value );
1034  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
1035  inline void stream( size_t i, size_t j, const IntrinsicType& value );
1036 
1037  template< typename MT2 >
1038  inline typename DisableIf< VectorizedAssign<MT2> >::Type
1039  assign( const DenseMatrix<MT2,SO>& rhs );
1040 
1041  template< typename MT2 >
1042  inline typename EnableIf< VectorizedAssign<MT2> >::Type
1043  assign( const DenseMatrix<MT2,SO>& rhs );
1044 
1045  template< typename MT2 > inline void assign( const DenseMatrix<MT2,!SO>& rhs );
1046  template< typename MT2 > inline void assign( const SparseMatrix<MT2,SO>& rhs );
1047  template< typename MT2 > inline void assign( const SparseMatrix<MT2,!SO>& rhs );
1048 
1049  template< typename MT2 >
1050  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
1051  addAssign( const DenseMatrix<MT2,SO>& rhs );
1052 
1053  template< typename MT2 >
1054  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
1055  addAssign( const DenseMatrix<MT2,SO>& rhs );
1056 
1057  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,!SO>& rhs );
1058  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
1059  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,!SO>& rhs );
1060 
1061  template< typename MT2 >
1062  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
1063  subAssign( const DenseMatrix<MT2,SO>& rhs );
1064 
1065  template< typename MT2 >
1066  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
1067  subAssign( const DenseMatrix<MT2,SO>& rhs );
1068 
1069  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,!SO>& rhs );
1070  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
1071  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,!SO>& rhs );
1073  //**********************************************************************************************
1074 
1075  private:
1076  //**Utility functions***************************************************************************
1079  inline bool hasOverlap() const;
1080 
1081  template< typename MT2, bool SO2, typename MT3, bool SO3 >
1082  inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
1083  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
1084 
1085  template< typename MT2, bool SO2, typename MT3, bool SO3 >
1086  inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1087  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
1088 
1089  template< typename MT2, bool SO2, typename MT3 >
1090  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1091  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
1092 
1093  template< typename MT2, bool SO2, typename MT3 >
1094  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1095  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
1096 
1097  template< typename MT2, bool SO2, typename MT3 >
1098  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1099  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
1100 
1101  template< typename MT2, bool SO2, typename MT3 >
1102  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1103  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
1104 
1105  template< typename MT2, bool SO2, typename MT3 >
1106  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1107  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
1108 
1109  template< typename MT2, bool SO2, typename MT3 >
1110  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1111  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
1112 
1113  template< typename MT2, bool SO2, typename MT3 >
1114  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1115  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
1116 
1117  template< typename MT2, bool SO2, typename MT3 >
1118  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1119  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
1120 
1121  template< typename MT2, bool SO2, typename MT3 >
1122  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
1123  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
1124 
1125  template< typename MT2, bool SO2, typename MT3 >
1126  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
1127  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
1128 
1129  template< typename MT2, bool SO2, typename MT3 >
1130  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
1131  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
1132 
1133  template< typename MT2, bool SO2, typename MT3 >
1134  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
1135  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
1137  //**********************************************************************************************
1138 
1139  //**Member variables****************************************************************************
1142  Operand matrix_;
1143  const size_t row_;
1144  const size_t column_;
1145  const size_t m_;
1146  const size_t n_;
1147  const size_t rest_;
1148  const size_t final_;
1149 
1153  const bool isAligned_;
1154 
1164  //**********************************************************************************************
1165 
1166  //**Friend declarations*************************************************************************
1168  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
1169 
1170  template< bool AF1, typename MT2, bool AF2, bool SO2 >
1171  friend const DenseSubmatrix<MT2,AF1,SO2>
1172  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
1173 
1174  template< typename MT2, bool AF2, bool SO2 >
1175  friend bool isSymmetric( const DenseSubmatrix<MT2,AF2,SO2>& dm );
1176 
1177  template< typename MT2, bool AF2, bool SO2 >
1178  friend bool isLower( const DenseSubmatrix<MT2,AF2,SO2>& dm );
1179 
1180  template< typename MT2, bool AF2, bool SO2 >
1181  friend bool isUpper( const DenseSubmatrix<MT2,AF2,SO2>& dm );
1182 
1183  template< typename MT2, bool AF2, bool SO2 >
1184  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
1185 
1186  template< typename MT2, bool AF2, bool SO2 >
1187  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
1188 
1189  template< typename MT2, bool AF2, bool SO2 >
1190  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
1191 
1192  template< typename MT2, bool AF2, bool SO2 >
1193  friend typename DerestrictTrait< DenseSubmatrix<MT2,AF2,SO2> >::Type
1194  derestrict( DenseSubmatrix<MT2,AF2,SO2>& dm );
1196  //**********************************************************************************************
1197 
1198  //**Compile time checks*************************************************************************
1209  //**********************************************************************************************
1210 };
1211 //*************************************************************************************************
1212 
1213 
1214 
1215 
1216 //=================================================================================================
1217 //
1218 // CONSTRUCTOR
1219 //
1220 //=================================================================================================
1221 
1222 //*************************************************************************************************
1235 template< typename MT // Type of the dense matrix
1236  , bool AF // Alignment flag
1237  , bool SO > // Storage order
1238 inline DenseSubmatrix<MT,AF,SO>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
1239  : matrix_ ( matrix ) // The dense matrix containing the submatrix
1240  , row_ ( row ) // The first row of the submatrix
1241  , column_ ( column ) // The first column of the submatrix
1242  , m_ ( m ) // The number of rows of the submatrix
1243  , n_ ( n ) // The number of columns of the submatrix
1244  , rest_ ( n % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
1245  , final_ ( n - rest_ ) // The final index for unaligned intrinsic operations
1246  , isAligned_( ( column % IT::size == 0UL ) &&
1247  ( column + n == matrix.columns() || n % IT::size == 0UL ) )
1248 {
1249  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
1250  throw std::invalid_argument( "Invalid submatrix specification" );
1251 }
1252 //*************************************************************************************************
1253 
1254 
1255 
1256 
1257 //=================================================================================================
1258 //
1259 // DATA ACCESS FUNCTIONS
1260 //
1261 //=================================================================================================
1262 
1263 //*************************************************************************************************
1270 template< typename MT // Type of the dense matrix
1271  , bool AF // Alignment flag
1272  , bool SO > // Storage order
1275 {
1276  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1277  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1278 
1279  return matrix_(row_+i,column_+j);
1280 }
1281 //*************************************************************************************************
1282 
1283 
1284 //*************************************************************************************************
1291 template< typename MT // Type of the dense matrix
1292  , bool AF // Alignment flag
1293  , bool SO > // Storage order
1295  DenseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
1296 {
1297  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1298  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1299 
1300  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
1301 }
1302 //*************************************************************************************************
1303 
1304 
1305 //*************************************************************************************************
1314 template< typename MT // Type of the dense matrix
1315  , bool AF // Alignment flag
1316  , bool SO > // Storage order
1318 {
1319  return matrix_.data() + row_*spacing() + column_;
1320 }
1321 //*************************************************************************************************
1322 
1323 
1324 //*************************************************************************************************
1333 template< typename MT // Type of the dense matrix
1334  , bool AF // Alignment flag
1335  , bool SO > // Storage order
1337 {
1338  return matrix_.data() + row_*spacing() + column_;
1339 }
1340 //*************************************************************************************************
1341 
1342 
1343 //*************************************************************************************************
1354 template< typename MT // Type of the dense matrix
1355  , bool AF // Alignment flag
1356  , bool SO > // Storage order
1358 {
1359  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1360  const typename MT::Iterator first( matrix_.begin( row_ + i ) + column_ );
1361  return Iterator( first, first + final_, rest_, isAligned_ );
1362 }
1363 //*************************************************************************************************
1364 
1365 
1366 //*************************************************************************************************
1377 template< typename MT // Type of the dense matrix
1378  , bool AF // Alignment flag
1379  , bool SO > // Storage order
1382 {
1383  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1384  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
1385  return ConstIterator( first, first + final_, rest_, isAligned_ );
1386 }
1387 //*************************************************************************************************
1388 
1389 
1390 //*************************************************************************************************
1401 template< typename MT // Type of the dense matrix
1402  , bool AF // Alignment flag
1403  , bool SO > // Storage order
1406 {
1407  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1408  const typename MT::ConstIterator first( matrix_.cbegin( row_ + i ) + column_ );
1409  return ConstIterator( first, first + final_, rest_, isAligned_ );
1410 }
1411 //*************************************************************************************************
1412 
1413 
1414 //*************************************************************************************************
1425 template< typename MT // Type of the dense matrix
1426  , bool AF // Alignment flag
1427  , bool SO > // Storage order
1429 {
1430  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1431  const typename MT::Iterator last( matrix_.begin( row_ + i ) + column_ + n_ );
1432  return Iterator( last, last, rest_, isAligned_ );
1433 }
1434 //*************************************************************************************************
1435 
1436 
1437 //*************************************************************************************************
1448 template< typename MT // Type of the dense matrix
1449  , bool AF // Alignment flag
1450  , bool SO > // Storage order
1453 {
1454  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1455  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1456  return ConstIterator( last, last, rest_, isAligned_ );
1457 }
1458 //*************************************************************************************************
1459 
1460 
1461 //*************************************************************************************************
1472 template< typename MT // Type of the dense matrix
1473  , bool AF // Alignment flag
1474  , bool SO > // Storage order
1477 {
1478  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1479  const typename MT::ConstIterator last( matrix_.cbegin( row_ + i ) + column_ + n_ );
1480  return ConstIterator( last, last, rest_, isAligned_ );
1481 }
1482 //*************************************************************************************************
1483 
1484 
1485 
1486 
1487 //=================================================================================================
1488 //
1489 // ASSIGNMENT OPERATORS
1490 //
1491 //=================================================================================================
1492 
1493 //*************************************************************************************************
1503 template< typename MT // Type of the dense matrix
1504  , bool AF // Alignment flag
1505  , bool SO > // Storage order
1507 {
1508  const size_t iend( row_ + m_ );
1509 
1510  for( size_t i=row_; i<iend; ++i )
1511  {
1512  const size_t jbegin( ( IsUpper<MT>::value )
1514  ?( max( i+1UL, column_ ) )
1515  :( max( i, column_ ) ) )
1516  :( column_ ) );
1517  const size_t jend ( ( IsLower<MT>::value )
1519  ?( min( i, column_+n_ ) )
1520  :( min( i+1UL, column_+n_ ) ) )
1521  :( column_+n_ ) );
1522 
1523  for( size_t j=jbegin; j<jend; ++j )
1524  matrix_(i,j) = rhs;
1525  }
1526 
1527  return *this;
1528 }
1529 //*************************************************************************************************
1530 
1531 
1532 //*************************************************************************************************
1546 template< typename MT // Type of the dense matrix
1547  , bool AF // Alignment flag
1548  , bool SO > // Storage order
1550 {
1553 
1554  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1555  return *this;
1556 
1557  if( rows() != rhs.rows() || columns() != rhs.columns() )
1558  throw std::invalid_argument( "Submatrix sizes do not match" );
1559 
1560  if( !preservesInvariant( matrix_, rhs ) )
1561  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1562 
1563  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1564 
1565  if( rhs.canAlias( &matrix_ ) ) {
1566  const ResultType tmp( rhs );
1567  smpAssign( left, tmp );
1568  }
1569  else {
1570  smpAssign( left, rhs );
1571  }
1572 
1573  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1574  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1575  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1576 
1577  return *this;
1578 }
1579 //*************************************************************************************************
1580 
1581 
1582 //*************************************************************************************************
1596 template< typename MT // Type of the dense matrix
1597  , bool AF // Alignment flag
1598  , bool SO > // Storage order
1599 template< typename MT2 // Type of the right-hand side matrix
1600  , bool SO2 > // Storage order of the right-hand side matrix
1602 {
1604 
1605  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1606  throw std::invalid_argument( "Matrix sizes do not match" );
1607 
1608  typedef typename If< IsAdaptor<MT>, typename MT2::CompositeType, const MT2& >::Type Right;
1609  Right right( ~rhs );
1610 
1611  if( !preservesInvariant( matrix_, right ) )
1612  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1613 
1615  reset();
1616 
1617  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1618 
1619  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1620  const typename MT2::ResultType tmp( right );
1621  smpAssign( left, tmp );
1622  }
1623  else {
1624  smpAssign( left, right );
1625  }
1626 
1627  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1628  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1629  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1630 
1631  return *this;
1632 }
1633 //*************************************************************************************************
1634 
1635 
1636 //*************************************************************************************************
1649 template< typename MT // Type of the dense matrix
1650  , bool AF // Alignment flag
1651  , bool SO > // Storage order
1652 template< typename MT2 // Type of the right-hand side matrix
1653  , bool SO2 > // Storage order of the right-hand side matrix
1655  , DenseSubmatrix<MT,AF,SO>& >::Type
1657 {
1661 
1662  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
1663 
1666 
1667  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1668  throw std::invalid_argument( "Matrix sizes do not match" );
1669 
1670  if( !preservesInvariant( matrix_, ~rhs ) )
1671  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1672 
1673  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1674 
1675  if( ( IsSymmetric<MT>::value && hasOverlap() ) || (~rhs).canAlias( &matrix_ ) ) {
1676  const AddType tmp( *this + (~rhs) );
1677  smpAssign( left, tmp );
1678  }
1679  else {
1680  smpAddAssign( left, ~rhs );
1681  }
1682 
1683  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1684  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1685  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1686 
1687  return *this;
1688 }
1689 //*************************************************************************************************
1690 
1691 
1692 //*************************************************************************************************
1705 template< typename MT // Type of the dense matrix
1706  , bool AF // Alignment flag
1707  , bool SO > // Storage order
1708 template< typename MT2 // Type of the right-hand side matrix
1709  , bool SO2 > // Storage order of the right-hand side matrix
1710 inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
1711  , DenseSubmatrix<MT,AF,SO>& >::Type
1713 {
1717 
1718  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
1719 
1722 
1723  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1724  throw std::invalid_argument( "Matrix sizes do not match" );
1725 
1726  const AddType tmp( *this + (~rhs) );
1727 
1728  if( !preservesInvariant( matrix_, tmp ) )
1729  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1730 
1731  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1732 
1733  smpAssign( left, tmp );
1734 
1735  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1736  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1737  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1738 
1739  return *this;
1740 }
1741 //*************************************************************************************************
1742 
1743 
1744 //*************************************************************************************************
1757 template< typename MT // Type of the dense matrix
1758  , bool AF // Alignment flag
1759  , bool SO > // Storage order
1760 template< typename MT2 // Type of the right-hand side matrix
1761  , bool SO2 > // Storage order of the right-hand side matrix
1762 inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
1763  , DenseSubmatrix<MT,AF,SO>& >::Type
1765 {
1769 
1770  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
1771 
1774 
1775  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1776  throw std::invalid_argument( "Matrix sizes do not match" );
1777 
1778  if( !preservesInvariant( matrix_, ~rhs ) )
1779  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1780 
1781  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1782 
1783  if( ( IsSymmetric<MT>::value && hasOverlap() ) || (~rhs).canAlias( &matrix_ ) ) {
1784  const SubType tmp( *this - (~rhs ) );
1785  smpAssign( left, tmp );
1786  }
1787  else {
1788  smpSubAssign( left, ~rhs );
1789  }
1790 
1791  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1792  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1793  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1794 
1795  return *this;
1796 }
1797 //*************************************************************************************************
1798 
1799 
1800 //*************************************************************************************************
1813 template< typename MT // Type of the dense matrix
1814  , bool AF // Alignment flag
1815  , bool SO > // Storage order
1816 template< typename MT2 // Type of the right-hand side matrix
1817  , bool SO2 > // Storage order of the right-hand side matrix
1818 inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
1819  , DenseSubmatrix<MT,AF,SO>& >::Type
1821 {
1825 
1826  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
1827 
1830 
1831  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
1832  throw std::invalid_argument( "Matrix sizes do not match" );
1833 
1834  const SubType tmp( *this - (~rhs) );
1835 
1836  if( !preservesInvariant( matrix_, tmp ) )
1837  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1838 
1839  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1840 
1841  smpAssign( left, tmp );
1842 
1843  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1844  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1845  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1846 
1847  return *this;
1848 }
1849 //*************************************************************************************************
1850 
1851 
1852 //*************************************************************************************************
1865 template< typename MT // Type of the dense matrix
1866  , bool AF // Alignment flag
1867  , bool SO > // Storage order
1868 template< typename MT2 // Type of the right-hand side matrix
1869  , bool SO2 > // Storage order of the right-hand side matrix
1871 {
1875 
1876  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1877 
1880 
1881  if( columns() != (~rhs).rows() )
1882  throw std::invalid_argument( "Matrix sizes do not match" );
1883 
1884  const MultType tmp( *this * (~rhs) );
1885 
1886  if( !preservesInvariant( matrix_, tmp ) )
1887  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
1888 
1889  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1890 
1891  smpAssign( left, tmp );
1892 
1893  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1894  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1895  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
1896 
1897  return *this;
1898 }
1899 //*************************************************************************************************
1900 
1901 
1902 //*************************************************************************************************
1912 template< typename MT // Type of the dense matrix
1913  , bool AF // Alignment flag
1914  , bool SO > // Storage order
1915 template< typename Other > // Data type of the right-hand side scalar
1916 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1918 {
1920 
1921  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1922  smpAssign( left, (*this) * rhs );
1923 
1924  return *this;
1925 }
1926 //*************************************************************************************************
1927 
1928 
1929 //*************************************************************************************************
1941 template< typename MT // Type of the dense matrix
1942  , bool AF // Alignment flag
1943  , bool SO > // Storage order
1944 template< typename Other > // Data type of the right-hand side scalar
1945 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1947 {
1949 
1950  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1951 
1952  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1953  smpAssign( left, (*this) / rhs );
1954 
1955  return *this;
1956 }
1957 //*************************************************************************************************
1958 
1959 
1960 
1961 
1962 //=================================================================================================
1963 //
1964 // UTILITY FUNCTIONS
1965 //
1966 //=================================================================================================
1967 
1968 //*************************************************************************************************
1973 template< typename MT // Type of the dense matrix
1974  , bool AF // Alignment flag
1975  , bool SO > // Storage order
1976 inline size_t DenseSubmatrix<MT,AF,SO>::rows() const
1977 {
1978  return m_;
1979 }
1980 //*************************************************************************************************
1981 
1982 
1983 //*************************************************************************************************
1988 template< typename MT // Type of the dense matrix
1989  , bool AF // Alignment flag
1990  , bool SO > // Storage order
1992 {
1993  return n_;
1994 }
1995 //*************************************************************************************************
1996 
1997 
1998 //*************************************************************************************************
2008 template< typename MT // Type of the dense matrix
2009  , bool AF // Alignment flag
2010  , bool SO > // Storage order
2012 {
2013  return matrix_.spacing();
2014 }
2015 //*************************************************************************************************
2016 
2017 
2018 //*************************************************************************************************
2023 template< typename MT // Type of the dense matrix
2024  , bool AF // Alignment flag
2025  , bool SO > // Storage order
2027 {
2028  return rows() * columns();
2029 }
2030 //*************************************************************************************************
2031 
2032 
2033 //*************************************************************************************************
2044 template< typename MT // Type of the dense matrix
2045  , bool AF // Alignment flag
2046  , bool SO > // Storage order
2047 inline size_t DenseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
2048 {
2049  UNUSED_PARAMETER( i );
2050 
2051  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2052 
2053  return columns();
2054 }
2055 //*************************************************************************************************
2056 
2057 
2058 //*************************************************************************************************
2063 template< typename MT // Type of the dense matrix
2064  , bool AF // Alignment flag
2065  , bool SO > // Storage order
2067 {
2068  const size_t iend( row_ + m_ );
2069  const size_t jend( column_ + n_ );
2070  size_t nonzeros( 0UL );
2071 
2072  for( size_t i=row_; i<iend; ++i )
2073  for( size_t j=column_; j<jend; ++j )
2074  if( !isDefault( matrix_(i,j) ) )
2075  ++nonzeros;
2076 
2077  return nonzeros;
2078 }
2079 //*************************************************************************************************
2080 
2081 
2082 //*************************************************************************************************
2093 template< typename MT // Type of the dense matrix
2094  , bool AF // Alignment flag
2095  , bool SO > // Storage order
2096 inline size_t DenseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
2097 {
2098  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2099 
2100  const size_t jend( column_ + n_ );
2101  size_t nonzeros( 0UL );
2102 
2103  for( size_t j=column_; j<jend; ++j )
2104  if( !isDefault( matrix_(row_+i,j) ) )
2105  ++nonzeros;
2106 
2107  return nonzeros;
2108 }
2109 //*************************************************************************************************
2110 
2111 
2112 //*************************************************************************************************
2117 template< typename MT // Type of the dense matrix
2118  , bool AF // Alignment flag
2119  , bool SO > // Storage order
2121 {
2122  using blaze::clear;
2123 
2124  for( size_t i=row_; i<row_+m_; ++i )
2125  {
2126  const size_t jbegin( ( IsUpper<MT>::value )
2128  ?( max( i+1UL, column_ ) )
2129  :( max( i, column_ ) ) )
2130  :( column_ ) );
2131  const size_t jend ( ( IsLower<MT>::value )
2133  ?( min( i, column_+n_ ) )
2134  :( min( i+1UL, column_+n_ ) ) )
2135  :( column_+n_ ) );
2136 
2137  for( size_t j=jbegin; j<jend; ++j )
2138  clear( matrix_(i,j) );
2139  }
2140 }
2141 //*************************************************************************************************
2142 
2143 
2144 //*************************************************************************************************
2155 template< typename MT // Type of the dense matrix
2156  , bool AF // Alignment flag
2157  , bool SO > // Storage order
2158 inline void DenseSubmatrix<MT,AF,SO>::reset( size_t i )
2159 {
2160  using blaze::clear;
2161 
2162  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2163 
2164  const size_t jbegin( ( IsUpper<MT>::value )
2166  ?( max( i+1UL, column_ ) )
2167  :( max( i, column_ ) ) )
2168  :( column_ ) );
2169  const size_t jend ( ( IsLower<MT>::value )
2171  ?( min( i, column_+n_ ) )
2172  :( min( i+1UL, column_+n_ ) ) )
2173  :( column_+n_ ) );
2174 
2175  for( size_t j=jbegin; j<jend; ++j )
2176  clear( matrix_(row_+i,j) );
2177 }
2178 //*************************************************************************************************
2179 
2180 
2181 //*************************************************************************************************
2196 template< typename MT // Type of the dense matrix
2197  , bool AF // Alignment flag
2198  , bool SO > // Storage order
2200 {
2201  if( rows() != columns() )
2202  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
2203 
2204  if( IsLower<MT>::value && ( row_ + 1UL < column_ + n_ ) )
2205  throw std::runtime_error( "Invalid transpose of a lower matrix" );
2206 
2207  if( IsUpper<MT>::value && ( column_ + 1UL < row_ + m_ ) )
2208  throw std::runtime_error( "Invalid transpose of an upper matrix" );
2209 
2210  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
2211  const ResultType tmp( trans(*this) );
2212  smpAssign( left, tmp );
2213 
2214  return *this;
2215 }
2216 //*************************************************************************************************
2217 
2218 
2219 //*************************************************************************************************
2229 template< typename MT // Type of the dense matrix
2230  , bool AF // Alignment flag
2231  , bool SO > // Storage order
2232 template< typename Other > // Data type of the scalar value
2234 {
2236 
2237  const size_t iend( row_ + m_ );
2238 
2239  for( size_t i=row_; i<iend; ++i )
2240  {
2241  const size_t jbegin( ( IsUpper<MT>::value )
2243  ?( max( i+1UL, column_ ) )
2244  :( max( i, column_ ) ) )
2245  :( column_ ) );
2246  const size_t jend ( ( IsLower<MT>::value )
2248  ?( min( i, column_+n_ ) )
2249  :( min( i+1UL, column_+n_ ) ) )
2250  :( column_+n_ ) );
2251 
2252  for( size_t j=jbegin; j<jend; ++j )
2253  matrix_(i,j) *= scalar;
2254  }
2255 
2256  return *this;
2257 }
2258 //*************************************************************************************************
2259 
2260 
2261 //*************************************************************************************************
2270 template< typename MT // Type of the dense matrix
2271  , bool AF // Alignment flag
2272  , bool SO > // Storage order
2274 {
2275  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
2276 
2277  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
2278  return false;
2279  else return true;
2280 }
2281 //*************************************************************************************************
2282 
2283 
2284 //*************************************************************************************************
2295 template< typename MT // Type of the dense matrix
2296  , bool AF // Alignment flag
2297  , bool SO > // Storage order
2298 template< typename MT2 // Type of the left-hand side dense matrix
2299  , bool SO2 // Storage order of the left-hand side dense matrix
2300  , typename MT3 // Type of the right-hand side matrix
2301  , bool SO3 > // Storage order of the right-hand side matrix
2302 inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
2304 {
2305  UNUSED_PARAMETER( lhs, rhs );
2306 
2307  return true;
2308 }
2309 //*************************************************************************************************
2310 
2311 
2312 //*************************************************************************************************
2323 template< typename MT // Type of the dense matrix
2324  , bool AF // Alignment flag
2325  , bool SO > // Storage order
2326 template< typename MT2 // Type of the left-hand side dense matrix
2327  , bool SO2 // Storage order of the left-hand side dense matrix
2328  , typename MT3 // Type of the right-hand side matrix
2329  , bool SO3 > // Storage order of the right-hand side matrix
2330 inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2332 {
2334 
2335  UNUSED_PARAMETER( lhs );
2336 
2337  if( !hasOverlap() )
2338  return true;
2339 
2340  const bool lower( row_ > column_ );
2341  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
2342 
2343  if( size < 2UL )
2344  return true;
2345 
2346  const size_t row ( lower ? 0UL : column_ - row_ );
2347  const size_t column( lower ? row_ - column_ : 0UL );
2348 
2349  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
2350 }
2351 //*************************************************************************************************
2352 
2353 
2354 //*************************************************************************************************
2366 template< typename MT // Type of the dense matrix
2367  , bool AF // Alignment flag
2368  , bool SO > // Storage order
2369 template< typename MT2 // Type of the left-hand side dense matrix
2370  , bool SO2 // Storage order of the left-hand side dense matrix
2371  , typename MT3 > // Type of the right-hand side dense matrix
2372 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2374 {
2376 
2377  UNUSED_PARAMETER( lhs );
2378 
2379  if( row_ + 1UL >= column_ + n_ )
2380  return true;
2381 
2382  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
2383  ?( column_ + n_ - row_ )
2384  :( column_ + n_ - row_ - 1UL ) );
2385  const size_t iend( min( ipos, m_ ) );
2386 
2387  for( size_t i=0UL; i<iend; ++i )
2388  {
2389  const bool containsDiagonal( row_+i >= column_ );
2390 
2391  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
2392  return false;
2393 
2394  const size_t jbegin( ( containsDiagonal )
2396  ?( row_ + i - column_ )
2397  :( row_ + i - column_ + 1UL ) )
2398  :( 0UL ) );
2399 
2400  for( size_t j=jbegin; j<n_; ++j ) {
2401  if( !isDefault( (~rhs)(i,j) ) )
2402  return false;
2403  }
2404  }
2405 
2406  return true;
2407 }
2408 //*************************************************************************************************
2409 
2410 
2411 //*************************************************************************************************
2423 template< typename MT // Type of the dense matrix
2424  , bool AF // Alignment flag
2425  , bool SO > // Storage order
2426 template< typename MT2 // Type of the left-hand side dense matrix
2427  , bool SO2 // Storage order of the left-hand side dense matrix
2428  , typename MT3 > // Type of the right-hand side dense matrix
2429 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2431 {
2433 
2434  UNUSED_PARAMETER( lhs );
2435 
2436  if( row_ + 1UL >= column_ + n_ )
2437  return true;
2438 
2439  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
2440  ?( row_ - column_ )
2441  :( row_ - column_ + 1UL ) );
2442  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
2443 
2444  for( size_t j=jbegin; j<n_; ++j )
2445  {
2446  const bool containsDiagonal( column_+j < row_+m_ );
2447 
2448  const size_t ipos( ( IsStrictlyLower<MT2>::value && containsDiagonal )
2449  ?( column_ + j - row_ + 1UL )
2450  :( column_ + j - row_ ) );
2451  const size_t iend( min( ipos, m_ ) );
2452 
2453  for( size_t i=0UL; i<iend; ++i ) {
2454  if( !isDefault( (~rhs)(i,j) ) )
2455  return false;
2456  }
2457 
2458  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
2459  return false;
2460  }
2461 
2462  return true;
2463 }
2464 //*************************************************************************************************
2465 
2466 
2467 //*************************************************************************************************
2479 template< typename MT // Type of the dense matrix
2480  , bool AF // Alignment flag
2481  , bool SO > // Storage order
2482 template< typename MT2 // Type of the left-hand side dense matrix
2483  , bool SO2 // Storage order of the left-hand side dense matrix
2484  , typename MT3 > // Type of the right-hand side sparse matrix
2485 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2487 {
2489 
2490  UNUSED_PARAMETER( lhs );
2491 
2492  typedef typename MT3::ConstIterator RhsIterator;
2493 
2494  if( row_ + 1UL >= column_ + n_ )
2495  return true;
2496 
2497  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
2498  ?( column_ + n_ - row_ )
2499  :( column_ + n_ - row_ - 1UL ) );
2500  const size_t iend( min( ipos, m_ ) );
2501 
2502  for( size_t i=0UL; i<iend; ++i )
2503  {
2504  const bool containsDiagonal( row_+i >= column_ );
2505 
2506  const size_t index( ( containsDiagonal )
2508  ?( row_ + i - column_ )
2509  :( row_ + i - column_ + 1UL ) )
2510  :( 0UL ) );
2511 
2512  const RhsIterator last( (~rhs).end(i) );
2513  RhsIterator element( (~rhs).lowerBound( i, index ) );
2514 
2515  if( IsUniLower<MT2>::value && containsDiagonal ) {
2516  if( element == last || ( element->index() != row_+i-column_ ) || !isOne( element->value() ) )
2517  return false;
2518  ++element;
2519  }
2520 
2521  for( ; element!=last; ++element ) {
2522  if( !isDefault( element->value() ) )
2523  return false;
2524  }
2525  }
2526 
2527  return true;
2528 }
2529 //*************************************************************************************************
2530 
2531 
2532 //*************************************************************************************************
2544 template< typename MT // Type of the dense matrix
2545  , bool AF // Alignment flag
2546  , bool SO > // Storage order
2547 template< typename MT2 // Type of the left-hand side dense matrix
2548  , bool SO2 // Storage order of the left-hand side dense matrix
2549  , typename MT3 > // Type of the right-hand side sparse matrix
2550 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2552 {
2554 
2555  UNUSED_PARAMETER( lhs );
2556 
2557  typedef typename MT3::ConstIterator RhsIterator;
2558 
2559  if( row_ + 1UL >= column_ + n_ )
2560  return true;
2561 
2562  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
2563  ?( row_ - column_ )
2564  :( row_ - column_ + 1UL ) );
2565  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
2566 
2567  for( size_t j=jbegin; j<n_; ++j )
2568  {
2569  const bool containsDiagonal( column_+j < row_+m_ );
2570 
2571  const size_t index( ( IsStrictlyLower<MT2>::value && containsDiagonal )
2572  ?( column_ + j - row_ + 1UL )
2573  :( column_ + j - row_ ) );
2574  const RhsIterator last( (~rhs).lowerBound( min( index, m_ ), j ) );
2575 
2576  if( IsUniLower<MT2>::value && containsDiagonal &&
2577  ( last == (~rhs).end(j) || ( last->index() != column_+j-row_ ) || !isOne( last->value() ) ) ) {
2578  return false;
2579  }
2580 
2581  for( RhsIterator element=(~rhs).begin(j); element!=last; ++element ) {
2582  if( !isDefault( element->value() ) )
2583  return false;
2584  }
2585  }
2586 
2587  return true;
2588 }
2589 //*************************************************************************************************
2590 
2591 
2592 //*************************************************************************************************
2604 template< typename MT // Type of the dense matrix
2605  , bool AF // Alignment flag
2606  , bool SO > // Storage order
2607 template< typename MT2 // Type of the left-hand side dense matrix
2608  , bool SO2 // Storage order of the left-hand side dense matrix
2609  , typename MT3 > // Type of the right-hand side dense matrix
2610 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2612 {
2614 
2615  UNUSED_PARAMETER( lhs );
2616 
2617  if( column_ + 1UL >= row_ + m_ )
2618  return true;
2619 
2620  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
2621  ?( column_ - row_ )
2622  :( column_ - row_ + 1UL ) );
2623  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
2624 
2625  for( size_t i=ibegin; i<m_; ++i )
2626  {
2627  const bool containsDiagonal( row_+i < column_+n_ );
2628 
2629  const size_t jpos( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
2630  ?( row_ + i - column_ + 1UL )
2631  :( row_ + i - column_ ) );
2632  const size_t jend( min( jpos, n_ ) );
2633 
2634  for( size_t j=0UL; j<jend; ++j ) {
2635  if( !isDefault( (~rhs)(i,j) ) )
2636  return false;
2637  }
2638 
2639  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
2640  return false;
2641  }
2642 
2643  return true;
2644 }
2645 //*************************************************************************************************
2646 
2647 
2648 //*************************************************************************************************
2660 template< typename MT // Type of the dense matrix
2661  , bool AF // Alignment flag
2662  , bool SO > // Storage order
2663 template< typename MT2 // Type of the left-hand side dense matrix
2664  , bool SO2 // Storage order of the left-hand side dense matrix
2665  , typename MT3 > // Type of the right-hand side dense matrix
2666 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2668 {
2670 
2671  UNUSED_PARAMETER( lhs );
2672 
2673  if( column_ + 1UL >= row_ + m_ )
2674  return true;
2675 
2676  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
2677  ?( row_ + m_ - column_ )
2678  :( row_ + m_ - column_ - 1UL ) );
2679  const size_t jend( min( jpos, n_ ) );
2680 
2681  for( size_t j=0UL; j<jend; ++j )
2682  {
2683  const bool containsDiagonal( column_+j >= row_ );
2684 
2685  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
2686  return false;
2687 
2688  const size_t ibegin( ( containsDiagonal )
2690  ?( column_ + j - row_ )
2691  :( column_ + j - row_ + 1UL ) )
2692  :( 0UL ) );
2693 
2694  for( size_t i=ibegin; i<m_; ++i ) {
2695  if( !isDefault( (~rhs)(i,j) ) )
2696  return false;
2697  }
2698  }
2699 
2700  return true;
2701 }
2702 //*************************************************************************************************
2703 
2704 
2705 //*************************************************************************************************
2717 template< typename MT // Type of the dense matrix
2718  , bool AF // Alignment flag
2719  , bool SO > // Storage order
2720 template< typename MT2 // Type of the left-hand side dense matrix
2721  , bool SO2 // Storage order of the left-hand side dense matrix
2722  , typename MT3 > // Type of the right-hand side sparse matrix
2723 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2725 {
2727 
2728  UNUSED_PARAMETER( lhs );
2729 
2730  typedef typename MT3::ConstIterator RhsIterator;
2731 
2732  if( column_ + 1UL >= row_ + m_ )
2733  return true;
2734 
2735  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
2736  ?( column_ - row_ )
2737  :( column_ - row_ + 1UL ) );
2738  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
2739 
2740  for( size_t i=ibegin; i<m_; ++i )
2741  {
2742  const bool containsDiagonal( row_+i < column_+n_ );
2743 
2744  const size_t index( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
2745  ?( row_ + i - column_ + 1UL )
2746  :( row_ + i - column_ ) );
2747  const RhsIterator last( (~rhs).lowerBound( i, min( index, n_ ) ) );
2748 
2749  if( IsUniUpper<MT2>::value && containsDiagonal &&
2750  ( last == (~rhs).end(i) || ( last->index() != row_+i-column_ ) || !isOne( last->value() ) ) ) {
2751  return false;
2752  }
2753 
2754  for( RhsIterator element=(~rhs).begin(i); element!=last; ++element ) {
2755  if( !isDefault( element->value() ) )
2756  return false;
2757  }
2758  }
2759 
2760  return true;
2761 }
2762 //*************************************************************************************************
2763 
2764 
2765 //*************************************************************************************************
2777 template< typename MT // Type of the dense matrix
2778  , bool AF // Alignment flag
2779  , bool SO > // Storage order
2780 template< typename MT2 // Type of the left-hand side dense matrix
2781  , bool SO2 // Storage order of the left-hand side dense matrix
2782  , typename MT3 > // Type of the right-hand side sparse matrix
2783 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2785 {
2787 
2788  UNUSED_PARAMETER( lhs );
2789 
2790  typedef typename MT3::ConstIterator RhsIterator;
2791 
2792  if( column_ + 1UL >= row_ + m_ )
2793  return true;
2794 
2795  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
2796  ?( row_ + m_ - column_ )
2797  :( row_ + m_ - column_ - 1UL ) );
2798  const size_t jend( min( jpos, n_ ) );
2799 
2800  for( size_t j=0UL; j<jend; ++j )
2801  {
2802  const bool containsDiagonal( column_+j >= row_ );
2803 
2804  const size_t index( ( containsDiagonal )
2806  ?( column_ + j - row_ )
2807  :( column_ + j - row_ + 1UL ) )
2808  :( 0UL ) );
2809 
2810  const RhsIterator last( (~rhs).end(j) );
2811  RhsIterator element( (~rhs).lowerBound( index, j ) );
2812 
2813  if( IsUniUpper<MT2>::value && containsDiagonal ) {
2814  if( element == last || ( element->index() != column_+j-row_ ) || !isOne( element->value() ) )
2815  return false;
2816  ++element;
2817  }
2818 
2819  for( ; element!=last; ++element ) {
2820  if( !isDefault( element->value() ) )
2821  return false;
2822  }
2823  }
2824 
2825  return true;
2826 }
2827 //*************************************************************************************************
2828 
2829 
2830 //*************************************************************************************************
2841 template< typename MT // Type of the dense matrix
2842  , bool AF // Alignment flag
2843  , bool SO > // Storage order
2844 template< typename MT2 // Type of the left-hand side dense matrix
2845  , bool SO2 // Storage order of the left-hand side dense matrix
2846  , typename MT3 > // Type of the right-hand side dense matrix
2847 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2849 {
2851 
2852  UNUSED_PARAMETER( lhs );
2853 
2854  for( size_t i=0UL; i<m_; ++i ) {
2855  for( size_t j=0UL; j<n_; ++j ) {
2856  if( ( row_ + i != column_ + j ) && !isDefault( (~rhs)(i,j) ) )
2857  return false;
2858  }
2859  }
2860 
2861  return true;
2862 }
2863 //*************************************************************************************************
2864 
2865 
2866 //*************************************************************************************************
2877 template< typename MT // Type of the dense matrix
2878  , bool AF // Alignment flag
2879  , bool SO > // Storage order
2880 template< typename MT2 // Type of the left-hand side dense matrix
2881  , bool SO2 // Storage order of the left-hand side dense matrix
2882  , typename MT3 > // Type of the right-hand side dense matrix
2883 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2885 {
2887 
2888  UNUSED_PARAMETER( lhs );
2889 
2890  for( size_t j=0UL; j<n_; ++j ) {
2891  for( size_t i=0UL; i<m_; ++i ) {
2892  if( ( column_ + j != row_ + i ) && !isDefault( (~rhs)(i,j) ) )
2893  return false;
2894  }
2895  }
2896 
2897  return true;
2898 }
2899 //*************************************************************************************************
2900 
2901 
2902 //*************************************************************************************************
2913 template< typename MT // Type of the dense matrix
2914  , bool AF // Alignment flag
2915  , bool SO > // Storage order
2916 template< typename MT2 // Type of the left-hand side dense matrix
2917  , bool SO2 // Storage order of the left-hand side dense matrix
2918  , typename MT3 > // Type of the right-hand side sparse matrix
2919 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2921 {
2923 
2924  UNUSED_PARAMETER( lhs );
2925 
2926  typedef typename MT3::ConstIterator RhsIterator;
2927 
2928  for( size_t i=0UL; i<m_; ++i ) {
2929  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
2930  if( ( row_ + i != column_ + element->index() ) && !isDefault( element->value() ) )
2931  return false;
2932  }
2933  }
2934 
2935  return true;
2936 }
2937 //*************************************************************************************************
2938 
2939 
2940 //*************************************************************************************************
2951 template< typename MT // Type of the dense matrix
2952  , bool AF // Alignment flag
2953  , bool SO > // Storage order
2954 template< typename MT2 // Type of the left-hand side dense matrix
2955  , bool SO2 // Storage order of the left-hand side dense matrix
2956  , typename MT3 > // Type of the right-hand side sparse matrix
2957 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2959 {
2961 
2962  UNUSED_PARAMETER( lhs );
2963 
2964  typedef typename MT3::ConstIterator RhsIterator;
2965 
2966  for( size_t j=0UL; j<n_; ++j ) {
2967  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
2968  if( ( column_ + j != row_ + element->index() ) && !isDefault( element->value() ) )
2969  return false;
2970  }
2971  }
2972 
2973  return true;
2974 }
2975 //*************************************************************************************************
2976 
2977 
2978 
2979 
2980 //=================================================================================================
2981 //
2982 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2983 //
2984 //=================================================================================================
2985 
2986 //*************************************************************************************************
2996 template< typename MT // Type of the dense matrix
2997  , bool AF // Alignment flag
2998  , bool SO > // Storage order
2999 template< typename Other > // Data type of the foreign expression
3000 inline bool DenseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
3001 {
3002  return matrix_.isAliased( alias );
3003 }
3004 //*************************************************************************************************
3005 
3006 
3007 //*************************************************************************************************
3017 template< typename MT // Type of the dense matrix
3018  , bool AF // Alignment flag
3019  , bool SO > // Storage order
3020 template< typename MT2 // Data type of the foreign dense submatrix
3021  , bool AF2 // Alignment flag of the foreign dense submatrix
3022  , bool SO2 > // Storage order of the foreign dense submatrix
3024 {
3025  return ( matrix_.isAliased( &alias->matrix_ ) &&
3026  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
3027  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
3028 }
3029 //*************************************************************************************************
3030 
3031 
3032 //*************************************************************************************************
3042 template< typename MT // Type of the dense matrix
3043  , bool AF // Alignment flag
3044  , bool SO > // Storage order
3045 template< typename Other > // Data type of the foreign expression
3046 inline bool DenseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
3047 {
3048  return matrix_.isAliased( alias );
3049 }
3050 //*************************************************************************************************
3051 
3052 
3053 //*************************************************************************************************
3063 template< typename MT // Type of the dense matrix
3064  , bool AF // Alignment flag
3065  , bool SO > // Storage order
3066 template< typename MT2 // Data type of the foreign dense submatrix
3067  , bool AF2 // Alignment flag of the foreign dense submatrix
3068  , bool SO2 > // Storage order of the foreign dense submatrix
3070 {
3071  return ( matrix_.isAliased( &alias->matrix_ ) &&
3072  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
3073  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
3074 }
3075 //*************************************************************************************************
3076 
3077 
3078 //*************************************************************************************************
3087 template< typename MT // Type of the dense matrix
3088  , bool AF // Alignment flag
3089  , bool SO > // Storage order
3091 {
3092  return isAligned_;
3093 }
3094 //*************************************************************************************************
3095 
3096 
3097 //*************************************************************************************************
3107 template< typename MT // Type of the dense matrix
3108  , bool AF // Alignment flag
3109  , bool SO > // Storage order
3111 {
3112  return ( rows() > SMP_DMATASSIGN_THRESHOLD );
3113 }
3114 //*************************************************************************************************
3115 
3116 
3117 //*************************************************************************************************
3133 template< typename MT // Type of the dense matrix
3134  , bool AF // Alignment flag
3135  , bool SO > // Storage order
3137  DenseSubmatrix<MT,AF,SO>::load( size_t i, size_t j ) const
3138 {
3139  return loadu( i, j );
3140 }
3141 //*************************************************************************************************
3142 
3143 
3144 //*************************************************************************************************
3160 template< typename MT // Type of the dense matrix
3161  , bool AF // Alignment flag
3162  , bool SO > // Storage order
3164  DenseSubmatrix<MT,AF,SO>::loadu( size_t i, size_t j ) const
3165 {
3166  using blaze::load;
3167 
3169 
3170  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
3171  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
3172  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
3173 
3174  if( isAligned_ ) {
3175  return matrix_.load( row_+i, column_+j );
3176  }
3177  else if( j != final_ ) {
3178  return matrix_.loadu( row_+i, column_+j );
3179  }
3180  else {
3182  for( size_t k=0UL; k<rest_; ++k )
3183  array[k] = matrix_(row_+i,column_+j+k);
3184  for( size_t k=rest_; k<IT::size; ++k )
3185  array[k] = ElementType();
3186  return load( array.data() );
3187  }
3188 }
3189 //*************************************************************************************************
3190 
3191 
3192 //*************************************************************************************************
3208 template< typename MT // Type of the dense matrix
3209  , bool AF // Alignment flag
3210  , bool SO > // Storage order
3211 inline void DenseSubmatrix<MT,AF,SO>::store( size_t i, size_t j, const IntrinsicType& value )
3212 {
3213  storeu( i, j, value );
3214 }
3215 //*************************************************************************************************
3216 
3217 
3218 //*************************************************************************************************
3234 template< typename MT // Type of the dense matrix
3235  , bool AF // Alignment flag
3236  , bool SO > // Storage order
3237 inline void DenseSubmatrix<MT,AF,SO>::storeu( size_t i, size_t j, const IntrinsicType& value )
3238 {
3239  using blaze::store;
3240 
3242 
3243  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
3244  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
3245  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
3246 
3247  if( isAligned_ ) {
3248  matrix_.store( row_+i, column_+j, value );
3249  }
3250  else if( j != final_ ) {
3251  matrix_.storeu( row_+i, column_+j, value );
3252  }
3253  else {
3255  store( array.data(), value );
3256  for( size_t k=0UL; k<rest_; ++k )
3257  matrix_(row_+i,column_+j+k) = array[k];
3258  }
3259 }
3260 //*************************************************************************************************
3261 
3262 
3263 //*************************************************************************************************
3280 template< typename MT // Type of the dense matrix
3281  , bool AF // Alignment flag
3282  , bool SO > // Storage order
3283 inline void DenseSubmatrix<MT,AF,SO>::stream( size_t i, size_t j, const IntrinsicType& value )
3284 {
3285  storeu( i, j, value );
3286 }
3287 //*************************************************************************************************
3288 
3289 
3290 //*************************************************************************************************
3301 template< typename MT // Type of the dense matrix
3302  , bool AF // Alignment flag
3303  , bool SO > // Storage order
3304 template< typename MT2 > // Type of the right-hand side dense matrix
3305 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
3307 {
3309 
3310  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3311  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3312 
3313  const size_t jpos( n_ & size_t(-2) );
3314  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
3315 
3316  for( size_t i=0UL; i<m_; ++i ) {
3317  for( size_t j=0UL; j<jpos; j+=2UL ) {
3318  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
3319  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
3320  }
3321  if( jpos < n_ ) {
3322  matrix_(row_+i,column_+jpos) = (~rhs)(i,jpos);
3323  }
3324  }
3325 }
3326 //*************************************************************************************************
3327 
3328 
3329 //*************************************************************************************************
3340 template< typename MT // Type of the dense matrix
3341  , bool AF // Alignment flag
3342  , bool SO > // Storage order
3343 template< typename MT2 > // Type of the right-hand side dense matrix
3344 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
3346 {
3349 
3350  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3351  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3352 
3353  if( useStreaming && isAligned_ &&
3354  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
3355  !(~rhs).isAliased( &matrix_ ) )
3356  {
3357  for( size_t i=0UL; i<m_; ++i )
3358  for( size_t j=0UL; j<n_; j+=IT::size )
3359  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
3360  }
3361  else
3362  {
3363  const size_t jpos( n_ & size_t(-IT::size*4) );
3364  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jpos, "Invalid end calculation" );
3365 
3366  for( size_t i=0UL; i<m_; ++i ) {
3367  typename MT2::ConstIterator it( (~rhs).begin(i) );
3368  for( size_t j=0UL; j<jpos; j+=IT::size*4UL ) {
3369  matrix_.storeu( row_+i, column_+j , it.load() ); it += IT::size;
3370  matrix_.storeu( row_+i, column_+j+IT::size , it.load() ); it += IT::size;
3371  matrix_.storeu( row_+i, column_+j+IT::size*2UL, it.load() ); it += IT::size;
3372  matrix_.storeu( row_+i, column_+j+IT::size*3UL, it.load() ); it += IT::size;
3373  }
3374  for( size_t j=jpos; j<n_; j+=IT::size, it+=IT::size ) {
3375  storeu( i, j, it.load() );
3376  }
3377  }
3378  }
3379 }
3380 //*************************************************************************************************
3381 
3382 
3383 //*************************************************************************************************
3394 template< typename MT // Type of the dense matrix
3395  , bool AF // Alignment flag
3396  , bool SO > // Storage order
3397 template< typename MT2 > // Type of the right-hand side dense matrix
3399 {
3402 
3403  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3404  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3405 
3406  const size_t block( 16UL );
3407 
3408  for( size_t ii=0UL; ii<m_; ii+=block ) {
3409  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3410  for( size_t jj=0UL; jj<n_; jj+=block ) {
3411  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3412  for( size_t i=ii; i<iend; ++i ) {
3413  for( size_t j=jj; j<jend; ++j ) {
3414  matrix_(row_+i,column_+j) = (~rhs)(i,j);
3415  }
3416  }
3417  }
3418  }
3419 }
3420 //*************************************************************************************************
3421 
3422 
3423 //*************************************************************************************************
3434 template< typename MT // Type of the dense matrix
3435  , bool AF // Alignment flag
3436  , bool SO > // Storage order
3437 template< typename MT2 > // Type of the right-hand side sparse matrix
3439 {
3441 
3442  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3443  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3444 
3445  for( size_t i=0UL; i<m_; ++i )
3446  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3447  matrix_(row_+i,column_+element->index()) = element->value();
3448 }
3449 //*************************************************************************************************
3450 
3451 
3452 //*************************************************************************************************
3463 template< typename MT // Type of the dense matrix
3464  , bool AF // Alignment flag
3465  , bool SO > // Storage order
3466 template< typename MT2 > // Type of the right-hand side sparse matrix
3468 {
3471 
3472  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3473  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3474 
3475  for( size_t j=0UL; j<n_; ++j )
3476  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3477  matrix_(row_+element->index(),column_+j) = element->value();
3478 }
3479 //*************************************************************************************************
3480 
3481 
3482 //*************************************************************************************************
3493 template< typename MT // Type of the dense matrix
3494  , bool AF // Alignment flag
3495  , bool SO > // Storage order
3496 template< typename MT2 > // Type of the right-hand side dense matrix
3497 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
3499 {
3501 
3502  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3503  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3504 
3505  const size_t jpos( n_ & size_t(-2) );
3506  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
3507 
3508  for( size_t i=0UL; i<m_; ++i ) {
3509  for( size_t j=0UL; j<jpos; j+=2UL ) {
3510  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
3511  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
3512  }
3513  if( jpos < n_ ) {
3514  matrix_(row_+i,column_+jpos) += (~rhs)(i,jpos);
3515  }
3516  }
3517 }
3518 //*************************************************************************************************
3519 
3520 
3521 //*************************************************************************************************
3532 template< typename MT // Type of the dense matrix
3533  , bool AF // Alignment flag
3534  , bool SO > // Storage order
3535 template< typename MT2 > // Type of the right-hand side dense matrix
3536 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
3538 {
3541 
3542  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3543  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3544 
3545  const size_t jpos( n_ & size_t(-IT::size*4) );
3546  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jpos, "Invalid end calculation" );
3547 
3548  for( size_t i=0UL; i<m_; ++i ) {
3549  typename MT2::ConstIterator it( (~rhs).begin(i) );
3550  for( size_t j=0UL; j<jpos; j+=IT::size*4UL ) {
3551  matrix_.storeu( row_+i, column_+j , load(i,j ) + it.load() ); it += IT::size;
3552  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
3553  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
3554  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
3555  }
3556  for( size_t j=jpos; j<n_; j+=IT::size, it+=IT::size ) {
3557  storeu( i, j, load(i,j) + it.load() );
3558  }
3559  }
3560 }
3561 //*************************************************************************************************
3562 
3563 
3564 //*************************************************************************************************
3575 template< typename MT // Type of the dense matrix
3576  , bool AF // Alignment flag
3577  , bool SO > // Storage order
3578 template< typename MT2 > // Type of the right-hand side dense matrix
3580 {
3583 
3584  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3585  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3586 
3587  const size_t block( 16UL );
3588 
3589  for( size_t ii=0UL; ii<m_; ii+=block ) {
3590  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3591  for( size_t jj=0UL; jj<n_; jj+=block ) {
3592  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3593  for( size_t i=ii; i<iend; ++i ) {
3594  for( size_t j=jj; j<jend; ++j ) {
3595  matrix_(row_+i,column_+j) += (~rhs)(i,j);
3596  }
3597  }
3598  }
3599  }
3600 }
3601 //*************************************************************************************************
3602 
3603 
3604 //*************************************************************************************************
3615 template< typename MT // Type of the dense matrix
3616  , bool AF // Alignment flag
3617  , bool SO > // Storage order
3618 template< typename MT2 > // Type of the right-hand side sparse matrix
3620 {
3622 
3623  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3624  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3625 
3626  for( size_t i=0UL; i<m_; ++i )
3627  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3628  matrix_(row_+i,column_+element->index()) += element->value();
3629 }
3630 //*************************************************************************************************
3631 
3632 
3633 //*************************************************************************************************
3644 template< typename MT // Type of the dense matrix
3645  , bool AF // Alignment flag
3646  , bool SO > // Storage order
3647 template< typename MT2 > // Type of the right-hand side sparse matrix
3649 {
3652 
3653  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3654  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3655 
3656  for( size_t j=0UL; j<n_; ++j )
3657  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3658  matrix_(row_+element->index(),column_+j) += element->value();
3659 }
3660 //*************************************************************************************************
3661 
3662 
3663 //*************************************************************************************************
3674 template< typename MT // Type of the dense matrix
3675  , bool AF // Alignment flag
3676  , bool SO > // Storage order
3677 template< typename MT2 > // Type of the right-hand side dense matrix
3678 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
3680 {
3682 
3683  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3684  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3685 
3686  const size_t jpos( n_ & size_t(-2) );
3687  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
3688 
3689  for( size_t i=0UL; i<m_; ++i ) {
3690  for( size_t j=0UL; j<jpos; j+=2UL ) {
3691  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
3692  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
3693  }
3694  if( jpos < n_ ) {
3695  matrix_(row_+i,column_+jpos) -= (~rhs)(i,jpos);
3696  }
3697  }
3698 }
3699 //*************************************************************************************************
3700 
3701 
3702 //*************************************************************************************************
3713 template< typename MT // Type of the dense matrix
3714  , bool AF // Alignment flag
3715  , bool SO > // Storage order
3716 template< typename MT2 > // Type of the right-hand side dense matrix
3717 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
3719 {
3722 
3723  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3724  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3725 
3726  const size_t jpos( n_ & size_t(-IT::size*4) );
3727  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jpos, "Invalid end calculation" );
3728 
3729  for( size_t i=0UL; i<m_; ++i ) {
3730  typename MT2::ConstIterator it( (~rhs).begin(i) );
3731  for( size_t j=0UL; j<jpos; j+=IT::size*4UL ) {
3732  matrix_.storeu( row_+i, column_+j , load(i,j ) - it.load() ); it += IT::size;
3733  matrix_.storeu( row_+i, column_+j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
3734  matrix_.storeu( row_+i, column_+j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
3735  matrix_.storeu( row_+i, column_+j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
3736  }
3737  for( size_t j=jpos; j<n_; j+=IT::size, it+=IT::size ) {
3738  storeu( i, j, load(i,j) - it.load() );
3739  }
3740  }
3741 }
3742 //*************************************************************************************************
3743 
3744 
3745 //*************************************************************************************************
3756 template< typename MT // Type of the dense matrix
3757  , bool AF // Alignment flag
3758  , bool SO > // Storage order
3759 template< typename MT2 > // Type of the right-hand side dense matrix
3761 {
3764 
3765  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3766  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3767 
3768  const size_t block( 16UL );
3769 
3770  for( size_t ii=0UL; ii<m_; ii+=block ) {
3771  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3772  for( size_t jj=0UL; jj<n_; jj+=block ) {
3773  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3774  for( size_t i=ii; i<iend; ++i ) {
3775  for( size_t j=jj; j<jend; ++j ) {
3776  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
3777  }
3778  }
3779  }
3780  }
3781 }
3782 //*************************************************************************************************
3783 
3784 
3785 //*************************************************************************************************
3796 template< typename MT // Type of the dense matrix
3797  , bool AF // Alignment flag
3798  , bool SO > // Storage order
3799 template< typename MT2 > // Type of the right-hand side sparse matrix
3801 {
3803 
3804  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3805  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3806 
3807  for( size_t i=0UL; i<m_; ++i )
3808  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3809  matrix_(row_+i,column_+element->index()) -= element->value();
3810 }
3811 //*************************************************************************************************
3812 
3813 
3814 //*************************************************************************************************
3825 template< typename MT // Type of the dense matrix
3826  , bool AF // Alignment flag
3827  , bool SO > // Storage order
3828 template< typename MT2 > // Type of the right-hand side sparse matrix
3830 {
3833 
3834  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3835  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3836 
3837  for( size_t j=0UL; j<n_; ++j )
3838  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3839  matrix_(row_+element->index(),column_+j) -= element->value();
3840 }
3841 //*************************************************************************************************
3842 
3843 
3844 
3845 
3846 
3847 
3848 
3849 
3850 //=================================================================================================
3851 //
3852 // CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED COLUMN-MAJOR MATRICES
3853 //
3854 //=================================================================================================
3855 
3856 //*************************************************************************************************
3864 template< typename MT > // Type of the dense matrix
3865 class DenseSubmatrix<MT,unaligned,true> : public DenseMatrix< DenseSubmatrix<MT,unaligned,true>, true >
3866  , private Submatrix
3867 {
3868  private:
3869  //**Type definitions****************************************************************************
3871  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
3872 
3875  //**********************************************************************************************
3876 
3877  //**********************************************************************************************
3879 
3885  enum { useConst = IsConst<MT>::value };
3886  //**********************************************************************************************
3887 
3888  public:
3889  //**Type definitions****************************************************************************
3890  typedef DenseSubmatrix<MT,unaligned,true> This;
3891  typedef typename SubmatrixTrait<MT>::Type ResultType;
3892  typedef typename ResultType::OppositeType OppositeType;
3893  typedef typename ResultType::TransposeType TransposeType;
3894  typedef typename MT::ElementType ElementType;
3895  typedef typename IT::Type IntrinsicType;
3896  typedef typename MT::ReturnType ReturnType;
3897  typedef const DenseSubmatrix& CompositeType;
3898 
3900  typedef typename MT::ConstReference ConstReference;
3901 
3903  typedef typename IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference;
3904 
3906  typedef const ElementType* ConstPointer;
3907 
3909  typedef typename IfTrue< useConst, ConstPointer, ElementType* >::Type Pointer;
3910  //**********************************************************************************************
3911 
3912  //**SubmatrixIterator class definition**********************************************************
3915  template< typename IteratorType > // Type of the dense matrix iterator
3916  class SubmatrixIterator
3917  {
3918  public:
3919  //**Type definitions*************************************************************************
3921  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
3922 
3924  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
3925 
3927  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
3928 
3930  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
3931 
3933  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
3934 
3935  // STL iterator requirements
3936  typedef IteratorCategory iterator_category;
3937  typedef ValueType value_type;
3938  typedef PointerType pointer;
3939  typedef ReferenceType reference;
3940  typedef DifferenceType difference_type;
3941  //*******************************************************************************************
3942 
3943  //**Constructor******************************************************************************
3946  inline SubmatrixIterator()
3947  : iterator_ ( ) // Iterator to the current submatrix element
3948  , final_ ( 0UL ) // The final iterator for intrinsic operations
3949  , rest_ ( 0UL ) // The number of remaining elements beyond the final iterator
3950  , isAligned_( false ) // Memory alignment flag
3951  {}
3952  //*******************************************************************************************
3953 
3954  //**Constructor******************************************************************************
3962  inline SubmatrixIterator( IteratorType iterator, IteratorType finalIterator,
3963  size_t remainingElements, bool isMemoryAligned )
3964  : iterator_ ( iterator ) // Iterator to the current submatrix element
3965  , final_ ( finalIterator ) // The final iterator for intrinsic operations
3966  , rest_ ( remainingElements ) // The number of remaining elements beyond the final iterator
3967  , isAligned_( isMemoryAligned ) // Memory alignment flag
3968  {}
3969  //*******************************************************************************************
3970 
3971  //**Constructor******************************************************************************
3976  template< typename IteratorType2 >
3977  inline SubmatrixIterator( const SubmatrixIterator<IteratorType2>& it )
3978  : iterator_ ( it.base() ) // Iterator to the current submatrix element
3979  , final_ ( it.final() ) // The final iterator for intrinsic operations
3980  , rest_ ( it.rest() ) // The number of remaining elements beyond the final iterator
3981  , isAligned_( it.isAligned() ) // Memory alignment flag
3982  {}
3983  //*******************************************************************************************
3984 
3985  //**Addition assignment operator*************************************************************
3991  inline SubmatrixIterator& operator+=( size_t inc ) {
3992  iterator_ += inc;
3993  return *this;
3994  }
3995  //*******************************************************************************************
3996 
3997  //**Subtraction assignment operator**********************************************************
4003  inline SubmatrixIterator& operator-=( size_t dec ) {
4004  iterator_ -= dec;
4005  return *this;
4006  }
4007  //*******************************************************************************************
4008 
4009  //**Prefix increment operator****************************************************************
4014  inline SubmatrixIterator& operator++() {
4015  ++iterator_;
4016  return *this;
4017  }
4018  //*******************************************************************************************
4019 
4020  //**Postfix increment operator***************************************************************
4025  inline const SubmatrixIterator operator++( int ) {
4027  }
4028  //*******************************************************************************************
4029 
4030  //**Prefix decrement operator****************************************************************
4035  inline SubmatrixIterator& operator--() {
4036  --iterator_;
4037  return *this;
4038  }
4039  //*******************************************************************************************
4040 
4041  //**Postfix decrement operator***************************************************************
4046  inline const SubmatrixIterator operator--( int ) {
4048  }
4049  //*******************************************************************************************
4050 
4051  //**Element access operator******************************************************************
4056  inline ReferenceType operator*() const {
4057  return *iterator_;
4058  }
4059  //*******************************************************************************************
4060 
4061  //**Load function****************************************************************************
4071  inline IntrinsicType load() const {
4072  return loadu();
4073  }
4074  //*******************************************************************************************
4075 
4076  //**Loadu function***************************************************************************
4086  inline IntrinsicType loadu() const {
4087  if( isAligned_ ) {
4088  return iterator_.load();
4089  }
4090  else if( iterator_ != final_ ) {
4091  return iterator_.loadu();
4092  }
4093  else {
4094  AlignedArray<ElementType,IT::size> array;
4095  for( size_t i=0UL; i<rest_; ++i )
4096  array[i] = *(iterator_+i);
4097  for( size_t i=rest_; i<IT::size; ++i )
4098  array[i] = ElementType();
4099  return blaze::load( array.data() );
4100  }
4101  }
4102  //*******************************************************************************************
4103 
4104  //**Equality operator************************************************************************
4110  inline bool operator==( const SubmatrixIterator& rhs ) const {
4111  return iterator_ == rhs.iterator_;
4112  }
4113  //*******************************************************************************************
4114 
4115  //**Inequality operator**********************************************************************
4121  inline bool operator!=( const SubmatrixIterator& rhs ) const {
4122  return iterator_ != rhs.iterator_;
4123  }
4124  //*******************************************************************************************
4125 
4126  //**Less-than operator***********************************************************************
4132  inline bool operator<( const SubmatrixIterator& rhs ) const {
4133  return iterator_ < rhs.iterator_;
4134  }
4135  //*******************************************************************************************
4136 
4137  //**Greater-than operator********************************************************************
4143  inline bool operator>( const SubmatrixIterator& rhs ) const {
4144  return iterator_ > rhs.iterator_;
4145  }
4146  //*******************************************************************************************
4147 
4148  //**Less-or-equal-than operator**************************************************************
4154  inline bool operator<=( const SubmatrixIterator& rhs ) const {
4155  return iterator_ <= rhs.iterator_;
4156  }
4157  //*******************************************************************************************
4158 
4159  //**Greater-or-equal-than operator***********************************************************
4165  inline bool operator>=( const SubmatrixIterator& rhs ) const {
4166  return iterator_ >= rhs.iterator_;
4167  }
4168  //*******************************************************************************************
4169 
4170  //**Subtraction operator*********************************************************************
4176  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
4177  return iterator_ - rhs.iterator_;
4178  }
4179  //*******************************************************************************************
4180 
4181  //**Addition operator************************************************************************
4188  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
4189  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
4190  }
4191  //*******************************************************************************************
4192 
4193  //**Addition operator************************************************************************
4200  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
4201  return SubmatrixIterator( it.iterator_ + inc, it.final_, it.rest_, it.isAligned_ );
4202  }
4203  //*******************************************************************************************
4204 
4205  //**Subtraction operator*********************************************************************
4212  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
4213  return SubmatrixIterator( it.iterator_ - dec, it.final_, it.rest_, it.isAligned_ );
4214  }
4215  //*******************************************************************************************
4216 
4217  //**Base function****************************************************************************
4222  inline IteratorType base() const {
4223  return iterator_;
4224  }
4225  //*******************************************************************************************
4226 
4227  //**Final function***************************************************************************
4232  inline IteratorType final() const {
4233  return final_;
4234  }
4235  //*******************************************************************************************
4236 
4237  //**Rest function****************************************************************************
4242  inline size_t rest() const {
4243  return rest_;
4244  }
4245  //*******************************************************************************************
4246 
4247  //**IsAligned function***********************************************************************
4252  inline bool isAligned() const {
4253  return isAligned_;
4254  }
4255  //*******************************************************************************************
4256 
4257  private:
4258  //**Member variables*************************************************************************
4259  IteratorType iterator_;
4260  IteratorType final_;
4261  size_t rest_;
4262  bool isAligned_;
4263  //*******************************************************************************************
4264  };
4265  //**********************************************************************************************
4266 
4267  //**Type definitions****************************************************************************
4269  typedef SubmatrixIterator<typename MT::ConstIterator> ConstIterator;
4270 
4272  typedef typename IfTrue< useConst, ConstIterator, SubmatrixIterator<typename MT::Iterator> >::Type Iterator;
4273  //**********************************************************************************************
4274 
4275  //**Compilation flags***************************************************************************
4277  enum { vectorizable = MT::vectorizable };
4278 
4280  enum { smpAssignable = MT::smpAssignable };
4281  //**********************************************************************************************
4282 
4283  //**Constructors********************************************************************************
4286  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
4287  // No explicitly declared copy constructor.
4289  //**********************************************************************************************
4290 
4291  //**Destructor**********************************************************************************
4292  // No explicitly declared destructor.
4293  //**********************************************************************************************
4294 
4295  //**Data access functions***********************************************************************
4298  inline Reference operator()( size_t i, size_t j );
4299  inline ConstReference operator()( size_t i, size_t j ) const;
4300  inline Pointer data ();
4301  inline ConstPointer data () const;
4302  inline Iterator begin ( size_t i );
4303  inline ConstIterator begin ( size_t i ) const;
4304  inline ConstIterator cbegin( size_t i ) const;
4305  inline Iterator end ( size_t i );
4306  inline ConstIterator end ( size_t i ) const;
4307  inline ConstIterator cend ( size_t i ) const;
4309  //**********************************************************************************************
4310 
4311  //**Assignment operators************************************************************************
4314  inline DenseSubmatrix& operator=( const ElementType& rhs );
4315  inline DenseSubmatrix& operator=( const DenseSubmatrix& rhs );
4316 
4317  template< typename MT2, bool SO >
4318  inline DenseSubmatrix& operator=( const Matrix<MT2,SO>& rhs );
4319 
4320  template< typename MT2, bool SO >
4321  inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
4322  operator+=( const Matrix<MT2,SO>& rhs );
4323 
4324  template< typename MT2, bool SO >
4325  inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
4326  operator+=( const Matrix<MT2,SO>& rhs );
4327 
4328  template< typename MT2, bool SO >
4329  inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
4330  operator-=( const Matrix<MT2,SO>& rhs );
4331 
4332  template< typename MT2, bool SO >
4333  inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
4334  operator-=( const Matrix<MT2,SO>& rhs );
4335 
4336  template< typename MT2, bool SO >
4337  inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
4338 
4339  template< typename Other >
4340  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
4341  operator*=( Other rhs );
4342 
4343  template< typename Other >
4344  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
4345  operator/=( Other rhs );
4347  //**********************************************************************************************
4348 
4349  //**Utility functions***************************************************************************
4352  inline size_t rows() const;
4353  inline size_t columns() const;
4354  inline size_t spacing() const;
4355  inline size_t capacity() const;
4356  inline size_t capacity( size_t i ) const;
4357  inline size_t nonZeros() const;
4358  inline size_t nonZeros( size_t i ) const;
4359  inline void reset();
4360  inline void reset( size_t i );
4361  inline DenseSubmatrix& transpose();
4362  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
4364  //**********************************************************************************************
4365 
4366  private:
4367  //**********************************************************************************************
4369  template< typename MT2 >
4370  struct VectorizedAssign {
4371  enum { value = vectorizable && MT2::vectorizable &&
4372  IsSame<ElementType,typename MT2::ElementType>::value };
4373  };
4374  //**********************************************************************************************
4375 
4376  //**********************************************************************************************
4378  template< typename MT2 >
4379  struct VectorizedAddAssign {
4380  enum { value = vectorizable && MT2::vectorizable &&
4381  IsSame<ElementType,typename MT2::ElementType>::value &&
4382  IntrinsicTrait<ElementType>::addition };
4383  };
4384  //**********************************************************************************************
4385 
4386  //**********************************************************************************************
4388  template< typename MT2 >
4389  struct VectorizedSubAssign {
4390  enum { value = vectorizable && MT2::vectorizable &&
4391  IsSame<ElementType,typename MT2::ElementType>::value &&
4392  IntrinsicTrait<ElementType>::subtraction };
4393  };
4394  //**********************************************************************************************
4395 
4396  public:
4397  //**Expression template evaluation functions****************************************************
4400  template< typename Other >
4401  inline bool canAlias( const Other* alias ) const;
4402 
4403  template< typename MT2, bool AF2, bool SO2 >
4404  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
4405 
4406  template< typename Other >
4407  inline bool isAliased( const Other* alias ) const;
4408 
4409  template< typename MT2, bool AF2, bool SO2 >
4410  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
4411 
4412  inline bool isAligned () const;
4413  inline bool canSMPAssign() const;
4414 
4415  inline IntrinsicType load ( size_t i, size_t j ) const;
4416  inline IntrinsicType loadu( size_t i, size_t j ) const;
4417 
4418  inline void store ( size_t i, size_t j, const IntrinsicType& value );
4419  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
4420  inline void stream( size_t i, size_t j, const IntrinsicType& value );
4421 
4422  template< typename MT2 >
4423  inline typename DisableIf< VectorizedAssign<MT2> >::Type
4424  assign( const DenseMatrix<MT2,true>& rhs );
4425 
4426  template< typename MT2 >
4427  inline typename EnableIf< VectorizedAssign<MT2> >::Type
4428  assign( const DenseMatrix<MT2,true>& rhs );
4429 
4430  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
4431  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
4432  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
4433 
4434  template< typename MT2 >
4435  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
4436  addAssign( const DenseMatrix<MT2,true>& rhs );
4437 
4438  template< typename MT2 >
4439  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
4440  addAssign( const DenseMatrix<MT2,true>& rhs );
4441 
4442  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
4443  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
4444  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
4445 
4446  template< typename MT2 >
4447  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
4448  subAssign( const DenseMatrix<MT2,true>& rhs );
4449 
4450  template< typename MT2 >
4451  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
4452  subAssign( const DenseMatrix<MT2,true>& rhs );
4453 
4454  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
4455  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
4456  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
4458  //**********************************************************************************************
4459 
4460  private:
4461  //**Utility functions***************************************************************************
4464  inline bool hasOverlap() const;
4465 
4466  template< typename MT2, bool SO2, typename MT3, bool SO3 >
4467  inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
4468  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
4469 
4470  template< typename MT2, bool SO2, typename MT3, bool SO3 >
4471  inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4472  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
4473 
4474  template< typename MT2, bool SO2, typename MT3 >
4475  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4476  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
4477 
4478  template< typename MT2, bool SO2, typename MT3 >
4479  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4480  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
4481 
4482  template< typename MT2, bool SO2, typename MT3 >
4483  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4484  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
4485 
4486  template< typename MT2, bool SO2, typename MT3 >
4487  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4488  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
4489 
4490  template< typename MT2, bool SO2, typename MT3 >
4491  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4492  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
4493 
4494  template< typename MT2, bool SO2, typename MT3 >
4495  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4496  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
4497 
4498  template< typename MT2, bool SO2, typename MT3 >
4499  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4500  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
4501 
4502  template< typename MT2, bool SO2, typename MT3 >
4503  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4504  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
4505 
4506  template< typename MT2, bool SO2, typename MT3 >
4507  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4508  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
4509 
4510  template< typename MT2, bool SO2, typename MT3 >
4511  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4512  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
4513 
4514  template< typename MT2, bool SO2, typename MT3 >
4515  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4516  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
4517 
4518  template< typename MT2, bool SO2, typename MT3 >
4519  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4520  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
4522  //**********************************************************************************************
4523 
4524  //**Member variables****************************************************************************
4527  Operand matrix_;
4528  const size_t row_;
4529  const size_t column_;
4530  const size_t m_;
4531  const size_t n_;
4532  const size_t rest_;
4533  const size_t final_;
4534 
4538  const bool isAligned_;
4539 
4549  //**********************************************************************************************
4550 
4551  //**Friend declarations*************************************************************************
4552  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
4553 
4554  template< bool AF1, typename MT2, bool AF2, bool SO2 >
4555  friend const DenseSubmatrix<MT2,AF1,SO2>
4556  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
4557 
4558  template< typename MT2, bool AF2, bool SO2 >
4559  friend bool isSymmetric( const DenseSubmatrix<MT2,AF2,SO2>& dm );
4560 
4561  template< typename MT2, bool AF2, bool SO2 >
4562  friend bool isLower( const DenseSubmatrix<MT2,AF2,SO2>& dm );
4563 
4564  template< typename MT2, bool AF2, bool SO2 >
4565  friend bool isUpper( const DenseSubmatrix<MT2,AF2,SO2>& dm );
4566 
4567  template< typename MT2, bool AF2, bool SO2 >
4568  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
4569 
4570  template< typename MT2, bool AF2, bool SO2 >
4571  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
4572 
4573  template< typename MT2, bool AF2, bool SO2 >
4574  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
4575 
4576  template< typename MT2, bool AF2, bool SO2 >
4577  friend typename DerestrictTrait< DenseSubmatrix<MT2,AF2,SO2> >::Type
4578  derestrict( DenseSubmatrix<MT2,AF2,SO2>& dm );
4579  //**********************************************************************************************
4580 
4581  //**Compile time checks*************************************************************************
4589  BLAZE_STATIC_ASSERT( !IsRestricted<MT>::value || IsLower<MT>::value || IsUpper<MT>::value );
4590  //**********************************************************************************************
4591 };
4593 //*************************************************************************************************
4594 
4595 
4596 
4597 
4598 //=================================================================================================
4599 //
4600 // CONSTRUCTOR
4601 //
4602 //=================================================================================================
4603 
4604 //*************************************************************************************************
4618 template< typename MT > // Type of the dense matrix
4619 inline DenseSubmatrix<MT,unaligned,true>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
4620  : matrix_ ( matrix ) // The dense matrix containing the submatrix
4621  , row_ ( row ) // The first row of the submatrix
4622  , column_ ( column ) // The first column of the submatrix
4623  , m_ ( m ) // The number of rows of the submatrix
4624  , n_ ( n ) // The number of columns of the submatrix
4625  , rest_ ( m % IT::size ) // The number of remaining elements in an unaligned intrinsic operation
4626  , final_ ( m - rest_ ) // The final index for unaligned intrinsic operations
4627  , isAligned_( ( row % IT::size == 0UL ) &&
4628  ( row + m == matrix.rows() || m % IT::size == 0UL ) )
4629 {
4630  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
4631  throw std::invalid_argument( "Invalid submatrix specification" );
4632 }
4634 //*************************************************************************************************
4635 
4636 
4637 
4638 
4639 //=================================================================================================
4640 //
4641 // DATA ACCESS FUNCTIONS
4642 //
4643 //=================================================================================================
4644 
4645 //*************************************************************************************************
4653 template< typename MT > // Type of the dense matrix
4655  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j )
4656 {
4657  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4658  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4659 
4660  return matrix_(row_+i,column_+j);
4661 }
4663 //*************************************************************************************************
4664 
4665 
4666 //*************************************************************************************************
4674 template< typename MT > // Type of the dense matrix
4676  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j ) const
4677 {
4678  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4679  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4680 
4681  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
4682 }
4684 //*************************************************************************************************
4685 
4686 
4687 //*************************************************************************************************
4697 template< typename MT > // Type of the dense matrix
4698 inline typename DenseSubmatrix<MT,unaligned,true>::Pointer DenseSubmatrix<MT,unaligned,true>::data()
4699 {
4700  return matrix_.data() + row_ + column_*spacing();
4701 }
4703 //*************************************************************************************************
4704 
4705 
4706 //*************************************************************************************************
4716 template< typename MT > // Type of the dense matrix
4717 inline typename DenseSubmatrix<MT,unaligned,true>::ConstPointer
4719 {
4720  return matrix_.data() + row_ + column_*spacing();
4721 }
4723 //*************************************************************************************************
4724 
4725 
4726 //*************************************************************************************************
4733 template< typename MT > // Type of the dense matrix
4736 {
4737  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4738  const typename MT::Iterator first( matrix_.begin( column_ + j ) + row_ );
4739  return Iterator( first, first + final_, rest_, isAligned_ );
4740 }
4742 //*************************************************************************************************
4743 
4744 
4745 //*************************************************************************************************
4752 template< typename MT > // Type of the dense matrix
4755 {
4756  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4757  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
4758  return ConstIterator( first, first + final_, rest_, isAligned_ );
4759 }
4761 //*************************************************************************************************
4762 
4763 
4764 //*************************************************************************************************
4771 template< typename MT > // Type of the dense matrix
4774 {
4775  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4776  const typename MT::ConstIterator first( matrix_.cbegin( column_ + j ) + row_ );
4777  return ConstIterator( first, first + final_, rest_, isAligned_ );
4778 }
4780 //*************************************************************************************************
4781 
4782 
4783 //*************************************************************************************************
4790 template< typename MT > // Type of the dense matrix
4793 {
4794  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4795  const typename MT::Iterator last( matrix_.begin( column_ + j ) + row_ + m_ );
4796  return Iterator( last, last, rest_, isAligned_ );
4797 }
4799 //*************************************************************************************************
4800 
4801 
4802 //*************************************************************************************************
4809 template< typename MT > // Type of the dense matrix
4811  DenseSubmatrix<MT,unaligned,true>::end( size_t j ) const
4812 {
4813  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4814  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
4815  return ConstIterator( last, last, rest_, isAligned_ );
4816 }
4818 //*************************************************************************************************
4819 
4820 
4821 //*************************************************************************************************
4828 template< typename MT > // Type of the dense matrix
4830  DenseSubmatrix<MT,unaligned,true>::cend( size_t j ) const
4831 {
4832  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4833  const typename MT::ConstIterator last( matrix_.cbegin( column_ + j ) + row_ + m_ );
4834  return ConstIterator( last, last, rest_, isAligned_ );
4835 }
4837 //*************************************************************************************************
4838 
4839 
4840 
4841 
4842 //=================================================================================================
4843 //
4844 // ASSIGNMENT OPERATORS
4845 //
4846 //=================================================================================================
4847 
4848 //*************************************************************************************************
4859 template< typename MT > // Type of the dense matrix
4860 inline DenseSubmatrix<MT,unaligned,true>&
4861  DenseSubmatrix<MT,unaligned,true>::operator=( const ElementType& rhs )
4862 {
4863  const size_t jend( column_ + n_ );
4864 
4865  for( size_t j=column_; j<jend; ++j )
4866  {
4867  const size_t ibegin( ( IsLower<MT>::value )
4868  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4869  ?( max( j+1UL, row_ ) )
4870  :( max( j, row_ ) ) )
4871  :( row_ ) );
4872  const size_t iend ( ( IsUpper<MT>::value )
4873  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4874  ?( min( j, row_+m_ ) )
4875  :( min( j+1UL, row_+m_ ) ) )
4876  :( row_+m_ ) );
4877 
4878  for( size_t i=ibegin; i<iend; ++i )
4879  matrix_(i,j) = rhs;
4880  }
4881 
4882  return *this;
4883 }
4885 //*************************************************************************************************
4886 
4887 
4888 //*************************************************************************************************
4903 template< typename MT > // Type of the dense matrix
4904 inline DenseSubmatrix<MT,unaligned,true>&
4905  DenseSubmatrix<MT,unaligned,true>::operator=( const DenseSubmatrix& rhs )
4906 {
4909 
4910  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
4911  return *this;
4912 
4913  if( rows() != rhs.rows() || columns() != rhs.columns() )
4914  throw std::invalid_argument( "Submatrix sizes do not match" );
4915 
4916  if( !preservesInvariant( matrix_, rhs ) )
4917  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
4918 
4919  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4920 
4921  if( rhs.canAlias( &matrix_ ) ) {
4922  const ResultType tmp( rhs );
4923  smpAssign( left, tmp );
4924  }
4925  else {
4926  smpAssign( left, rhs );
4927  }
4928 
4929  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4930  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4931  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
4932 
4933  return *this;
4934 }
4936 //*************************************************************************************************
4937 
4938 
4939 //*************************************************************************************************
4954 template< typename MT > // Type of the dense matrix
4955 template< typename MT2 // Type of the right-hand side matrix
4956  , bool SO > // Storage order of the right-hand side matrix
4957 inline DenseSubmatrix<MT,unaligned,true>&
4958  DenseSubmatrix<MT,unaligned,true>::operator=( const Matrix<MT2,SO>& rhs )
4959 {
4961 
4962  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
4963  throw std::invalid_argument( "Matrix sizes do not match" );
4964 
4965  typedef typename If< IsAdaptor<MT>, typename MT2::CompositeType, const MT2& >::Type Right;
4966  Right right( ~rhs );
4967 
4968  if( !preservesInvariant( matrix_, right ) )
4969  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
4970 
4971  if( IsSparseMatrix<MT2>::value )
4972  reset();
4973 
4974  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4975 
4976  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4977  const typename MT2::ResultType tmp( right );
4978  smpAssign( left, tmp );
4979  }
4980  else {
4981  smpAssign( left, right );
4982  }
4983 
4984  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4985  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4986  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
4987 
4988  return *this;
4989 }
4991 //*************************************************************************************************
4992 
4993 
4994 //*************************************************************************************************
5008 template< typename MT > // Type of the dense matrix
5009 template< typename MT2 // Type of the right-hand side matrix
5010  , bool SO > // Storage order of the right-hand side matrix
5011 inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
5012  , DenseSubmatrix<MT,unaligned,true>& >::Type
5013  DenseSubmatrix<MT,unaligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
5014 {
5018 
5019  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
5020 
5023 
5024  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5025  throw std::invalid_argument( "Matrix sizes do not match" );
5026 
5027  if( !preservesInvariant( matrix_, ~rhs ) )
5028  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
5029 
5030  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5031 
5032  if( ( IsSymmetric<MT>::value && hasOverlap() ) || (~rhs).canAlias( &matrix_ ) ) {
5033  const AddType tmp( *this + (~rhs) );
5034  smpAssign( left, tmp );
5035  }
5036  else {
5037  smpAddAssign( left, ~rhs );
5038  }
5039 
5040  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
5041  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
5042  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
5043 
5044  return *this;
5045 }
5047 //*************************************************************************************************
5048 
5049 
5050 //*************************************************************************************************
5064 template< typename MT > // Type of the dense matrix
5065 template< typename MT2 // Type of the right-hand side matrix
5066  , bool SO > // Storage order of the right-hand side matrix
5067 inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
5068  , DenseSubmatrix<MT,unaligned,true>& >::Type
5069  DenseSubmatrix<MT,unaligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
5070 {
5074 
5075  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
5076 
5079 
5080  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5081  throw std::invalid_argument( "Matrix sizes do not match" );
5082 
5083  const AddType tmp( *this + (~rhs) );
5084 
5085  if( !preservesInvariant( matrix_, tmp ) )
5086  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
5087 
5088  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5089 
5090  smpAssign( left, tmp );
5091 
5092  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
5093  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
5094  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
5095 
5096  return *this;
5097 }
5099 //*************************************************************************************************
5100 
5101 
5102 //*************************************************************************************************
5116 template< typename MT > // Type of the dense matrix
5117 template< typename MT2 // Type of the right-hand side matrix
5118  , bool SO > // Storage order of the right-hand side matrix
5119 inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
5120  , DenseSubmatrix<MT,unaligned,true>& >::Type
5121  DenseSubmatrix<MT,unaligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
5122 {
5126 
5127  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
5128 
5131 
5132  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5133  throw std::invalid_argument( "Matrix sizes do not match" );
5134 
5135  if( !preservesInvariant( matrix_, ~rhs ) )
5136  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
5137 
5138  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5139 
5140  if( ( IsSymmetric<MT>::value && hasOverlap() ) || (~rhs).canAlias( &matrix_ ) ) {
5141  const SubType tmp( *this - (~rhs ) );
5142  smpAssign( left, tmp );
5143  }
5144  else {
5145  smpSubAssign( left, ~rhs );
5146  }
5147 
5148  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
5149  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
5150  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
5151 
5152  return *this;
5153 }
5155 //*************************************************************************************************
5156 
5157 
5158 //*************************************************************************************************
5172 template< typename MT > // Type of the dense matrix
5173 template< typename MT2 // Type of the right-hand side matrix
5174  , bool SO > // Storage order of the right-hand side matrix
5175 inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
5176  , DenseSubmatrix<MT,unaligned,true>& >::Type
5177  DenseSubmatrix<MT,unaligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
5178 {
5182 
5183  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
5184 
5187 
5188  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
5189  throw std::invalid_argument( "Matrix sizes do not match" );
5190 
5191  const SubType tmp( *this - (~rhs) );
5192 
5193  if( !preservesInvariant( matrix_, tmp ) )
5194  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
5195 
5196  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5197 
5198  smpAssign( left, tmp );
5199 
5200  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
5201  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
5202  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
5203 
5204  return *this;
5205 }
5207 //*************************************************************************************************
5208 
5209 
5210 //*************************************************************************************************
5224 template< typename MT > // Type of the dense matrix
5225 template< typename MT2 // Type of the right-hand side matrix
5226  , bool SO > // Storage order of the right-hand side matrix
5227 inline DenseSubmatrix<MT,unaligned,true>&
5228  DenseSubmatrix<MT,unaligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
5229 {
5233 
5234  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
5235 
5238 
5239  if( columns() != (~rhs).rows() )
5240  throw std::invalid_argument( "Matrix sizes do not match" );
5241 
5242  const MultType tmp( *this * (~rhs) );
5243 
5244  if( !preservesInvariant( matrix_, tmp ) )
5245  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
5246 
5247  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5248 
5249  smpAssign( left, tmp );
5250 
5251  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
5252  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
5253  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
5254 
5255  return *this;
5256 }
5258 //*************************************************************************************************
5259 
5260 
5261 //*************************************************************************************************
5272 template< typename MT > // Type of the dense matrix
5273 template< typename Other > // Data type of the right-hand side scalar
5274 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
5275  DenseSubmatrix<MT,unaligned,true>::operator*=( Other rhs )
5276 {
5278 
5279  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5280  smpAssign( left, (*this) * rhs );
5281 
5282  return *this;
5283 }
5285 //*************************************************************************************************
5286 
5287 
5288 //*************************************************************************************************
5301 template< typename MT > // Type of the dense matrix
5302 template< typename Other > // Data type of the right-hand side scalar
5303 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
5304  DenseSubmatrix<MT,unaligned,true>::operator/=( Other rhs )
5305 {
5307 
5308  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
5309 
5310  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5311  smpAssign( left, (*this) / rhs );
5312 
5313  return *this;
5314 }
5316 //*************************************************************************************************
5317 
5318 
5319 
5320 
5321 //=================================================================================================
5322 //
5323 // UTILITY FUNCTIONS
5324 //
5325 //=================================================================================================
5326 
5327 //*************************************************************************************************
5333 template< typename MT > // Type of the dense matrix
5334 inline size_t DenseSubmatrix<MT,unaligned,true>::rows() const
5335 {
5336  return m_;
5337 }
5339 //*************************************************************************************************
5340 
5341 
5342 //*************************************************************************************************
5348 template< typename MT > // Type of the dense matrix
5349 inline size_t DenseSubmatrix<MT,unaligned,true>::columns() const
5350 {
5351  return n_;
5352 }
5354 //*************************************************************************************************
5355 
5356 
5357 //*************************************************************************************************
5366 template< typename MT > // Type of the dense matrix
5367 inline size_t DenseSubmatrix<MT,unaligned,true>::spacing() const
5368 {
5369  return matrix_.spacing();
5370 }
5372 //*************************************************************************************************
5373 
5374 
5375 //*************************************************************************************************
5381 template< typename MT > // Type of the dense matrix
5382 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity() const
5383 {
5384  return rows() * columns();
5385 }
5387 //*************************************************************************************************
5388 
5389 
5390 //*************************************************************************************************
5397 template< typename MT > // Type of the dense matrix
5398 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity( size_t j ) const
5399 {
5400  UNUSED_PARAMETER( j );
5401 
5402  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5403 
5404  return rows();
5405 }
5407 //*************************************************************************************************
5408 
5409 
5410 //*************************************************************************************************
5416 template< typename MT > // Type of the dense matrix
5417 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros() const
5418 {
5419  const size_t iend( row_ + m_ );
5420  const size_t jend( column_ + n_ );
5421  size_t nonzeros( 0UL );
5422 
5423  for( size_t j=column_; j<jend; ++j )
5424  for( size_t i=row_; i<iend; ++i )
5425  if( !isDefault( matrix_(i,j) ) )
5426  ++nonzeros;
5427 
5428  return nonzeros;
5429 }
5431 //*************************************************************************************************
5432 
5433 
5434 //*************************************************************************************************
5441 template< typename MT > // Type of the dense matrix
5442 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros( size_t j ) const
5443 {
5444  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5445 
5446  const size_t iend( row_ + m_ );
5447  size_t nonzeros( 0UL );
5448 
5449  for( size_t i=row_; i<iend; ++i )
5450  if( !isDefault( matrix_(i,column_+j) ) )
5451  ++nonzeros;
5452 
5453  return nonzeros;
5454 }
5456 //*************************************************************************************************
5457 
5458 
5459 //*************************************************************************************************
5465 template< typename MT > // Type of the dense matrix
5467 {
5468  using blaze::clear;
5469 
5470  for( size_t j=column_; j<column_+n_; ++j )
5471  {
5472  const size_t ibegin( ( IsLower<MT>::value )
5473  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
5474  ?( max( j+1UL, row_ ) )
5475  :( max( j, row_ ) ) )
5476  :( row_ ) );
5477  const size_t iend ( ( IsUpper<MT>::value )
5478  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
5479  ?( min( j, row_+m_ ) )
5480  :( min( j+1UL, row_+m_ ) ) )
5481  :( row_+m_ ) );
5482 
5483  for( size_t i=ibegin; i<iend; ++i )
5484  clear( matrix_(i,j) );
5485  }
5486 }
5488 //*************************************************************************************************
5489 
5490 
5491 //*************************************************************************************************
5498 template< typename MT > // Type of the dense matrix
5499 inline void DenseSubmatrix<MT,unaligned,true>::reset( size_t j )
5500 {
5501  using blaze::clear;
5502 
5503  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5504 
5505  const size_t ibegin( ( IsLower<MT>::value )
5506  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
5507  ?( max( j+1UL, row_ ) )
5508  :( max( j, row_ ) ) )
5509  :( row_ ) );
5510  const size_t iend ( ( IsUpper<MT>::value )
5511  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
5512  ?( min( j, row_+m_ ) )
5513  :( min( j+1UL, row_+m_ ) ) )
5514  :( row_+m_ ) );
5515 
5516  for( size_t i=ibegin; i<iend; ++i )
5517  clear( matrix_(i,column_+j) );
5518 }
5520 //*************************************************************************************************
5521 
5522 
5523 //*************************************************************************************************
5539 template< typename MT > // Type of the dense matrix
5540 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::transpose()
5541 {
5542  if( rows() != columns() )
5543  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
5544 
5545  if( IsLower<MT>::value && ( row_ + 1UL < column_ + n_ ) )
5546  throw std::runtime_error( "Invalid transpose of a lower matrix" );
5547 
5548  if( IsUpper<MT>::value && ( column_ + 1UL < row_ + m_ ) )
5549  throw std::runtime_error( "Invalid transpose of an upper matrix" );
5550 
5551  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5552  const ResultType tmp( trans(*this) );
5553  smpAssign( left, tmp );
5554 
5555  return *this;
5556 }
5558 //*************************************************************************************************
5559 
5560 
5561 //*************************************************************************************************
5572 template< typename MT > // Type of the dense matrix
5573 template< typename Other > // Data type of the scalar value
5574 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::scale( const Other& scalar )
5575 {
5577 
5578  const size_t jend( column_ + n_ );
5579 
5580  for( size_t j=column_; j<jend; ++j )
5581  {
5582  const size_t ibegin( ( IsLower<MT>::value )
5583  ?( ( IsStrictlyLower<MT>::value )
5584  ?( max( j+1UL, row_ ) )
5585  :( max( j, row_ ) ) )
5586  :( row_ ) );
5587  const size_t iend ( ( IsUpper<MT>::value )
5588  ?( ( IsStrictlyUpper<MT>::value )
5589  ?( min( j, row_+m_ ) )
5590  :( min( j+1UL, row_+m_ ) ) )
5591  :( row_+m_ ) );
5592 
5593  for( size_t i=ibegin; i<iend; ++i )
5594  matrix_(i,j) *= scalar;
5595  }
5596 
5597  return *this;
5598 }
5600 //*************************************************************************************************
5601 
5602 
5603 //*************************************************************************************************
5613 template< typename MT > // Type of the dense matrix
5615 {
5616  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
5617 
5618  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
5619  return false;
5620  else return true;
5621 }
5623 //*************************************************************************************************
5624 
5625 
5626 //*************************************************************************************************
5638 template< typename MT > // Type of the dense matrix
5639 template< typename MT2 // Type of the left-hand side dense matrix
5640  , bool SO2 // Storage order of the left-hand side dense matrix
5641  , typename MT3 // Type of the right-hand side matrix
5642  , bool SO3 > // Storage order of the right-hand side matrix
5643 inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
5644  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs )
5645 {
5646  UNUSED_PARAMETER( lhs, rhs );
5647 
5648  return true;
5649 }
5651 //*************************************************************************************************
5652 
5653 
5654 //*************************************************************************************************
5666 template< typename MT > // Type of the dense matrix
5667 template< typename MT2 // Type of the left-hand side dense matrix
5668  , bool SO2 // Storage order of the left-hand side dense matrix
5669  , typename MT3 // Type of the right-hand side matrix
5670  , bool SO3 > // Storage order of the right-hand side matrix
5671 inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5672  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs )
5673 {
5675 
5676  UNUSED_PARAMETER( lhs );
5677 
5678  if( !hasOverlap() )
5679  return true;
5680 
5681  const bool lower( row_ > column_ );
5682  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
5683 
5684  if( size < 2UL )
5685  return true;
5686 
5687  const size_t row ( lower ? 0UL : column_ - row_ );
5688  const size_t column( lower ? row_ - column_ : 0UL );
5689 
5690  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
5691 }
5693 //*************************************************************************************************
5694 
5695 
5696 //*************************************************************************************************
5709 template< typename MT > // Type of the dense matrix
5710 template< typename MT2 // Type of the left-hand side dense matrix
5711  , bool SO2 // Storage order of the left-hand side dense matrix
5712  , typename MT3 > // Type of the right-hand side dense matrix
5713 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5714  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
5715 {
5717 
5718  UNUSED_PARAMETER( lhs );
5719 
5720  if( row_ + 1UL >= column_ + n_ )
5721  return true;
5722 
5723  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5724  ?( column_ + n_ - row_ )
5725  :( column_ + n_ - row_ - 1UL ) );
5726  const size_t iend( min( ipos, m_ ) );
5727 
5728  for( size_t i=0UL; i<iend; ++i )
5729  {
5730  const bool containsDiagonal( row_+i >= column_ );
5731 
5732  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
5733  return false;
5734 
5735  const size_t jbegin( ( containsDiagonal )
5736  ?( ( IsStrictlyLower<MT2>::value )
5737  ?( row_ + i - column_ )
5738  :( row_ + i - column_ + 1UL ) )
5739  :( 0UL ) );
5740 
5741  for( size_t j=jbegin; j<n_; ++j ) {
5742  if( !isDefault( (~rhs)(i,j) ) )
5743  return false;
5744  }
5745  }
5746 
5747  return true;
5748 }
5750 //*************************************************************************************************
5751 
5752 
5753 //*************************************************************************************************
5766 template< typename MT > // Type of the dense matrix
5767 template< typename MT2 // Type of the left-hand side dense matrix
5768  , bool SO2 // Storage order of the left-hand side dense matrix
5769  , typename MT3 > // Type of the right-hand side dense matrix
5770 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5771  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
5772 {
5774 
5775  UNUSED_PARAMETER( lhs );
5776 
5777  if( row_ + 1UL >= column_ + n_ )
5778  return true;
5779 
5780  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5781  ?( row_ - column_ )
5782  :( row_ - column_ + 1UL ) );
5783  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
5784 
5785  for( size_t j=jbegin; j<n_; ++j )
5786  {
5787  const bool containsDiagonal( column_+j < row_+m_ );
5788 
5789  const size_t ipos( ( IsStrictlyLower<MT2>::value && containsDiagonal )
5790  ?( column_ + j - row_ + 1UL )
5791  :( column_ + j - row_ ) );
5792  const size_t iend( min( ipos, m_ ) );
5793 
5794  for( size_t i=0UL; i<iend; ++i ) {
5795  if( !isDefault( (~rhs)(i,j) ) )
5796  return false;
5797  }
5798 
5799  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
5800  return false;
5801  }
5802 
5803  return true;
5804 }
5806 //*************************************************************************************************
5807 
5808 
5809 //*************************************************************************************************
5822 template< typename MT > // Type of the dense matrix
5823 template< typename MT2 // Type of the left-hand side dense matrix
5824  , bool SO2 // Storage order of the left-hand side dense matrix
5825  , typename MT3 > // Type of the right-hand side sparse matrix
5826 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5827  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
5828 {
5830 
5831  UNUSED_PARAMETER( lhs );
5832 
5833  typedef typename MT3::ConstIterator RhsIterator;
5834 
5835  if( row_ + 1UL >= column_ + n_ )
5836  return true;
5837 
5838  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5839  ?( column_ + n_ - row_ )
5840  :( column_ + n_ - row_ - 1UL ) );
5841  const size_t iend( min( ipos, m_ ) );
5842 
5843  for( size_t i=0UL; i<iend; ++i )
5844  {
5845  const bool containsDiagonal( row_+i >= column_ );
5846 
5847  const size_t index( ( containsDiagonal )
5848  ?( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5849  ?( row_ + i - column_ )
5850  :( row_ + i - column_ + 1UL ) )
5851  :( 0UL ) );
5852 
5853  const RhsIterator last( (~rhs).end(i) );
5854  RhsIterator element( (~rhs).lowerBound( i, index ) );
5855 
5856  if( IsUniLower<MT2>::value && containsDiagonal ) {
5857  if( element == last || ( element->index() != row_+i-column_ ) || !isOne( element->value() ) )
5858  return false;
5859  ++element;
5860  }
5861 
5862  for( ; element!=last; ++element ) {
5863  if( !isDefault( element->value() ) )
5864  return false;
5865  }
5866  }
5867 
5868  return true;
5869 }
5871 //*************************************************************************************************
5872 
5873 
5874 //*************************************************************************************************
5887 template< typename MT > // Type of the dense matrix
5888 template< typename MT2 // Type of the left-hand side dense matrix
5889  , bool SO2 // Storage order of the left-hand side dense matrix
5890  , typename MT3 > // Type of the right-hand side sparse matrix
5891 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5892  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
5893 {
5895 
5896  UNUSED_PARAMETER( lhs );
5897 
5898  typedef typename MT3::ConstIterator RhsIterator;
5899 
5900  if( row_ + 1UL >= column_ + n_ )
5901  return true;
5902 
5903  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
5904  ?( row_ - column_ )
5905  :( row_ - column_ + 1UL ) );
5906  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
5907 
5908  for( size_t j=jbegin; j<n_; ++j )
5909  {
5910  const bool containsDiagonal( column_+j < row_+m_ );
5911 
5912  const size_t index( ( IsStrictlyLower<MT2>::value && containsDiagonal )
5913  ?( column_ + j - row_ + 1UL )
5914  :( column_ + j - row_ ) );
5915  const RhsIterator last( (~rhs).lowerBound( min( index, m_ ), j ) );
5916 
5917  if( IsUniLower<MT2>::value && containsDiagonal &&
5918  ( last == (~rhs).end(j) || ( last->index() != column_+j-row_ ) || !isOne( last->value() ) ) ) {
5919  return false;
5920  }
5921 
5922  for( RhsIterator element=(~rhs).begin(j); element!=last; ++element ) {
5923  if( !isDefault( element->value() ) )
5924  return false;
5925  }
5926  }
5927 
5928  return true;
5929 }
5931 //*************************************************************************************************
5932 
5933 
5934 //*************************************************************************************************
5947 template< typename MT > // Type of the dense matrix
5948 template< typename MT2 // Type of the left-hand side dense matrix
5949  , bool SO2 // Storage order of the left-hand side dense matrix
5950  , typename MT3 > // Type of the right-hand side dense matrix
5951 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5952  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
5953 {
5955 
5956  UNUSED_PARAMETER( lhs );
5957 
5958  if( column_ + 1UL >= row_ + m_ )
5959  return true;
5960 
5961  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
5962  ?( column_ - row_ )
5963  :( column_ - row_ + 1UL ) );
5964  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
5965 
5966  for( size_t i=ibegin; i<m_; ++i )
5967  {
5968  const bool containsDiagonal( row_+i < column_+n_ );
5969 
5970  const size_t jpos( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
5971  ?( row_ + i - column_ + 1UL )
5972  :( row_ + i - column_ ) );
5973  const size_t jend( min( jpos, n_ ) );
5974 
5975  for( size_t j=0UL; j<jend; ++j ) {
5976  if( !isDefault( (~rhs)(i,j) ) )
5977  return false;
5978  }
5979 
5980  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
5981  return false;
5982  }
5983 
5984  return true;
5985 }
5987 //*************************************************************************************************
5988 
5989 
5990 //*************************************************************************************************
6003 template< typename MT > // Type of the dense matrix
6004 template< typename MT2 // Type of the left-hand side dense matrix
6005  , bool SO2 // Storage order of the left-hand side dense matrix
6006  , typename MT3 > // Type of the right-hand side dense matrix
6007 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
6008  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
6009 {
6011 
6012  UNUSED_PARAMETER( lhs );
6013 
6014  if( column_ + 1UL >= row_ + m_ )
6015  return true;
6016 
6017  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
6018  ?( row_ + m_ - column_ )
6019  :( row_ + m_ - column_ - 1UL ) );
6020  const size_t jend( min( jpos, n_ ) );
6021 
6022  for( size_t j=0UL; j<jend; ++j )
6023  {
6024  const bool containsDiagonal( column_+j >= row_ );
6025 
6026  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
6027  return false;
6028 
6029  const size_t ibegin( ( containsDiagonal )
6030  ?( ( IsStrictlyUpper<MT2>::value )
6031  ?( column_ + j - row_ )
6032  :( column_ + j - row_ + 1UL ) )
6033  :( 0UL ) );
6034 
6035  for( size_t i=ibegin; i<m_; ++i ) {
6036  if( !isDefault( (~rhs)(i,j) ) )
6037  return false;
6038  }
6039  }
6040 
6041  return true;
6042 }
6044 //*************************************************************************************************
6045 
6046 
6047 //*************************************************************************************************
6060 template< typename MT > // Type of the dense matrix
6061 template< typename MT2 // Type of the left-hand side dense matrix
6062  , bool SO2 // Storage order of the left-hand side dense matrix
6063  , typename MT3 > // Type of the right-hand side sparse matrix
6064 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
6065  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
6066 {
6068 
6069  UNUSED_PARAMETER( lhs );
6070 
6071  typedef typename MT3::ConstIterator RhsIterator;
6072 
6073  if( column_ + 1UL >= row_ + m_ )
6074  return true;
6075 
6076  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
6077  ?( column_ - row_ )
6078  :( column_ - row_ + 1UL ) );
6079  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
6080 
6081  for( size_t i=ibegin; i<m_; ++i )
6082  {
6083  const bool containsDiagonal( row_+i < column_+n_ );
6084 
6085  const size_t index( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
6086  ?( row_ + i - column_ + 1UL )
6087  :( row_ + i - column_ ) );
6088  const RhsIterator last( (~rhs).lowerBound( i, min( index, n_ ) ) );
6089 
6090  if( IsUniUpper<MT2>::value && containsDiagonal &&
6091  ( last == (~rhs).end(i) || ( last->index() != row_+i-column_ ) || !isOne( last->value() ) ) ) {
6092  return false;
6093  }
6094 
6095  for( RhsIterator element=(~rhs).begin(i); element!=last; ++element ) {
6096  if( !isDefault( element->value() ) )
6097  return false;
6098  }
6099  }
6100 
6101  return true;
6102 }
6104 //*************************************************************************************************
6105 
6106 
6107 //*************************************************************************************************
6120 template< typename MT > // Type of the dense matrix
6121 template< typename MT2 // Type of the left-hand side dense matrix
6122  , bool SO2 // Storage order of the left-hand side dense matrix
6123  , typename MT3 > // Type of the right-hand side sparse matrix
6124 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
6125  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
6126 {
6128 
6129  UNUSED_PARAMETER( lhs );
6130 
6131  typedef typename MT3::ConstIterator RhsIterator;
6132 
6133  if( column_ + 1UL >= row_ + m_ )
6134  return true;
6135 
6136  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
6137  ?( row_ + m_ - column_ )
6138  :( row_ + m_ - column_ - 1UL ) );
6139  const size_t jend( min( jpos, n_ ) );
6140 
6141  for( size_t j=0UL; j<jend; ++j )
6142  {
6143  const bool containsDiagonal( column_+j >= row_ );
6144 
6145  const size_t index( ( containsDiagonal )
6146  ?( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
6147  ?( column_ + j - row_ )
6148  :( column_ + j - row_ + 1UL ) )
6149  :( 0UL ) );
6150 
6151  const RhsIterator last( (~rhs).end(j) );
6152  RhsIterator element( (~rhs).lowerBound( index, j ) );
6153 
6154  if( IsUniUpper<MT2>::value && containsDiagonal ) {
6155  if( element == last || ( element->index() != column_+j-row_ ) || !isOne( element->value() ) )
6156  return false;
6157  ++element;
6158  }
6159 
6160  for( ; element!=last; ++element ) {
6161  if( !isDefault( element->value() ) )
6162  return false;
6163  }
6164  }
6165 
6166  return true;
6167 }
6169 //*************************************************************************************************
6170 
6171 
6172 //*************************************************************************************************
6184 template< typename MT > // Type of the dense matrix
6185 template< typename MT2 // Type of the left-hand side dense matrix
6186  , bool SO2 // Storage order of the left-hand side dense matrix
6187  , typename MT3 > // Type of the right-hand side dense matrix
6188 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
6189  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
6190 {
6192 
6193  UNUSED_PARAMETER( lhs );
6194 
6195  for( size_t i=0UL; i<m_; ++i ) {
6196  for( size_t j=0UL; j<n_; ++j ) {
6197  if( ( row_ + i != column_ + j ) && !isDefault( (~rhs)(i,j) ) )
6198  return false;
6199  }
6200  }
6201 
6202  return true;
6203 }
6205 //*************************************************************************************************
6206 
6207 
6208 //*************************************************************************************************
6220 template< typename MT > // Type of the dense matrix
6221 template< typename MT2 // Type of the left-hand side dense matrix
6222  , bool SO2 // Storage order of the left-hand side dense matrix
6223  , typename MT3 > // Type of the right-hand side dense matrix
6224 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
6225  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
6226 {
6228 
6229  UNUSED_PARAMETER( lhs );
6230 
6231  for( size_t j=0UL; j<n_; ++j ) {
6232  for( size_t i=0UL; i<m_; ++i ) {
6233  if( ( column_ + j != row_ + i ) && !isDefault( (~rhs)(i,j) ) )
6234  return false;
6235  }
6236  }
6237 
6238  return true;
6239 }
6241 //*************************************************************************************************
6242 
6243 
6244 //*************************************************************************************************
6256 template< typename MT > // Type of the dense matrix
6257 template< typename MT2 // Type of the left-hand side dense matrix
6258  , bool SO2 // Storage order of the left-hand side dense matrix
6259  , typename MT3 > // Type of the right-hand side sparse matrix
6260 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
6261  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
6262 {
6264 
6265  UNUSED_PARAMETER( lhs );
6266 
6267  typedef typename MT3::ConstIterator RhsIterator;
6268 
6269  for( size_t i=0UL; i<m_; ++i ) {
6270  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
6271  if( ( row_ + i != column_ + element->index() ) && !isDefault( element->value() ) )
6272  return false;
6273  }
6274  }
6275 
6276  return true;
6277 }
6279 //*************************************************************************************************
6280 
6281 
6282 //*************************************************************************************************
6294 template< typename MT > // Type of the dense matrix
6295 template< typename MT2 // Type of the left-hand side dense matrix
6296  , bool SO2 // Storage order of the left-hand side dense matrix
6297  , typename MT3 > // Type of the right-hand side sparse matrix
6298 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
6299  DenseSubmatrix<MT,unaligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
6300 {
6302 
6303  UNUSED_PARAMETER( lhs );
6304 
6305  typedef typename MT3::ConstIterator RhsIterator;
6306 
6307  for( size_t j=0UL; j<n_; ++j ) {
6308  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
6309  if( ( column_ + j != row_ + element->index() ) && !isDefault( element->value() ) )
6310  return false;
6311  }
6312  }
6313 
6314  return true;
6315 }
6317 //*************************************************************************************************
6318 
6319 
6320 
6321 
6322 //=================================================================================================
6323 //
6324 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6325 //
6326 //=================================================================================================
6327 
6328 //*************************************************************************************************
6339 template< typename MT > // Type of the dense matrix
6340 template< typename Other > // Data type of the foreign expression
6341 inline bool DenseSubmatrix<MT,unaligned,true>::canAlias( const Other* alias ) const
6342 {
6343  return matrix_.isAliased( alias );
6344 }
6346 //*************************************************************************************************
6347 
6348 
6349 //*************************************************************************************************
6360 template< typename MT > // Type of the dense matrix
6361 template< typename MT2 // Data type of the foreign dense submatrix
6362  , bool AF2 // Alignment flag of the foreign dense submatrix
6363  , bool SO2 > // Storage order of the foreign dense submatrix
6364 inline bool DenseSubmatrix<MT,unaligned,true>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
6365 {
6366  return ( matrix_.isAliased( &alias->matrix_ ) &&
6367  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
6368  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
6369 }
6371 //*************************************************************************************************
6372 
6373 
6374 //*************************************************************************************************
6385 template< typename MT > // Type of the dense matrix
6386 template< typename Other > // Data type of the foreign expression
6387 inline bool DenseSubmatrix<MT,unaligned,true>::isAliased( const Other* alias ) const
6388 {
6389  return matrix_.isAliased( alias );
6390 }
6392 //*************************************************************************************************
6393 
6394 
6395 //*************************************************************************************************
6406 template< typename MT > // Type of the dense matrix
6407 template< typename MT2 // Data type of the foreign dense submatrix
6408  , bool AF2 // Alignment flag of the foreign dense submatrix
6409  , bool SO2 > // Storage order of the foreign dense submatrix
6410 inline bool DenseSubmatrix<MT,unaligned,true>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
6411 {
6412  return ( matrix_.isAliased( &alias->matrix_ ) &&
6413  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
6414  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
6415 }
6417 //*************************************************************************************************
6418 
6419 
6420 //*************************************************************************************************
6430 template< typename MT > // Type of the dense matrix
6432 {
6433  return isAligned_;
6434 }
6436 //*************************************************************************************************
6437 
6438 
6439 //*************************************************************************************************
6450 template< typename MT > // Type of the dense matrix
6452 {
6453  return ( columns() > SMP_DMATASSIGN_THRESHOLD );
6454 }
6456 //*************************************************************************************************
6457 
6458 
6459 //*************************************************************************************************
6475 template< typename MT > // Type of the dense matrix
6476 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
6477  DenseSubmatrix<MT,unaligned,true>::load( size_t i, size_t j ) const
6478 {
6479  return loadu( i, j );
6480 }
6482 //*************************************************************************************************
6483 
6484 
6485 //*************************************************************************************************
6501 template< typename MT > // Type of the dense matrix
6502 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
6503  DenseSubmatrix<MT,unaligned,true>::loadu( size_t i, size_t j ) const
6504 {
6505  using blaze::load;
6506 
6508 
6509  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6510  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
6511  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6512 
6513  if( isAligned_ ) {
6514  return matrix_.load( row_+i, column_+j );
6515  }
6516  else if( i != final_ ) {
6517  return matrix_.loadu( row_+i, column_+j );
6518  }
6519  else {
6520  AlignedArray<ElementType,IT::size> array;
6521  for( size_t k=0UL; k<rest_; ++k )
6522  array[k] = matrix_(row_+i+k,column_+j);
6523  for( size_t k=rest_; k<IT::size; ++k )
6524  array[k] = ElementType();
6525  return load( array.data() );
6526  }
6527 }
6529 //*************************************************************************************************
6530 
6531 
6532 //*************************************************************************************************
6548 template< typename MT > // Type of the dense matrix
6549 inline void DenseSubmatrix<MT,unaligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
6550 {
6551  storeu( i, j, value );
6552 }
6554 //*************************************************************************************************
6555 
6556 
6557 //*************************************************************************************************
6574 template< typename MT > // Type of the dense matrix
6575 inline void DenseSubmatrix<MT,unaligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
6576 {
6577  using blaze::store;
6578 
6580 
6581  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
6582  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
6583  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
6584 
6585  if( isAligned_ ) {
6586  matrix_.store( row_+i, column_+j, value );
6587  }
6588  else if( i != final_ ) {
6589  matrix_.storeu( row_+i, column_+j, value );
6590  }
6591  else {
6592  AlignedArray<ElementType,IT::size> array;
6593  store( array.data(), value );
6594  for( size_t k=0UL; k<rest_; ++k )
6595  matrix_(row_+i+k,column_+j) = array[k];
6596  }
6597 }
6599 //*************************************************************************************************
6600 
6601 
6602 //*************************************************************************************************
6619 template< typename MT > // Type of the dense matrix
6620 inline void DenseSubmatrix<MT,unaligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
6621 {
6622  storeu( i, j, value );
6623 }
6625 //*************************************************************************************************
6626 
6627 
6628 //*************************************************************************************************
6640 template< typename MT > // Type of the dense matrix
6641 template< typename MT2 > // Type of the right-hand side dense matrix
6642 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
6643  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
6644 {
6646 
6647  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6648  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6649 
6650  const size_t ipos( m_ & size_t(-2) );
6651  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
6652 
6653  for( size_t j=0UL; j<n_; ++j ) {
6654  for( size_t i=0UL; i<ipos; i+=2UL ) {
6655  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
6656  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
6657  }
6658  if( ipos < m_ ) {
6659  matrix_(row_+ipos,column_+j) = (~rhs)(ipos,j);
6660  }
6661  }
6662 }
6664 //*************************************************************************************************
6665 
6666 
6667 //*************************************************************************************************
6679 template< typename MT > // Type of the dense matrix
6680 template< typename MT2 > // Type of the right-hand side dense matrix
6681 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
6682  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
6683 {
6686 
6687  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6688  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6689 
6690  if( useStreaming && isAligned_ &&
6691  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
6692  !(~rhs).isAliased( &matrix_ ) )
6693  {
6694  for( size_t j=0UL; j<n_; ++j )
6695  for( size_t i=0UL; i<m_; i+=IT::size )
6696  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
6697  }
6698  else
6699  {
6700  const size_t ipos( m_ & size_t(-IT::size*4) );
6701  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ipos, "Invalid end calculation" );
6702 
6703  for( size_t j=0UL; j<n_; ++j ) {
6704  typename MT2::ConstIterator it( (~rhs).begin(j) );
6705  for( size_t i=0UL; i<ipos; i+=IT::size*4UL ) {
6706  matrix_.storeu( row_+i , column_+j, it.load() ); it += IT::size;
6707  matrix_.storeu( row_+i+IT::size , column_+j, it.load() ); it += IT::size;
6708  matrix_.storeu( row_+i+IT::size*2UL, column_+j, it.load() ); it += IT::size;
6709  matrix_.storeu( row_+i+IT::size*3UL, column_+j, it.load() ); it += IT::size;
6710  }
6711  for( size_t i=ipos; i<m_; i+=IT::size, it+=IT::size ) {
6712  storeu( i, j, it.load() );
6713  }
6714  }
6715  }
6716 }
6718 //*************************************************************************************************
6719 
6720 
6721 //*************************************************************************************************
6733 template< typename MT > // Type of the dense matrix
6734 template< typename MT2 > // Type of the right-hand side dense matrix
6735 inline void DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
6736 {
6739 
6740  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6741  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6742 
6743  const size_t block( 16UL );
6744 
6745  for( size_t jj=0UL; jj<n_; jj+=block ) {
6746  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6747  for( size_t ii=0UL; ii<m_; ii+=block ) {
6748  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6749  for( size_t j=jj; j<jend; ++j ) {
6750  for( size_t i=ii; i<iend; ++i ) {
6751  matrix_(row_+i,column_+j) = (~rhs)(i,j);
6752  }
6753  }
6754  }
6755  }
6756 }
6758 //*************************************************************************************************
6759 
6760 
6761 //*************************************************************************************************
6773 template< typename MT > // Type of the dense matrix
6774 template< typename MT2 > // Type of the right-hand side sparse matrix
6775 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
6776 {
6778 
6779  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6780  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6781 
6782  for( size_t j=0UL; j<n_; ++j )
6783  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6784  matrix_(row_+element->index(),column_+j) = element->value();
6785 }
6787 //*************************************************************************************************
6788 
6789 
6790 //*************************************************************************************************
6802 template< typename MT > // Type of the dense matrix
6803 template< typename MT2 > // Type of the right-hand side sparse matrix
6804 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
6805 {
6808 
6809  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6810  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6811 
6812  for( size_t i=0UL; i<m_; ++i )
6813  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6814  matrix_(row_+i,column_+element->index()) = element->value();
6815 }
6817 //*************************************************************************************************
6818 
6819 
6820 //*************************************************************************************************
6832 template< typename MT > // Type of the dense matrix
6833 template< typename MT2 > // Type of the right-hand side dense matrix
6834 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
6835  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
6836 {
6838 
6839  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6840  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6841 
6842  const size_t ipos( m_ & size_t(-2) );
6843  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
6844 
6845  for( size_t j=0UL; j<n_; ++j ) {
6846  for( size_t i=0UL; i<ipos; i+=2UL ) {
6847  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
6848  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
6849  }
6850  if( ipos < m_ ) {
6851  matrix_(row_+ipos,column_+j) += (~rhs)(ipos,j);
6852  }
6853  }
6854 }
6856 //*************************************************************************************************
6857 
6858 
6859 //*************************************************************************************************
6871 template< typename MT > // Type of the dense matrix
6872 template< typename MT2 > // Type of the right-hand side dense matrix
6873 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
6874  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
6875 {
6878 
6879  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6880  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6881 
6882  const size_t ipos( m_ & size_t(-IT::size*4) );
6883  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ipos, "Invalid end calculation" );
6884 
6885  for( size_t j=0UL; j<n_; ++j ) {
6886  typename MT2::ConstIterator it( (~rhs).begin(j) );
6887  for( size_t i=0UL; i<ipos; i+=IT::size*4UL ) {
6888  matrix_.storeu( row_+i , column_+j, load(i ,j) + it.load() ); it += IT::size;
6889  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) + it.load() ); it += IT::size;
6890  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
6891  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
6892  }
6893  for( size_t i=ipos; i<m_; i+=IT::size, it+=IT::size ) {
6894  storeu( i, j, load(i,j) + it.load() );
6895  }
6896  }
6897 }
6899 //*************************************************************************************************
6900 
6901 
6902 //*************************************************************************************************
6914 template< typename MT > // Type of the dense matrix
6915 template< typename MT2 > // Type of the right-hand side dense matrix
6916 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
6917 {
6920 
6921  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6922  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6923 
6924  const size_t block( 16UL );
6925 
6926  for( size_t jj=0UL; jj<n_; jj+=block ) {
6927  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6928  for( size_t ii=0UL; ii<m_; ii+=block ) {
6929  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6930  for( size_t j=jj; j<jend; ++j ) {
6931  for( size_t i=ii; i<iend; ++i ) {
6932  matrix_(row_+i,column_+j) += (~rhs)(i,j);
6933  }
6934  }
6935  }
6936  }
6937 }
6939 //*************************************************************************************************
6940 
6941 
6942 //*************************************************************************************************
6954 template< typename MT > // Type of the dense matrix
6955 template< typename MT2 > // Type of the right-hand side sparse matrix
6956 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
6957 {
6959 
6960  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6961  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6962 
6963  for( size_t j=0UL; j<n_; ++j )
6964  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6965  matrix_(row_+element->index(),column_+j) += element->value();
6966 }
6968 //*************************************************************************************************
6969 
6970 
6971 //*************************************************************************************************
6983 template< typename MT > // Type of the dense matrix
6984 template< typename MT2 > // Type of the right-hand side sparse matrix
6985 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
6986 {
6989 
6990  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6991  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6992 
6993  for( size_t i=0UL; i<m_; ++i )
6994  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6995  matrix_(row_+i,column_+element->index()) += element->value();
6996 }
6998 //*************************************************************************************************
6999 
7000 
7001 //*************************************************************************************************
7013 template< typename MT > // Type of the dense matrix
7014 template< typename MT2 > // Type of the right-hand side dense matrix
7015 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
7016  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
7017 {
7019 
7020  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7021  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7022 
7023  const size_t ipos( m_ & size_t(-2) );
7024  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
7025 
7026  for( size_t j=0UL; j<n_; ++j ) {
7027  for( size_t i=0UL; i<ipos; i+=2UL ) {
7028  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
7029  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
7030  }
7031  if( ipos < m_ ) {
7032  matrix_(row_+ipos,column_+j) -= (~rhs)(ipos,j);
7033  }
7034  }
7035 }
7037 //*************************************************************************************************
7038 
7039 
7040 //*************************************************************************************************
7052 template< typename MT > // Type of the dense matrix
7053 template< typename MT2 > // Type of the right-hand side dense matrix
7054 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
7055  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
7056 {
7059 
7060  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7061  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7062 
7063  const size_t ipos( m_ & size_t(-IT::size*4) );
7064  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ipos, "Invalid end calculation" );
7065 
7066  for( size_t j=0UL; j<n_; ++j ) {
7067  typename MT2::ConstIterator it( (~rhs).begin(j) );
7068  for( size_t i=0UL; i<ipos; i+=IT::size*4UL ) {
7069  matrix_.storeu( row_+i , column_+j, load(i ,j) - it.load() ); it += IT::size;
7070  matrix_.storeu( row_+i+IT::size , column_+j, load(i+IT::size ,j) - it.load() ); it += IT::size;
7071  matrix_.storeu( row_+i+IT::size*2UL, column_+j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
7072  matrix_.storeu( row_+i+IT::size*3UL, column_+j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
7073  }
7074  for( size_t i=ipos; i<m_; i+=IT::size, it+=IT::size ) {
7075  storeu( i, j, load(i,j) - it.load() );
7076  }
7077  }
7078 }
7080 //*************************************************************************************************
7081 
7082 
7083 //*************************************************************************************************
7095 template< typename MT > // Type of the dense matrix
7096 template< typename MT2 > // Type of the right-hand side dense matrix
7097 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
7098 {
7101 
7102  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7103  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7104 
7105  const size_t block( 16UL );
7106 
7107  for( size_t jj=0UL; jj<n_; jj+=block ) {
7108  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
7109  for( size_t ii=0UL; ii<m_; ii+=block ) {
7110  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
7111  for( size_t j=jj; j<jend; ++j ) {
7112  for( size_t i=ii; i<iend; ++i ) {
7113  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
7114  }
7115  }
7116  }
7117  }
7118 }
7120 //*************************************************************************************************
7121 
7122 
7123 //*************************************************************************************************
7135 template< typename MT > // Type of the dense matrix
7136 template< typename MT2 > // Type of the right-hand side sparse matrix
7137 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
7138 {
7140 
7141  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7142  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7143 
7144  for( size_t j=0UL; j<n_; ++j )
7145  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
7146  matrix_(row_+element->index(),column_+j) -= element->value();
7147 }
7149 //*************************************************************************************************
7150 
7151 
7152 //*************************************************************************************************
7164 template< typename MT > // Type of the dense matrix
7165 template< typename MT2 > // Type of the right-hand side sparse matrix
7166 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
7167 {
7170 
7171  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
7172  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
7173 
7174  for( size_t i=0UL; i<m_; ++i )
7175  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
7176  matrix_(row_+i,column_+element->index()) -= element->value();
7177 }
7179 //*************************************************************************************************
7180 
7181 
7182 
7183 
7184 
7185 
7186 
7187 
7188 //=================================================================================================
7189 //
7190 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED ROW-MAJOR SUBMATRICES
7191 //
7192 //=================================================================================================
7193 
7194 //*************************************************************************************************
7202 template< typename MT > // Type of the dense matrix
7203 class DenseSubmatrix<MT,aligned,false> : public DenseMatrix< DenseSubmatrix<MT,aligned,false>, false >
7204  , private Submatrix
7205 {
7206  private:
7207  //**Type definitions****************************************************************************
7209  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
7210 
7212  typedef IntrinsicTrait<typename MT::ElementType> IT;
7213  //**********************************************************************************************
7214 
7215  //**********************************************************************************************
7217 
7223  enum { useConst = IsConst<MT>::value };
7224  //**********************************************************************************************
7225 
7226  public:
7227  //**Type definitions****************************************************************************
7228  typedef DenseSubmatrix<MT,aligned,false> This;
7229  typedef typename SubmatrixTrait<MT>::Type ResultType;
7230  typedef typename ResultType::OppositeType OppositeType;
7231  typedef typename ResultType::TransposeType TransposeType;
7232  typedef typename MT::ElementType ElementType;
7233  typedef typename IT::Type IntrinsicType;
7234  typedef typename MT::ReturnType ReturnType;
7235  typedef const DenseSubmatrix& CompositeType;
7236 
7238  typedef typename MT::ConstReference ConstReference;
7239 
7241  typedef typename IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference;
7242 
7244  typedef const ElementType* ConstPointer;
7245 
7247  typedef typename IfTrue< useConst, ConstPointer, ElementType* >::Type Pointer;
7248 
7250  typedef typename MT::ConstIterator ConstIterator;
7251 
7253  typedef typename IfTrue< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
7254  //**********************************************************************************************
7255 
7256  //**Compilation flags***************************************************************************
7258  enum { vectorizable = MT::vectorizable };
7259 
7261  enum { smpAssignable = MT::smpAssignable };
7262  //**********************************************************************************************
7263 
7264  //**Constructors********************************************************************************
7267  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
7268  // No explicitly declared copy constructor.
7270  //**********************************************************************************************
7271 
7272  //**Destructor**********************************************************************************
7273  // No explicitly declared destructor.
7274  //**********************************************************************************************
7275 
7276  //**Data access functions***********************************************************************
7279  inline Reference operator()( size_t i, size_t j );
7280  inline ConstReference operator()( size_t i, size_t j ) const;
7281  inline Pointer data ();
7282  inline ConstPointer data () const;
7283  inline Iterator begin ( size_t i );
7284  inline ConstIterator begin ( size_t i ) const;
7285  inline ConstIterator cbegin( size_t i ) const;
7286  inline Iterator end ( size_t i );
7287  inline ConstIterator end ( size_t i ) const;
7288  inline ConstIterator cend ( size_t i ) const;
7290  //**********************************************************************************************
7291 
7292  //**Assignment operators************************************************************************
7295  inline DenseSubmatrix& operator=( const ElementType& rhs );
7296  inline DenseSubmatrix& operator=( const DenseSubmatrix& rhs );
7297 
7298  template< typename MT2, bool SO >
7299  inline DenseSubmatrix& operator=( const Matrix<MT2,SO>& rhs );
7300 
7301  template< typename MT2, bool SO >
7302  inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
7303  operator=( const Matrix<MT2,SO>& rhs );
7304 
7305  template< typename MT2, bool SO >
7306  inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
7307  operator+=( const Matrix<MT2,SO>& rhs );
7308 
7309  template< typename MT2, bool SO >
7310  inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
7311  operator+=( const Matrix<MT2,SO>& rhs );
7312 
7313  template< typename MT2, bool SO >
7314  inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
7315  operator-=( const Matrix<MT2,SO>& rhs );
7316 
7317  template< typename MT2, bool SO >
7318  inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
7319  operator-=( const Matrix<MT2,SO>& rhs );
7320 
7321  template< typename MT2, bool SO >
7322  inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
7323 
7324  template< typename Other >
7325  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
7326  operator*=( Other rhs );
7327 
7328  template< typename Other >
7329  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
7330  operator/=( Other rhs );
7332  //**********************************************************************************************
7333 
7334  //**Utility functions***************************************************************************
7337  inline size_t rows() const;
7338  inline size_t columns() const;
7339  inline size_t spacing() const;
7340  inline size_t capacity() const;
7341  inline size_t capacity( size_t i ) const;
7342  inline size_t nonZeros() const;
7343  inline size_t nonZeros( size_t i ) const;
7344  inline void reset();
7345  inline void reset( size_t i );
7346  inline DenseSubmatrix& transpose();
7347  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
7349  //**********************************************************************************************
7350 
7351  private:
7352  //**********************************************************************************************
7354  template< typename MT2 >
7355  struct VectorizedAssign {
7356  enum { value = vectorizable && MT2::vectorizable &&
7357  IsSame<ElementType,typename MT2::ElementType>::value };
7358  };
7359  //**********************************************************************************************
7360 
7361  //**********************************************************************************************
7363  template< typename MT2 >
7364  struct VectorizedAddAssign {
7365  enum { value = vectorizable && MT2::vectorizable &&
7366  IsSame<ElementType,typename MT2::ElementType>::value &&
7367  IntrinsicTrait<ElementType>::addition };
7368  };
7369  //**********************************************************************************************
7370 
7371  //**********************************************************************************************
7373  template< typename MT2 >
7374  struct VectorizedSubAssign {
7375  enum { value = vectorizable && MT2::vectorizable &&
7376  IsSame<ElementType,typename MT2::ElementType>::value &&
7377  IntrinsicTrait<ElementType>::subtraction };
7378  };
7379  //**********************************************************************************************
7380 
7381  public:
7382  //**Expression template evaluation functions****************************************************
7385  template< typename Other >
7386  inline bool canAlias( const Other* alias ) const;
7387 
7388  template< typename MT2, bool AF2, bool SO2 >
7389  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
7390 
7391  template< typename Other >
7392  inline bool isAliased( const Other* alias ) const;
7393 
7394  template< typename MT2, bool AF2, bool SO2 >
7395  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
7396 
7397  inline bool isAligned () const;
7398  inline bool canSMPAssign() const;
7399 
7400  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
7401  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
7402 
7403  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
7404  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
7405  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
7406 
7407  template< typename MT2 >
7408  inline typename DisableIf< VectorizedAssign<MT2> >::Type
7409  assign( const DenseMatrix<MT2,false>& rhs );
7410 
7411  template< typename MT2 >
7412  inline typename EnableIf< VectorizedAssign<MT2> >::Type
7413  assign( const DenseMatrix<MT2,false>& rhs );
7414 
7415  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
7416  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
7417  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
7418 
7419  template< typename MT2 >
7420  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
7421  addAssign( const DenseMatrix<MT2,false>& rhs );
7422 
7423  template< typename MT2 >
7424  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
7425  addAssign( const DenseMatrix<MT2,false>& rhs );
7426 
7427  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
7428  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
7429  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
7430 
7431  template< typename MT2 >
7432  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
7433  subAssign( const DenseMatrix<MT2,false>& rhs );
7434 
7435  template< typename MT2 >
7436  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
7437  subAssign( const DenseMatrix<MT2,false>& rhs );
7438 
7439  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
7440  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
7441  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
7443  //**********************************************************************************************
7444 
7445  private:
7446  //**Utility functions***************************************************************************
7449  inline bool hasOverlap() const;
7450 
7451  template< typename MT2, bool SO2, typename MT3, bool SO3 >
7452  inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
7453  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
7454 
7455  template< typename MT2, bool SO2, typename MT3, bool SO3 >
7456  inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
7457  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
7458 
7459  template< typename MT2, bool SO2, typename MT3 >
7460  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
7461  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
7462 
7463  template< typename MT2, bool SO2, typename MT3 >
7464  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
7465  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
7466 
7467  template< typename MT2, bool SO2, typename MT3 >
7468  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
7469  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
7470 
7471  template< typename MT2, bool SO2, typename MT3 >
7472  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
7473  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
7474 
7475  template< typename MT2, bool SO2, typename MT3 >
7476  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
7477  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
7478 
7479  template< typename MT2, bool SO2, typename MT3 >
7480  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
7481  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
7482 
7483  template< typename MT2, bool SO2, typename MT3 >
7484  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
7485  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
7486 
7487  template< typename MT2, bool SO2, typename MT3 >
7488  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
7489  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
7490 
7491  template< typename MT2, bool SO2, typename MT3 >
7492  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
7493  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
7494 
7495  template< typename MT2, bool SO2, typename MT3 >
7496  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
7497  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
7498 
7499  template< typename MT2, bool SO2, typename MT3 >
7500  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
7501  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
7502 
7503  template< typename MT2, bool SO2, typename MT3 >
7504  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
7505  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
7507  //**********************************************************************************************
7508 
7509  //**Member variables****************************************************************************
7512  Operand matrix_;
7513  const size_t row_;
7514  const size_t column_;
7515  const size_t m_;
7516  const size_t n_;
7517 
7518  //**********************************************************************************************
7519 
7520  //**Friend declarations*************************************************************************
7521  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
7522 
7523  template< bool AF1, typename MT2, bool AF2, bool SO2 >
7524  friend const DenseSubmatrix<MT2,AF1,SO2>
7525  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
7526 
7527  template< typename MT2, bool AF2, bool SO2 >
7528  friend bool isSymmetric( const DenseSubmatrix<MT2,AF2,SO2>& dm );
7529 
7530  template< typename MT2, bool AF2, bool SO2 >
7531  friend bool isLower( const DenseSubmatrix<MT2,AF2,SO2>& dm );
7532 
7533  template< typename MT2, bool AF2, bool SO2 >
7534  friend bool isUpper( const DenseSubmatrix<MT2,AF2,SO2>& dm );
7535 
7536  template< typename MT2, bool AF2, bool SO2 >
7537  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
7538 
7539  template< typename MT2, bool AF2, bool SO2 >
7540  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
7541 
7542  template< typename MT2, bool AF2, bool SO2 >
7543  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
7544 
7545  template< typename MT2, bool AF2, bool SO2 >
7546  friend typename DerestrictTrait< DenseSubmatrix<MT2,AF2,SO2> >::Type
7547  derestrict( DenseSubmatrix<MT2,AF2,SO2>& dm );
7548  //**********************************************************************************************
7549 
7550  //**Compile time checks*************************************************************************
7558  BLAZE_STATIC_ASSERT( !IsRestricted<MT>::value || IsLower<MT>::value || IsUpper<MT>::value );
7559  //**********************************************************************************************
7560 };
7562 //*************************************************************************************************
7563 
7564 
7565 
7566 
7567 //=================================================================================================
7568 //
7569 // CONSTRUCTOR
7570 //
7571 //=================================================================================================
7572 
7573 //*************************************************************************************************
7587 template< typename MT > // Type of the dense matrix
7588 inline DenseSubmatrix<MT,aligned,false>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
7589  : matrix_( matrix ) // The dense matrix containing the submatrix
7590  , row_ ( row ) // The first row of the submatrix
7591  , column_( column ) // The first column of the submatrix
7592  , m_ ( m ) // The number of rows of the submatrix
7593  , n_ ( n ) // The number of columns of the submatrix
7594 {
7595  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
7596  throw std::invalid_argument( "Invalid submatrix specification" );
7597 
7598  if( column % IT::size != 0UL || ( column_ + n_ != matrix_.columns() && n_ % IT::size != 0UL ) )
7599  throw std::invalid_argument( "Invalid submatrix alignment" );
7600 }
7602 //*************************************************************************************************
7603 
7604 
7605 
7606 
7607 //=================================================================================================
7608 //
7609 // DATA ACCESS FUNCTIONS
7610 //
7611 //=================================================================================================
7612 
7613 //*************************************************************************************************
7621 template< typename MT > // Type of the dense matrix
7623  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j )
7624 {
7625  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
7626  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7627 
7628  return matrix_(row_+i,column_+j);
7629 }
7631 //*************************************************************************************************
7632 
7633 
7634 //*************************************************************************************************
7642 template< typename MT > // Type of the dense matrix
7644  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j ) const
7645 {
7646  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
7647  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
7648 
7649  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
7650 }
7652 //*************************************************************************************************
7653 
7654 
7655 //*************************************************************************************************
7665 template< typename MT > // Type of the dense matrix
7666 inline typename DenseSubmatrix<MT,aligned,false>::Pointer DenseSubmatrix<MT,aligned,false>::data()
7667 {
7668  return matrix_.data() + row_*spacing() + column_;
7669 }
7671 //*************************************************************************************************
7672 
7673 
7674 //*************************************************************************************************
7684 template< typename MT > // Type of the dense matrix
7685 inline typename DenseSubmatrix<MT,aligned,false>::ConstPointer
7687 {
7688  return matrix_.data() + row_*spacing() + column_;
7689 }
7691 //*************************************************************************************************
7692 
7693 
7694 //*************************************************************************************************
7706 template< typename MT > // Type of the dense matrix
7709 {
7710  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
7711  return ( matrix_.begin( row_ + i ) + column_ );
7712 }
7714 //*************************************************************************************************
7715 
7716 
7717 //*************************************************************************************************
7729 template< typename MT > // Type of the dense matrix
7731  DenseSubmatrix<MT,aligned,false>::begin( size_t i ) const
7732 {
7733  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
7734  return ( matrix_.cbegin( row_ + i ) + column_ );
7735 }
7737 //*************************************************************************************************
7738 
7739 
7740 //*************************************************************************************************
7752 template< typename MT > // Type of the dense matrix
7755 {
7756  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
7757  return ( matrix_.cbegin( row_ + i ) + column_ );
7758 }
7760 //*************************************************************************************************
7761 
7762 
7763 //*************************************************************************************************
7775 template< typename MT > // Type of the dense matrix
7778 {
7779  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
7780  return ( matrix_.begin( row_ + i ) + column_ + n_ );
7781 }
7783 //*************************************************************************************************
7784 
7785 
7786 //*************************************************************************************************
7798 template< typename MT > // Type of the dense matrix
7800  DenseSubmatrix<MT,aligned,false>::end( size_t i ) const
7801 {
7802  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
7803  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
7804 }
7806 //*************************************************************************************************
7807 
7808 
7809 //*************************************************************************************************
7821 template< typename MT > // Type of the dense matrix
7823  DenseSubmatrix<MT,aligned,false>::cend( size_t i ) const
7824 {
7825  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
7826  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
7827 }
7829 //*************************************************************************************************
7830 
7831 
7832 
7833 
7834 //=================================================================================================
7835 //
7836 // ASSIGNMENT OPERATORS
7837 //
7838 //=================================================================================================
7839 
7840 //*************************************************************************************************
7851 template< typename MT > // Type of the dense matrix
7852 inline DenseSubmatrix<MT,aligned,false>&
7853  DenseSubmatrix<MT,aligned,false>::operator=( const ElementType& rhs )
7854 {
7855  const size_t iend( row_ + m_ );
7856 
7857  for( size_t i=row_; i<iend; ++i )
7858  {
7859  const size_t jbegin( ( IsUpper<MT>::value )
7860  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
7861  ?( max( i+1UL, column_ ) )
7862  :( max( i, column_ ) ) )
7863  :( column_ ) );
7864  const size_t jend ( ( IsLower<MT>::value )
7865  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
7866  ?( min( i, column_+n_ ) )
7867  :( min( i+1UL, column_+n_ ) ) )
7868  :( column_+n_ ) );
7869 
7870  for( size_t j=jbegin; j<jend; ++j )
7871  matrix_(i,j) = rhs;
7872  }
7873 
7874  return *this;
7875 }
7877 //*************************************************************************************************
7878 
7879 
7880 //*************************************************************************************************
7895 template< typename MT > // Type of the dense matrix
7896 inline DenseSubmatrix<MT,aligned,false>&
7897  DenseSubmatrix<MT,aligned,false>::operator=( const DenseSubmatrix& rhs )
7898 {
7901 
7902  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
7903  return *this;
7904 
7905  if( rows() != rhs.rows() || columns() != rhs.columns() )
7906  throw std::invalid_argument( "Submatrix sizes do not match" );
7907 
7908  if( !preservesInvariant( matrix_, rhs ) )
7909  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
7910 
7911  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7912 
7913  if( rhs.canAlias( &matrix_ ) ) {
7914  const ResultType tmp( rhs );
7915  smpAssign( left, tmp );
7916  }
7917  else {
7918  smpAssign( left, rhs );
7919  }
7920 
7921  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
7922  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
7923  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
7924 
7925  return *this;
7926 }
7928 //*************************************************************************************************
7929 
7930 
7931 //*************************************************************************************************
7946 template< typename MT > // Type of the dense matrix
7947 template< typename MT2 // Type of the right-hand side matrix
7948  , bool SO > // Storage order of the right-hand side matrix
7949 inline DenseSubmatrix<MT,aligned,false>&
7950  DenseSubmatrix<MT,aligned,false>::operator=( const Matrix<MT2,SO>& rhs )
7951 {
7953 
7954  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
7955  throw std::invalid_argument( "Matrix sizes do not match" );
7956 
7957  typedef typename If< IsAdaptor<MT>, typename MT2::CompositeType, const MT2& >::Type Right;
7958  Right right( ~rhs );
7959 
7960  if( !preservesInvariant( matrix_, right ) )
7961  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
7962 
7963  if( IsSparseMatrix<MT2>::value )
7964  reset();
7965 
7966  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7967 
7968  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
7969  const typename MT2::ResultType tmp( right );
7970  smpAssign( left, tmp );
7971  }
7972  else {
7973  smpAssign( left, right );
7974  }
7975 
7976  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
7977  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
7978  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
7979 
7980  return *this;
7981 }
7983 //*************************************************************************************************
7984 
7985 
7986 //*************************************************************************************************
8000 template< typename MT > // Type of the dense matrix
8001 template< typename MT2 // Type of the right-hand side matrix
8002  , bool SO > // Storage order of the right-hand side matrix
8003 inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
8004  , DenseSubmatrix<MT,aligned,false>& >::Type
8005  DenseSubmatrix<MT,aligned,false>::operator+=( const Matrix<MT2,SO>& rhs )
8006 {
8010 
8011  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
8012 
8015 
8016  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
8017  throw std::invalid_argument( "Matrix sizes do not match" );
8018 
8019  if( !preservesInvariant( matrix_, ~rhs ) )
8020  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
8021 
8022  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
8023 
8024  if( ( IsSymmetric<MT>::value && hasOverlap() ) || (~rhs).canAlias( &matrix_ ) ) {
8025  const AddType tmp( *this + (~rhs) );
8026  smpAssign( left, tmp );
8027  }
8028  else {
8029  smpAddAssign( left, ~rhs );
8030  }
8031 
8032  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
8033  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
8034  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
8035 
8036  return *this;
8037 }
8039 //*************************************************************************************************
8040 
8041 
8042 //*************************************************************************************************
8056 template< typename MT > // Type of the dense matrix
8057 template< typename MT2 // Type of the right-hand side matrix
8058  , bool SO > // Storage order of the right-hand side matrix
8059 inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
8060  , DenseSubmatrix<MT,aligned,false>& >::Type
8061  DenseSubmatrix<MT,aligned,false>::operator+=( const Matrix<MT2,SO>& rhs )
8062 {
8066 
8067  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
8068 
8071 
8072  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
8073  throw std::invalid_argument( "Matrix sizes do not match" );
8074 
8075  const AddType tmp( *this + (~rhs) );
8076 
8077  if( !preservesInvariant( matrix_, tmp ) )
8078  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
8079 
8080  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
8081 
8082  smpAssign( left, tmp );
8083 
8084  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
8085  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
8086  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
8087 
8088  return *this;
8089 }
8091 //*************************************************************************************************
8092 
8093 
8094 //*************************************************************************************************
8108 template< typename MT > // Type of the dense matrix
8109 template< typename MT2 // Type of the right-hand side matrix
8110  , bool SO > // Storage order of the right-hand side matrix
8111 inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
8112  , DenseSubmatrix<MT,aligned,false>& >::Type
8113  DenseSubmatrix<MT,aligned,false>::operator-=( const Matrix<MT2,SO>& rhs )
8114 {
8118 
8119  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
8120 
8123 
8124  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
8125  throw std::invalid_argument( "Matrix sizes do not match" );
8126 
8127  if( !preservesInvariant( matrix_, ~rhs ) )
8128  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
8129 
8130  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
8131 
8132  if( ( IsSymmetric<MT>::value && hasOverlap() ) || (~rhs).canAlias( &matrix_ ) ) {
8133  const SubType tmp( *this - (~rhs ) );
8134  smpAssign( left, tmp );
8135  }
8136  else {
8137  smpSubAssign( left, ~rhs );
8138  }
8139 
8140  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
8141  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
8142  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
8143 
8144  return *this;
8145 }
8147 //*************************************************************************************************
8148 
8149 
8150 //*************************************************************************************************
8164 template< typename MT > // Type of the dense matrix
8165 template< typename MT2 // Type of the right-hand side matrix
8166  , bool SO > // Storage order of the right-hand side matrix
8167 inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
8168  , DenseSubmatrix<MT,aligned,false>& >::Type
8169  DenseSubmatrix<MT,aligned,false>::operator-=( const Matrix<MT2,SO>& rhs )
8170 {
8174 
8175  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
8176 
8179 
8180  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
8181  throw std::invalid_argument( "Matrix sizes do not match" );
8182 
8183  const SubType tmp( *this - (~rhs) );
8184 
8185  if( !preservesInvariant( matrix_, tmp ) )
8186  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
8187 
8188  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
8189 
8190  smpAssign( left, tmp );
8191 
8192  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
8193  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
8194  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
8195 
8196  return *this;
8197 }
8199 //*************************************************************************************************
8200 
8201 
8202 //*************************************************************************************************
8216 template< typename MT > // Type of the dense matrix
8217 template< typename MT2 // Type of the right-hand side matrix
8218  , bool SO > // Storage order of the right-hand side matrix
8219 inline DenseSubmatrix<MT,aligned,false>&
8220  DenseSubmatrix<MT,aligned,false>::operator*=( const Matrix<MT2,SO>& rhs )
8221 {
8225 
8226  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
8227 
8230 
8231  if( columns() != (~rhs).rows() )
8232  throw std::invalid_argument( "Matrix sizes do not match" );
8233 
8234  const MultType tmp( *this * (~rhs) );
8235 
8236  if( !preservesInvariant( matrix_, tmp ) )
8237  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
8238 
8239  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
8240 
8241  smpAssign( left, tmp );
8242 
8243  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
8244  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
8245  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
8246 
8247  return *this;
8248 }
8250 //*************************************************************************************************
8251 
8252 
8253 //*************************************************************************************************
8264 template< typename MT > // Type of the dense matrix
8265 template< typename Other > // Data type of the right-hand side scalar
8266 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
8267  DenseSubmatrix<MT,aligned,false>::operator*=( Other rhs )
8268 {
8270 
8271  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
8272  smpAssign( left, (*this) * rhs );
8273 
8274  return *this;
8275 }
8277 //*************************************************************************************************
8278 
8279 
8280 //*************************************************************************************************
8293 template< typename MT > // Type of the dense matrix
8294 template< typename Other > // Data type of the right-hand side scalar
8295 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
8296  DenseSubmatrix<MT,aligned,false>::operator/=( Other rhs )
8297 {
8299 
8300  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
8301 
8302  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
8303  smpAssign( left, (*this) / rhs );
8304 
8305  return *this;
8306 }
8308 //*************************************************************************************************
8309 
8310 
8311 
8312 
8313 //=================================================================================================
8314 //
8315 // UTILITY FUNCTIONS
8316 //
8317 //=================================================================================================
8318 
8319 //*************************************************************************************************
8325 template< typename MT > // Type of the dense matrix
8326 inline size_t DenseSubmatrix<MT,aligned,false>::rows() const
8327 {
8328  return m_;
8329 }
8331 //*************************************************************************************************
8332 
8333 
8334 //*************************************************************************************************
8340 template< typename MT > // Type of the dense matrix
8341 inline size_t DenseSubmatrix<MT,aligned,false>::columns() const
8342 {
8343  return n_;
8344 }
8346 //*************************************************************************************************
8347 
8348 
8349 //*************************************************************************************************
8360 template< typename MT > // Type of the dense matrix
8361 inline size_t DenseSubmatrix<MT,aligned,false>::spacing() const
8362 {
8363  return matrix_.spacing();
8364 }
8366 //*************************************************************************************************
8367 
8368 
8369 //*************************************************************************************************
8375 template< typename MT > // Type of the dense matrix
8376 inline size_t DenseSubmatrix<MT,aligned,false>::capacity() const
8377 {
8378  return rows() * columns();
8379 }
8381 //*************************************************************************************************
8382 
8383 
8384 //*************************************************************************************************
8396 template< typename MT > // Type of the dense matrix
8397 inline size_t DenseSubmatrix<MT,aligned,false>::capacity( size_t i ) const
8398 {
8399  UNUSED_PARAMETER( i );
8400 
8401  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
8402 
8403  return columns();
8404 }
8406 //*************************************************************************************************
8407 
8408 
8409 //*************************************************************************************************
8415 template< typename MT > // Type of the dense matrix
8416 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros() const
8417 {
8418  const size_t iend( row_ + m_ );
8419  const size_t jend( column_ + n_ );
8420  size_t nonzeros( 0UL );
8421 
8422  for( size_t i=row_; i<iend; ++i )
8423  for( size_t j=column_; j<jend; ++j )
8424  if( !isDefault( matrix_(i,j) ) )
8425  ++nonzeros;
8426 
8427  return nonzeros;
8428 }
8430 //*************************************************************************************************
8431 
8432 
8433 //*************************************************************************************************
8445 template< typename MT > // Type of the dense matrix
8446 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros( size_t i ) const
8447 {
8448  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
8449 
8450  const size_t jend( column_ + n_ );
8451  size_t nonzeros( 0UL );
8452 
8453  for( size_t j=column_; j<jend; ++j )
8454  if( !isDefault( matrix_(row_+i,j) ) )
8455  ++nonzeros;
8456 
8457  return nonzeros;
8458 }
8460 //*************************************************************************************************
8461 
8462 
8463 //*************************************************************************************************
8469 template< typename MT > // Type of the dense matrix
8471 {
8472  using blaze::clear;
8473 
8474  for( size_t i=row_; i<row_+m_; ++i )
8475  {
8476  const size_t jbegin( ( IsUpper<MT>::value )
8477  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
8478  ?( max( i+1UL, column_ ) )
8479  :( max( i, column_ ) ) )
8480  :( column_ ) );
8481  const size_t jend ( ( IsLower<MT>::value )
8482  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
8483  ?( min( i, column_+n_ ) )
8484  :( min( i+1UL, column_+n_ ) ) )
8485  :( column_+n_ ) );
8486 
8487  for( size_t j=jbegin; j<jend; ++j )
8488  clear( matrix_(i,j) );
8489  }
8490 }
8492 //*************************************************************************************************
8493 
8494 
8495 //*************************************************************************************************
8507 template< typename MT > // Type of the dense matrix
8508 inline void DenseSubmatrix<MT,aligned,false>::reset( size_t i )
8509 {
8510  using blaze::clear;
8511 
8512  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
8513 
8514  const size_t jbegin( ( IsUpper<MT>::value )
8515  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
8516  ?( max( i+1UL, column_ ) )
8517  :( max( i, column_ ) ) )
8518  :( column_ ) );
8519  const size_t jend ( ( IsLower<MT>::value )
8520  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
8521  ?( min( i, column_+n_ ) )
8522  :( min( i+1UL, column_+n_ ) ) )
8523  :( column_+n_ ) );
8524 
8525  for( size_t j=jbegin; j<jend; ++j )
8526  clear( matrix_(row_+i,j) );
8527 }
8529 //*************************************************************************************************
8530 
8531 
8532 //*************************************************************************************************
8548 template< typename MT > // Type of the dense matrix
8549 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::transpose()
8550 {
8551  if( rows() != columns() )
8552  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
8553 
8554  if( IsLower<MT>::value && ( row_ + 1UL < column_ + n_ ) )
8555  throw std::runtime_error( "Invalid transpose of a lower matrix" );
8556 
8557  if( IsUpper<MT>::value && ( column_ + 1UL < row_ + m_ ) )
8558  throw std::runtime_error( "Invalid transpose of an upper matrix" );
8559 
8560  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
8561  const ResultType tmp( trans(*this) );
8562  smpAssign( left, tmp );
8563 
8564  return *this;
8565 }
8567 //*************************************************************************************************
8568 
8569 
8570 //*************************************************************************************************
8581 template< typename MT > // Type of the dense matrix
8582 template< typename Other > // Data type of the scalar value
8583 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::scale( const Other& scalar )
8584 {
8586 
8587  const size_t iend( row_ + m_ );
8588 
8589  for( size_t i=row_; i<iend; ++i )
8590  {
8591  const size_t jbegin( ( IsUpper<MT>::value )
8592  ?( ( IsStrictlyUpper<MT>::value )
8593  ?( max( i+1UL, column_ ) )
8594  :( max( i, column_ ) ) )
8595  :( column_ ) );
8596  const size_t jend ( ( IsLower<MT>::value )
8597  ?( ( IsStrictlyLower<MT>::value )
8598  ?( min( i, column_+n_ ) )
8599  :( min( i+1UL, column_+n_ ) ) )
8600  :( column_+n_ ) );
8601 
8602  for( size_t j=jbegin; j<jend; ++j )
8603  matrix_(i,j) *= scalar;
8604  }
8605 
8606  return *this;
8607 }
8609 //*************************************************************************************************
8610 
8611 
8612 //*************************************************************************************************
8622 template< typename MT > // Type of the dense matrix
8624 {
8625  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
8626 
8627  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
8628  return false;
8629  else return true;
8630 }
8632 //*************************************************************************************************
8633 
8634 
8635 //*************************************************************************************************
8647 template< typename MT > // Type of the dense matrix
8648 template< typename MT2 // Type of the left-hand side dense matrix
8649  , bool SO2 // Storage order of the left-hand side dense matrix
8650  , typename MT3 // Type of the right-hand side matrix
8651  , bool SO3 > // Storage order of the right-hand side matrix
8652 inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
8653  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs )
8654 {
8655  UNUSED_PARAMETER( lhs, rhs );
8656 
8657  return true;
8658 }
8660 //*************************************************************************************************
8661 
8662 
8663 //*************************************************************************************************
8675 template< typename MT > // Type of the dense matrix
8676 template< typename MT2 // Type of the left-hand side dense matrix
8677  , bool SO2 // Storage order of the left-hand side dense matrix
8678  , typename MT3 // Type of the right-hand side matrix
8679  , bool SO3 > // Storage order of the right-hand side matrix
8680 inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
8681  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs )
8682 {
8684 
8685  UNUSED_PARAMETER( lhs );
8686 
8687  if( !hasOverlap() )
8688  return true;
8689 
8690  const bool lower( row_ > column_ );
8691  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
8692 
8693  if( size < 2UL )
8694  return true;
8695 
8696  const size_t row ( lower ? 0UL : column_ - row_ );
8697  const size_t column( lower ? row_ - column_ : 0UL );
8698 
8699  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
8700 }
8702 //*************************************************************************************************
8703 
8704 
8705 //*************************************************************************************************
8718 template< typename MT > // Type of the dense matrix
8719 template< typename MT2 // Type of the left-hand side dense matrix
8720  , bool SO2 // Storage order of the left-hand side dense matrix
8721  , typename MT3 > // Type of the right-hand side dense matrix
8722 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
8723  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
8724 {
8726 
8727  UNUSED_PARAMETER( lhs );
8728 
8729  if( row_ + 1UL >= column_ + n_ )
8730  return true;
8731 
8732  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
8733  ?( column_ + n_ - row_ )
8734  :( column_ + n_ - row_ - 1UL ) );
8735  const size_t iend( min( ipos, m_ ) );
8736 
8737  for( size_t i=0UL; i<iend; ++i )
8738  {
8739  const bool containsDiagonal( row_+i >= column_ );
8740 
8741  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
8742  return false;
8743 
8744  const size_t jbegin( ( containsDiagonal )
8745  ?( ( IsStrictlyLower<MT2>::value )
8746  ?( row_ + i - column_ )
8747  :( row_ + i - column_ + 1UL ) )
8748  :( 0UL ) );
8749 
8750  for( size_t j=jbegin; j<n_; ++j ) {
8751  if( !isDefault( (~rhs)(i,j) ) )
8752  return false;
8753  }
8754  }
8755 
8756  return true;
8757 }
8759 //*************************************************************************************************
8760 
8761 
8762 //*************************************************************************************************
8775 template< typename MT > // Type of the dense matrix
8776 template< typename MT2 // Type of the left-hand side dense matrix
8777  , bool SO2 // Storage order of the left-hand side dense matrix
8778  , typename MT3 > // Type of the right-hand side dense matrix
8779 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
8780  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
8781 {
8783 
8784  UNUSED_PARAMETER( lhs );
8785 
8786  if( row_ + 1UL >= column_ + n_ )
8787  return true;
8788 
8789  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
8790  ?( row_ - column_ )
8791  :( row_ - column_ + 1UL ) );
8792  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
8793 
8794  for( size_t j=jbegin; j<n_; ++j )
8795  {
8796  const bool containsDiagonal( column_+j < row_+m_ );
8797 
8798  const size_t ipos( ( IsStrictlyLower<MT2>::value && containsDiagonal )
8799  ?( column_ + j - row_ + 1UL )
8800  :( column_ + j - row_ ) );
8801  const size_t iend( min( ipos, m_ ) );
8802 
8803  for( size_t i=0UL; i<iend; ++i ) {
8804  if( !isDefault( (~rhs)(i,j) ) )
8805  return false;
8806  }
8807 
8808  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
8809  return false;
8810  }
8811 
8812  return true;
8813 }
8815 //*************************************************************************************************
8816 
8817 
8818 //*************************************************************************************************
8831 template< typename MT > // Type of the dense matrix
8832 template< typename MT2 // Type of the left-hand side dense matrix
8833  , bool SO2 // Storage order of the left-hand side dense matrix
8834  , typename MT3 > // Type of the right-hand side sparse matrix
8835 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
8836  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
8837 {
8839 
8840  UNUSED_PARAMETER( lhs );
8841 
8842  typedef typename MT3::ConstIterator RhsIterator;
8843 
8844  if( row_ + 1UL >= column_ + n_ )
8845  return true;
8846 
8847  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
8848  ?( column_ + n_ - row_ )
8849  :( column_ + n_ - row_ - 1UL ) );
8850  const size_t iend( min( ipos, m_ ) );
8851 
8852  for( size_t i=0UL; i<iend; ++i )
8853  {
8854  const bool containsDiagonal( row_+i >= column_ );
8855 
8856  const size_t index( ( containsDiagonal )
8857  ?( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
8858  ?( row_ + i - column_ )
8859  :( row_ + i - column_ + 1UL ) )
8860  :( 0UL ) );
8861 
8862  const RhsIterator last( (~rhs).end(i) );
8863  RhsIterator element( (~rhs).lowerBound( i, index ) );
8864 
8865  if( IsUniLower<MT2>::value && containsDiagonal ) {
8866  if( element == last || ( element->index() != row_+i-column_ ) || !isOne( element->value() ) )
8867  return false;
8868  ++element;
8869  }
8870 
8871  for( ; element!=last; ++element ) {
8872  if( !isDefault( element->value() ) )
8873  return false;
8874  }
8875  }
8876 
8877  return true;
8878 }
8880 //*************************************************************************************************
8881 
8882 
8883 //*************************************************************************************************
8896 template< typename MT > // Type of the dense matrix
8897 template< typename MT2 // Type of the left-hand side dense matrix
8898  , bool SO2 // Storage order of the left-hand side dense matrix
8899  , typename MT3 > // Type of the right-hand side sparse matrix
8900 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
8901  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
8902 {
8904 
8905  UNUSED_PARAMETER( lhs );
8906 
8907  typedef typename MT3::ConstIterator RhsIterator;
8908 
8909  if( row_ + 1UL >= column_ + n_ )
8910  return true;
8911 
8912  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
8913  ?( row_ - column_ )
8914  :( row_ - column_ + 1UL ) );
8915  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
8916 
8917  for( size_t j=jbegin; j<n_; ++j )
8918  {
8919  const bool containsDiagonal( column_+j < row_+m_ );
8920 
8921  const size_t index( ( IsStrictlyLower<MT2>::value && containsDiagonal )
8922  ?( column_ + j - row_ + 1UL )
8923  :( column_ + j - row_ ) );
8924  const RhsIterator last( (~rhs).lowerBound( min( index, m_ ), j ) );
8925 
8926  if( IsUniLower<MT2>::value && containsDiagonal &&
8927  ( last == (~rhs).end(j) || ( last->index() != column_+j-row_ ) || !isOne( last->value() ) ) ) {
8928  return false;
8929  }
8930 
8931  for( RhsIterator element=(~rhs).begin(j); element!=last; ++element ) {
8932  if( !isDefault( element->value() ) )
8933  return false;
8934  }
8935  }
8936 
8937  return true;
8938 }
8940 //*************************************************************************************************
8941 
8942 
8943 //*************************************************************************************************
8956 template< typename MT > // Type of the dense matrix
8957 template< typename MT2 // Type of the left-hand side dense matrix
8958  , bool SO2 // Storage order of the left-hand side dense matrix
8959  , typename MT3 > // Type of the right-hand side dense matrix
8960 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
8961  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
8962 {
8964 
8965  UNUSED_PARAMETER( lhs );
8966 
8967  if( column_ + 1UL >= row_ + m_ )
8968  return true;
8969 
8970  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
8971  ?( column_ - row_ )
8972  :( column_ - row_ + 1UL ) );
8973  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
8974 
8975  for( size_t i=ibegin; i<m_; ++i )
8976  {
8977  const bool containsDiagonal( row_+i < column_+n_ );
8978 
8979  const size_t jpos( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
8980  ?( row_ + i - column_ + 1UL )
8981  :( row_ + i - column_ ) );
8982  const size_t jend( min( jpos, n_ ) );
8983 
8984  for( size_t j=0UL; j<jend; ++j ) {
8985  if( !isDefault( (~rhs)(i,j) ) )
8986  return false;
8987  }
8988 
8989  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
8990  return false;
8991  }
8992 
8993  return true;
8994 }
8996 //*************************************************************************************************
8997 
8998 
8999 //*************************************************************************************************
9012 template< typename MT > // Type of the dense matrix
9013 template< typename MT2 // Type of the left-hand side dense matrix
9014  , bool SO2 // Storage order of the left-hand side dense matrix
9015  , typename MT3 > // Type of the right-hand side dense matrix
9016 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
9017  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
9018 {
9020 
9021  UNUSED_PARAMETER( lhs );
9022 
9023  if( column_ + 1UL >= row_ + m_ )
9024  return true;
9025 
9026  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
9027  ?( row_ + m_ - column_ )
9028  :( row_ + m_ - column_ - 1UL ) );
9029  const size_t jend( min( jpos, n_ ) );
9030 
9031  for( size_t j=0UL; j<jend; ++j )
9032  {
9033  const bool containsDiagonal( column_+j >= row_ );
9034 
9035  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
9036  return false;
9037 
9038  const size_t ibegin( ( containsDiagonal )
9039  ?( ( IsStrictlyUpper<MT2>::value )
9040  ?( column_ + j - row_ )
9041  :( column_ + j - row_ + 1UL ) )
9042  :( 0UL ) );
9043 
9044  for( size_t i=ibegin; i<m_; ++i ) {
9045  if( !isDefault( (~rhs)(i,j) ) )
9046  return false;
9047  }
9048  }
9049 
9050  return true;
9051 }
9053 //*************************************************************************************************
9054 
9055 
9056 //*************************************************************************************************
9069 template< typename MT > // Type of the dense matrix
9070 template< typename MT2 // Type of the left-hand side dense matrix
9071  , bool SO2 // Storage order of the left-hand side dense matrix
9072  , typename MT3 > // Type of the right-hand side sparse matrix
9073 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
9074  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
9075 {
9077 
9078  UNUSED_PARAMETER( lhs );
9079 
9080  typedef typename MT3::ConstIterator RhsIterator;
9081 
9082  if( column_ + 1UL >= row_ + m_ )
9083  return true;
9084 
9085  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
9086  ?( column_ - row_ )
9087  :( column_ - row_ + 1UL ) );
9088  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
9089 
9090  for( size_t i=ibegin; i<m_; ++i )
9091  {
9092  const bool containsDiagonal( row_+i < column_+n_ );
9093 
9094  const size_t index( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
9095  ?( row_ + i - column_ + 1UL )
9096  :( row_ + i - column_ ) );
9097  const RhsIterator last( (~rhs).lowerBound( i, min( index, n_ ) ) );
9098 
9099  if( IsUniUpper<MT2>::value && containsDiagonal &&
9100  ( last == (~rhs).end(i) || ( last->index() != row_+i-column_ ) || !isOne( last->value() ) ) ) {
9101  return false;
9102  }
9103 
9104  for( RhsIterator element=(~rhs).begin(i); element!=last; ++element ) {
9105  if( !isDefault( element->value() ) )
9106  return false;
9107  }
9108  }
9109 
9110  return true;
9111 }
9113 //*************************************************************************************************
9114 
9115 
9116 //*************************************************************************************************
9129 template< typename MT > // Type of the dense matrix
9130 template< typename MT2 // Type of the left-hand side dense matrix
9131  , bool SO2 // Storage order of the left-hand side dense matrix
9132  , typename MT3 > // Type of the right-hand side sparse matrix
9133 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
9134  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
9135 {
9137 
9138  UNUSED_PARAMETER( lhs );
9139 
9140  typedef typename MT3::ConstIterator RhsIterator;
9141 
9142  if( column_ + 1UL >= row_ + m_ )
9143  return true;
9144 
9145  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
9146  ?( row_ + m_ - column_ )
9147  :( row_ + m_ - column_ - 1UL ) );
9148  const size_t jend( min( jpos, n_ ) );
9149 
9150  for( size_t j=0UL; j<jend; ++j )
9151  {
9152  const bool containsDiagonal( column_+j >= row_ );
9153 
9154  const size_t index( ( containsDiagonal )
9155  ?( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
9156  ?( column_ + j - row_ )
9157  :( column_ + j - row_ + 1UL ) )
9158  :( 0UL ) );
9159 
9160  const RhsIterator last( (~rhs).end(j) );
9161  RhsIterator element( (~rhs).lowerBound( index, j ) );
9162 
9163  if( IsUniUpper<MT2>::value && containsDiagonal ) {
9164  if( element == last || ( element->index() != column_+j-row_ ) || !isOne( element->value() ) )
9165  return false;
9166  ++element;
9167  }
9168 
9169  for( ; element!=last; ++element ) {
9170  if( !isDefault( element->value() ) )
9171  return false;
9172  }
9173  }
9174 
9175  return true;
9176 }
9178 //*************************************************************************************************
9179 
9180 
9181 //*************************************************************************************************
9193 template< typename MT > // Type of the dense matrix
9194 template< typename MT2 // Type of the left-hand side dense matrix
9195  , bool SO2 // Storage order of the left-hand side dense matrix
9196  , typename MT3 > // Type of the right-hand side dense matrix
9197 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
9198  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
9199 {
9201 
9202  UNUSED_PARAMETER( lhs );
9203 
9204  for( size_t i=0UL; i<m_; ++i ) {
9205  for( size_t j=0UL; j<n_; ++j ) {
9206  if( ( row_ + i != column_ + j ) && !isDefault( (~rhs)(i,j) ) )
9207  return false;
9208  }
9209  }
9210 
9211  return true;
9212 }
9214 //*************************************************************************************************
9215 
9216 
9217 //*************************************************************************************************
9229 template< typename MT > // Type of the dense matrix
9230 template< typename MT2 // Type of the left-hand side dense matrix
9231  , bool SO2 // Storage order of the left-hand side dense matrix
9232  , typename MT3 > // Type of the right-hand side dense matrix
9233 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
9234  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
9235 {
9237 
9238  UNUSED_PARAMETER( lhs );
9239 
9240  for( size_t j=0UL; j<n_; ++j ) {
9241  for( size_t i=0UL; i<m_; ++i ) {
9242  if( ( column_ + j != row_ + i ) && !isDefault( (~rhs)(i,j) ) )
9243  return false;
9244  }
9245  }
9246 
9247  return true;
9248 }
9250 //*************************************************************************************************
9251 
9252 
9253 //*************************************************************************************************
9265 template< typename MT > // Type of the dense matrix
9266 template< typename MT2 // Type of the left-hand side dense matrix
9267  , bool SO2 // Storage order of the left-hand side dense matrix
9268  , typename MT3 > // Type of the right-hand side sparse matrix
9269 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
9270  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
9271 {
9273 
9274  UNUSED_PARAMETER( lhs );
9275 
9276  typedef typename MT3::ConstIterator RhsIterator;
9277 
9278  for( size_t i=0UL; i<m_; ++i ) {
9279  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
9280  if( ( row_ + i != column_ + element->index() ) && !isDefault( element->value() ) )
9281  return false;
9282  }
9283  }
9284 
9285  return true;
9286 }
9288 //*************************************************************************************************
9289 
9290 
9291 //*************************************************************************************************
9303 template< typename MT > // Type of the dense matrix
9304 template< typename MT2 // Type of the left-hand side dense matrix
9305  , bool SO2 // Storage order of the left-hand side dense matrix
9306  , typename MT3 > // Type of the right-hand side sparse matrix
9307 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
9308  DenseSubmatrix<MT,aligned,false>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
9309 {
9311 
9312  UNUSED_PARAMETER( lhs );
9313 
9314  typedef typename MT3::ConstIterator RhsIterator;
9315 
9316  for( size_t j=0UL; j<n_; ++j ) {
9317  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
9318  if( ( column_ + j != row_ + element->index() ) && !isDefault( element->value() ) )
9319  return false;
9320  }
9321  }
9322 
9323  return true;
9324 }
9326 //*************************************************************************************************
9327 
9328 
9329 
9330 
9331 //=================================================================================================
9332 //
9333 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
9334 //
9335 //=================================================================================================
9336 
9337 //*************************************************************************************************
9348 template< typename MT > // Type of the dense matrix
9349 template< typename Other > // Data type of the foreign expression
9350 inline bool DenseSubmatrix<MT,aligned,false>::canAlias( const Other* alias ) const
9351 {
9352  return matrix_.isAliased( alias );
9353 }
9355 //*************************************************************************************************
9356 
9357 
9358 //*************************************************************************************************
9369 template< typename MT > // Type of the dense matrix
9370 template< typename MT2 // Data type of the foreign dense submatrix
9371  , bool AF2 // Alignment flag of the foreign dense submatrix
9372  , bool SO2 > // Storage order of the foreign dense submatrix
9373 inline bool DenseSubmatrix<MT,aligned,false>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
9374 {
9375  return ( matrix_.isAliased( &alias->matrix_ ) &&
9376  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
9377  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
9378 }
9380 //*************************************************************************************************
9381 
9382 
9383 //*************************************************************************************************
9394 template< typename MT > // Type of the dense matrix
9395 template< typename Other > // Data type of the foreign expression
9396 inline bool DenseSubmatrix<MT,aligned,false>::isAliased( const Other* alias ) const
9397 {
9398  return matrix_.isAliased( alias );
9399 }
9401 //*************************************************************************************************
9402 
9403 
9404 //*************************************************************************************************
9415 template< typename MT > // Type of the dense matrix
9416 template< typename MT2 // Data type of the foreign dense submatrix
9417  , bool AF2 // Alignment flag of the foreign dense submatrix
9418  , bool SO2 > // Storage order of the foreign dense submatrix
9419 inline bool DenseSubmatrix<MT,aligned,false>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
9420 {
9421  return ( matrix_.isAliased( &alias->matrix_ ) &&
9422  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
9423  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
9424 }
9426 //*************************************************************************************************
9427 
9428 
9429 //*************************************************************************************************
9439 template< typename MT > // Type of the dense matrix
9441 {
9442  return true;
9443 }
9445 //*************************************************************************************************
9446 
9447 
9448 //*************************************************************************************************
9459 template< typename MT > // Type of the dense matrix
9461 {
9462  return ( rows() > SMP_DMATASSIGN_THRESHOLD );
9463 }
9465 //*************************************************************************************************
9466 
9467 
9468 //*************************************************************************************************
9485 template< typename MT > // Type of the dense matrix
9486 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
9487  DenseSubmatrix<MT,aligned,false>::load( size_t i, size_t j ) const
9488 {
9490 
9491  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
9492  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
9493  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
9494 
9495  return matrix_.load( row_+i, column_+j );
9496 }
9498 //*************************************************************************************************
9499 
9500 
9501 //*************************************************************************************************
9518 template< typename MT > // Type of the dense matrix
9519 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
9520  DenseSubmatrix<MT,aligned,false>::loadu( size_t i, size_t j ) const
9521 {
9523 
9524  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
9525  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
9526  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
9527 
9528  return matrix_.loadu( row_+i, column_+j );
9529 }
9531 //*************************************************************************************************
9532 
9533 
9534 //*************************************************************************************************
9551 template< typename MT > // Type of the dense matrix
9553  DenseSubmatrix<MT,aligned,false>::store( size_t i, size_t j, const IntrinsicType& value )
9554 {
9556 
9557  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
9558  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
9559  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
9560 
9561  return matrix_.store( row_+i, column_+j, value );
9562 }
9564 //*************************************************************************************************
9565 
9566 
9567 //*************************************************************************************************
9584 template< typename MT > // Type of the dense matrix
9586  DenseSubmatrix<MT,aligned,false>::storeu( size_t i, size_t j, const IntrinsicType& value )
9587 {
9589 
9590  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
9591  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
9592  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
9593 
9594  matrix_.storeu( row_+i, column_+j, value );
9595 }
9597 //*************************************************************************************************
9598 
9599 
9600 //*************************************************************************************************
9618 template< typename MT > // Type of the dense matrix
9620  DenseSubmatrix<MT,aligned,false>::stream( size_t i, size_t j, const IntrinsicType& value )
9621 {
9623 
9624  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
9625  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
9626  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
9627 
9628  matrix_.stream( row_+i, column_+j, value );
9629 }
9631 //*************************************************************************************************
9632 
9633 
9634 //*************************************************************************************************
9646 template< typename MT > // Type of the dense matrix
9647 template< typename MT2 > // Type of the right-hand side dense matrix
9648 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
9649  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
9650 {
9652 
9653  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9654  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9655 
9656  const size_t jpos( n_ & size_t(-2) );
9657  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
9658 
9659  for( size_t i=0UL; i<m_; ++i ) {
9660  for( size_t j=0UL; j<jpos; j+=2UL ) {
9661  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
9662  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
9663  }
9664  if( jpos < n_ ) {
9665  matrix_(row_+i,column_+jpos) = (~rhs)(i,jpos);
9666  }
9667  }
9668 }
9670 //*************************************************************************************************
9671 
9672 
9673 //*************************************************************************************************
9685 template< typename MT > // Type of the dense matrix
9686 template< typename MT2 > // Type of the right-hand side dense matrix
9687 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
9688  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
9689 {
9692 
9693  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9694  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9695 
9696  if( useStreaming &&
9697  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
9698  !(~rhs).isAliased( &matrix_ ) )
9699  {
9700  for( size_t i=0UL; i<m_; ++i )
9701  for( size_t j=0UL; j<n_; j+=IT::size )
9702  stream( i, j, (~rhs).load(i,j) );
9703  }
9704  else
9705  {
9706  const size_t jpos( n_ & size_t(-IT::size*4) );
9707  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jpos, "Invalid end calculation" );
9708 
9709  for( size_t i=0UL; i<m_; ++i ) {
9710  typename MT2::ConstIterator it( (~rhs).begin(i) );
9711  for( size_t j=0UL; j<jpos; j+=IT::size*4UL ) {
9712  store( i, j , it.load() ); it += IT::size;
9713  store( i, j+IT::size , it.load() ); it += IT::size;
9714  store( i, j+IT::size*2UL, it.load() ); it += IT::size;
9715  store( i, j+IT::size*3UL, it.load() ); it += IT::size;
9716  }
9717  for( size_t j=jpos; j<n_; j+=IT::size, it+=IT::size ) {
9718  store( i, j, it.load() );
9719  }
9720  }
9721  }
9722 }
9724 //*************************************************************************************************
9725 
9726 
9727 //*************************************************************************************************
9739 template< typename MT > // Type of the dense matrix
9740 template< typename MT2 > // Type of the right-hand side dense matrix
9741 inline void DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,true>& rhs )
9742 {
9745 
9746  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9747  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9748 
9749  const size_t block( 16UL );
9750 
9751  for( size_t ii=0UL; ii<m_; ii+=block ) {
9752  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
9753  for( size_t jj=0UL; jj<n_; jj+=block ) {
9754  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
9755  for( size_t i=ii; i<iend; ++i ) {
9756  for( size_t j=jj; j<jend; ++j ) {
9757  matrix_(row_+i,column_+j) = (~rhs)(i,j);
9758  }
9759  }
9760  }
9761  }
9762 }
9764 //*************************************************************************************************
9765 
9766 
9767 //*************************************************************************************************
9779 template< typename MT > // Type of the dense matrix
9780 template< typename MT2 > // Type of the right-hand side sparse matrix
9781 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,false>& rhs )
9782 {
9784 
9785  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9786  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9787 
9788  for( size_t i=0UL; i<m_; ++i )
9789  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
9790  matrix_(row_+i,column_+element->index()) = element->value();
9791 }
9793 //*************************************************************************************************
9794 
9795 
9796 //*************************************************************************************************
9808 template< typename MT > // Type of the dense matrix
9809 template< typename MT2 > // Type of the right-hand side sparse matrix
9810 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,true>& rhs )
9811 {
9814 
9815  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9816  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9817 
9818  for( size_t j=0UL; j<n_; ++j )
9819  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
9820  matrix_(row_+element->index(),column_+j) = element->value();
9821 }
9823 //*************************************************************************************************
9824 
9825 
9826 //*************************************************************************************************
9838 template< typename MT > // Type of the dense matrix
9839 template< typename MT2 > // Type of the right-hand side dense matrix
9840 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
9841  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
9842 {
9844 
9845  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9846  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9847 
9848  const size_t jpos( n_ & size_t(-2) );
9849  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
9850 
9851  for( size_t i=0UL; i<m_; ++i ) {
9852  for( size_t j=0UL; j<jpos; j+=2UL ) {
9853  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
9854  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
9855  }
9856  if( jpos < n_ ) {
9857  matrix_(row_+i,column_+jpos) += (~rhs)(i,jpos);
9858  }
9859  }
9860 }
9862 //*************************************************************************************************
9863 
9864 
9865 //*************************************************************************************************
9877 template< typename MT > // Type of the dense matrix
9878 template< typename MT2 > // Type of the right-hand side dense matrix
9879 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
9880  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
9881 {
9884 
9885  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9886  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9887 
9888  const size_t jpos( n_ & size_t(-IT::size*4) );
9889  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jpos, "Invalid end calculation" );
9890 
9891  for( size_t i=0UL; i<m_; ++i ) {
9892  typename MT2::ConstIterator it( (~rhs).begin(i) );
9893  for( size_t j=0UL; j<jpos; j+=IT::size*4UL ) {
9894  store( i, j , load(i,j ) + it.load() ); it += IT::size;
9895  store( i, j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
9896  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
9897  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
9898  }
9899  for( size_t j=jpos; j<n_; j+=IT::size, it+=IT::size ) {
9900  store( i, j, load(i,j) + it.load() );
9901  }
9902  }
9903 }
9905 //*************************************************************************************************
9906 
9907 
9908 //*************************************************************************************************
9920 template< typename MT > // Type of the dense matrix
9921 template< typename MT2 > // Type of the right-hand side dense matrix
9922 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,true>& rhs )
9923 {
9926 
9927  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9928  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9929 
9930  const size_t block( 16UL );
9931 
9932  for( size_t ii=0UL; ii<m_; ii+=block ) {
9933  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
9934  for( size_t jj=0UL; jj<n_; jj+=block ) {
9935  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
9936  for( size_t i=ii; i<iend; ++i ) {
9937  for( size_t j=jj; j<jend; ++j ) {
9938  matrix_(row_+i,column_+j) += (~rhs)(i,j);
9939  }
9940  }
9941  }
9942  }
9943 }
9945 //*************************************************************************************************
9946 
9947 
9948 //*************************************************************************************************
9960 template< typename MT > // Type of the dense matrix
9961 template< typename MT2 > // Type of the right-hand side sparse matrix
9962 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,false>& rhs )
9963 {
9965 
9966  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9967  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9968 
9969  for( size_t i=0UL; i<m_; ++i )
9970  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
9971  matrix_(row_+i,column_+element->index()) += element->value();
9972 }
9974 //*************************************************************************************************
9975 
9976 
9977 //*************************************************************************************************
9989 template< typename MT > // Type of the dense matrix
9990 template< typename MT2 > // Type of the right-hand side sparse matrix
9991 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,true>& rhs )
9992 {
9995 
9996  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
9997  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
9998 
9999  for( size_t j=0UL; j<n_; ++j )
10000  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
10001  matrix_(row_+element->index(),column_+j) += element->value();
10002 }
10004 //*************************************************************************************************
10005 
10006 
10007 //*************************************************************************************************
10019 template< typename MT > // Type of the dense matrix
10020 template< typename MT2 > // Type of the right-hand side dense matrix
10021 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
10022  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
10023 {
10025 
10026  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10027  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10028 
10029  const size_t jpos( n_ & size_t(-2) );
10030  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
10031 
10032  for( size_t i=0UL; i<m_; ++i ) {
10033  for( size_t j=0UL; j<jpos; j+=2UL ) {
10034  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
10035  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
10036  }
10037  if( jpos < n_ ) {
10038  matrix_(row_+i,column_+jpos) -= (~rhs)(i,jpos);
10039  }
10040  }
10041 }
10043 //*************************************************************************************************
10044 
10045 
10046 //*************************************************************************************************
10058 template< typename MT > // Type of the dense matrix
10059 template< typename MT2 > // Type of the right-hand side dense matrix
10060 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
10061  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
10062 {
10065 
10066  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10067  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10068 
10069  const size_t jpos( n_ & size_t(-IT::size*4) );
10070  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == jpos, "Invalid end calculation" );
10071 
10072  for( size_t i=0UL; i<m_; ++i ) {
10073  typename MT2::ConstIterator it( (~rhs).begin(i) );
10074  for( size_t j=0UL; j<jpos; j+=IT::size*4UL ) {
10075  store( i, j , load(i,j ) - it.load() ); it += IT::size;
10076  store( i, j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
10077  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
10078  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
10079  }
10080  for( size_t j=jpos; j<n_; j+=IT::size, it+=IT::size ) {
10081  store( i, j, load(i,j) - it.load() );
10082  }
10083  }
10084 }
10086 //*************************************************************************************************
10087 
10088 
10089 //*************************************************************************************************
10101 template< typename MT > // Type of the dense matrix
10102 template< typename MT2 > // Type of the right-hand side dense matrix
10103 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,true>& rhs )
10104 {
10107 
10108  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10109  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10110 
10111  const size_t block( 16UL );
10112 
10113  for( size_t ii=0UL; ii<m_; ii+=block ) {
10114  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
10115  for( size_t jj=0UL; jj<n_; jj+=block ) {
10116  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
10117  for( size_t i=ii; i<iend; ++i ) {
10118  for( size_t j=jj; j<jend; ++j ) {
10119  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
10120  }
10121  }
10122  }
10123  }
10124 }
10126 //*************************************************************************************************
10127 
10128 
10129 //*************************************************************************************************
10141 template< typename MT > // Type of the dense matrix
10142 template< typename MT2 > // Type of the right-hand side sparse matrix
10143 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,false>& rhs )
10144 {
10146 
10147  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10148  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10149 
10150  for( size_t i=0UL; i<m_; ++i )
10151  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
10152  matrix_(row_+i,column_+element->index()) -= element->value();
10153 }
10155 //*************************************************************************************************
10156 
10157 
10158 //*************************************************************************************************
10170 template< typename MT > // Type of the dense matrix
10171 template< typename MT2 > // Type of the right-hand side sparse matrix
10172 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,true>& rhs )
10173 {
10176 
10177  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10178  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10179 
10180  for( size_t j=0UL; j<n_; ++j )
10181  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
10182  matrix_(row_+element->index(),column_+j) -= element->value();
10183 }
10185 //*************************************************************************************************
10186 
10187 
10188 
10189 
10190 
10191 
10192 
10193 
10194 //=================================================================================================
10195 //
10196 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED COLUMN-MAJOR SUBMATRICES
10197 //
10198 //=================================================================================================
10199 
10200 //*************************************************************************************************
10208 template< typename MT > // Type of the dense matrix
10209 class DenseSubmatrix<MT,aligned,true> : public DenseMatrix< DenseSubmatrix<MT,aligned,true>, true >
10210  , private Submatrix
10211 {
10212  private:
10213  //**Type definitions****************************************************************************
10215  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
10216 
10218  typedef IntrinsicTrait<typename MT::ElementType> IT;
10219  //**********************************************************************************************
10220 
10221  //**********************************************************************************************
10223 
10229  enum { useConst = IsConst<MT>::value };
10230  //**********************************************************************************************
10231 
10232  public:
10233  //**Type definitions****************************************************************************
10234  typedef DenseSubmatrix<MT,aligned,true> This;
10235  typedef typename SubmatrixTrait<MT>::Type ResultType;
10236  typedef typename ResultType::OppositeType OppositeType;
10237  typedef typename ResultType::TransposeType TransposeType;
10238  typedef typename MT::ElementType ElementType;
10239  typedef typename IT::Type IntrinsicType;
10240  typedef typename MT::ReturnType ReturnType;
10241  typedef const DenseSubmatrix& CompositeType;
10242 
10244  typedef typename MT::ConstReference ConstReference;
10245 
10247  typedef typename IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference;
10248 
10250  typedef const ElementType* ConstPointer;
10251 
10253  typedef typename IfTrue< useConst, ConstPointer, ElementType* >::Type Pointer;
10254 
10256  typedef typename MT::ConstIterator ConstIterator;
10257 
10259  typedef typename IfTrue< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
10260  //**********************************************************************************************
10261 
10262  //**Compilation flags***************************************************************************
10264  enum { vectorizable = MT::vectorizable };
10265 
10267  enum { smpAssignable = MT::smpAssignable };
10268  //**********************************************************************************************
10269 
10270  //**Constructors********************************************************************************
10273  explicit inline DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n );
10274  // No explicitly declared copy constructor.
10276  //**********************************************************************************************
10277 
10278  //**Destructor**********************************************************************************
10279  // No explicitly declared destructor.
10280  //**********************************************************************************************
10281 
10282  //**Data access functions***********************************************************************
10285  inline Reference operator()( size_t i, size_t j );
10286  inline ConstReference operator()( size_t i, size_t j ) const;
10287  inline Pointer data ();
10288  inline ConstPointer data () const;
10289  inline Iterator begin ( size_t i );
10290  inline ConstIterator begin ( size_t i ) const;
10291  inline ConstIterator cbegin( size_t i ) const;
10292  inline Iterator end ( size_t i );
10293  inline ConstIterator end ( size_t i ) const;
10294  inline ConstIterator cend ( size_t i ) const;
10296  //**********************************************************************************************
10297 
10298  //**Assignment operators************************************************************************
10301  inline DenseSubmatrix& operator=( const ElementType& rhs );
10302  inline DenseSubmatrix& operator=( const DenseSubmatrix& rhs );
10303 
10304  template< typename MT2, bool SO >
10305  inline DenseSubmatrix& operator=( const Matrix<MT2,SO>& rhs );
10306 
10307  template< typename MT2, bool SO >
10308  inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
10309  operator+=( const Matrix<MT2,SO>& rhs );
10310 
10311  template< typename MT2, bool SO >
10312  inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
10313  operator+=( const Matrix<MT2,SO>& rhs );
10314 
10315  template< typename MT2, bool SO >
10316  inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
10317  operator-=( const Matrix<MT2,SO>& rhs );
10318 
10319  template< typename MT2, bool SO >
10320  inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
10321  operator-=( const Matrix<MT2,SO>& rhs );
10322 
10323  template< typename MT2, bool SO >
10324  inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
10325 
10326  template< typename Other >
10327  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
10328  operator*=( Other rhs );
10329 
10330  template< typename Other >
10331  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
10332  operator/=( Other rhs );
10334  //**********************************************************************************************
10335 
10336  //**Utility functions***************************************************************************
10339  inline size_t rows() const;
10340  inline size_t columns() const;
10341  inline size_t spacing() const;
10342  inline size_t capacity() const;
10343  inline size_t capacity( size_t i ) const;
10344  inline size_t nonZeros() const;
10345  inline size_t nonZeros( size_t i ) const;
10346  inline void reset();
10347  inline void reset( size_t i );
10348  inline DenseSubmatrix& transpose();
10349  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
10351  //**********************************************************************************************
10352 
10353  private:
10354  //**********************************************************************************************
10356  template< typename MT2 >
10357  struct VectorizedAssign {
10358  enum { value = vectorizable && MT2::vectorizable &&
10359  IsSame<ElementType,typename MT2::ElementType>::value };
10360  };
10361  //**********************************************************************************************
10362 
10363  //**********************************************************************************************
10365  template< typename MT2 >
10366  struct VectorizedAddAssign {
10367  enum { value = vectorizable && MT2::vectorizable &&
10368  IsSame<ElementType,typename MT2::ElementType>::value &&
10369  IntrinsicTrait<ElementType>::addition };
10370  };
10371  //**********************************************************************************************
10372 
10373  //**********************************************************************************************
10375  template< typename MT2 >
10376  struct VectorizedSubAssign {
10377  enum { value = vectorizable && MT2::vectorizable &&
10378  IsSame<ElementType,typename MT2::ElementType>::value &&
10379  IntrinsicTrait<ElementType>::subtraction };
10380  };
10381  //**********************************************************************************************
10382 
10383  public:
10384  //**Expression template evaluation functions****************************************************
10387  template< typename Other >
10388  inline bool canAlias( const Other* alias ) const;
10389 
10390  template< typename MT2, bool AF2, bool SO2 >
10391  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
10392 
10393  template< typename Other >
10394  inline bool isAliased( const Other* alias ) const;
10395 
10396  template< typename MT2, bool AF2, bool SO2 >
10397  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
10398 
10399  inline bool isAligned () const;
10400  inline bool canSMPAssign() const;
10401 
10402  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
10403  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
10404 
10405  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
10406  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
10407  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
10408 
10409  template< typename MT2 >
10410  inline typename DisableIf< VectorizedAssign<MT2> >::Type
10411  assign( const DenseMatrix<MT2,true>& rhs );
10412 
10413  template< typename MT2 >
10414  inline typename EnableIf< VectorizedAssign<MT2> >::Type
10415  assign( const DenseMatrix<MT2,true>& rhs );
10416 
10417  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
10418  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
10419  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
10420 
10421  template< typename MT2 >
10422  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
10423  addAssign( const DenseMatrix<MT2,true>& rhs );
10424 
10425  template< typename MT2 >
10426  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
10427  addAssign( const DenseMatrix<MT2,true>& rhs );
10428 
10429  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
10430  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
10431  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
10432 
10433  template< typename MT2 >
10434  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
10435  subAssign( const DenseMatrix<MT2,true>& rhs );
10436 
10437  template< typename MT2 >
10438  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
10439  subAssign( const DenseMatrix<MT2,true>& rhs );
10440 
10441  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
10442  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
10443  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
10445  //**********************************************************************************************
10446 
10447  private:
10448  //**Utility functions***************************************************************************
10451  inline bool hasOverlap() const;
10452 
10453  template< typename MT2, bool SO2, typename MT3, bool SO3 >
10454  inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
10455  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
10456 
10457  template< typename MT2, bool SO2, typename MT3, bool SO3 >
10458  inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
10459  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs );
10460 
10461  template< typename MT2, bool SO2, typename MT3 >
10462  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
10463  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
10464 
10465  template< typename MT2, bool SO2, typename MT3 >
10466  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
10467  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
10468 
10469  template< typename MT2, bool SO2, typename MT3 >
10470  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
10471  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
10472 
10473  template< typename MT2, bool SO2, typename MT3 >
10474  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
10475  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
10476 
10477  template< typename MT2, bool SO2, typename MT3 >
10478  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
10479  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
10480 
10481  template< typename MT2, bool SO2, typename MT3 >
10482  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
10483  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
10484 
10485  template< typename MT2, bool SO2, typename MT3 >
10486  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
10487  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
10488 
10489  template< typename MT2, bool SO2, typename MT3 >
10490  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
10491  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
10492 
10493  template< typename MT2, bool SO2, typename MT3 >
10494  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
10495  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs );
10496 
10497  template< typename MT2, bool SO2, typename MT3 >
10498  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
10499  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs );
10500 
10501  template< typename MT2, bool SO2, typename MT3 >
10502  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
10503  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs );
10504 
10505  template< typename MT2, bool SO2, typename MT3 >
10506  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
10507  preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs );
10509  //**********************************************************************************************
10510 
10511  //**Member variables****************************************************************************
10514  Operand matrix_;
10515  const size_t row_;
10516  const size_t column_;
10517  const size_t m_;
10518  const size_t n_;
10519 
10520  //**********************************************************************************************
10521 
10522  //**Friend declarations*************************************************************************
10523  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
10524 
10525  template< bool AF1, typename MT2, bool AF2, bool SO2 >
10526  friend const DenseSubmatrix<MT2,AF1,SO2>
10527  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
10528 
10529  template< typename MT2, bool AF2, bool SO2 >
10530  friend bool isSymmetric( const DenseSubmatrix<MT2,AF2,SO2>& dm );
10531 
10532  template< typename MT2, bool AF2, bool SO2 >
10533  friend bool isLower( const DenseSubmatrix<MT2,AF2,SO2>& dm );
10534 
10535  template< typename MT2, bool AF2, bool SO2 >
10536  friend bool isUpper( const DenseSubmatrix<MT2,AF2,SO2>& dm );
10537 
10538  template< typename MT2, bool AF2, bool SO2 >
10539  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
10540 
10541  template< typename MT2, bool AF2, bool SO2 >
10542  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
10543 
10544  template< typename MT2, bool AF2, bool SO2 >
10545  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
10546 
10547  template< typename MT2, bool AF2, bool SO2 >
10548  friend typename DerestrictTrait< DenseSubmatrix<MT2,AF2,SO2> >::Type
10549  derestrict( DenseSubmatrix<MT2,AF2,SO2>& dm );
10550  //**********************************************************************************************
10551 
10552  //**Compile time checks*************************************************************************
10560  BLAZE_STATIC_ASSERT( !IsRestricted<MT>::value || IsLower<MT>::value || IsUpper<MT>::value );
10561  //**********************************************************************************************
10562 };
10564 //*************************************************************************************************
10565 
10566 
10567 
10568 
10569 //=================================================================================================
10570 //
10571 // CONSTRUCTOR
10572 //
10573 //=================================================================================================
10574 
10575 //*************************************************************************************************
10589 template< typename MT > // Type of the dense matrix
10590 inline DenseSubmatrix<MT,aligned,true>::DenseSubmatrix( Operand matrix, size_t row, size_t column, size_t m, size_t n )
10591  : matrix_( matrix ) // The dense matrix containing the submatrix
10592  , row_ ( row ) // The first row of the submatrix
10593  , column_( column ) // The first column of the submatrix
10594  , m_ ( m ) // The number of rows of the submatrix
10595  , n_ ( n ) // The number of columns of the submatrix
10596 {
10597  if( ( row + m > matrix.rows() ) || ( column + n > matrix.columns() ) )
10598  throw std::invalid_argument( "Invalid submatrix specification" );
10599 
10600  if( row % IT::size != 0UL || ( row_ + m_ != matrix_.rows() && m_ % IT::size != 0UL ) )
10601  throw std::invalid_argument( "Invalid submatrix alignment" );
10602 }
10604 //*************************************************************************************************
10605 
10606 
10607 
10608 
10609 //=================================================================================================
10610 //
10611 // DATA ACCESS FUNCTIONS
10612 //
10613 //=================================================================================================
10614 
10615 //*************************************************************************************************
10623 template< typename MT > // Type of the dense matrix
10625  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j )
10626 {
10627  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
10628  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
10629 
10630  return matrix_(row_+i,column_+j);
10631 }
10633 //*************************************************************************************************
10634 
10635 
10636 //*************************************************************************************************
10644 template< typename MT > // Type of the dense matrix
10646  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j ) const
10647 {
10648  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
10649  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
10650 
10651  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
10652 }
10654 //*************************************************************************************************
10655 
10656 
10657 //*************************************************************************************************
10667 template< typename MT > // Type of the dense matrix
10668 inline typename DenseSubmatrix<MT,aligned,true>::Pointer DenseSubmatrix<MT,aligned,true>::data()
10669 {
10670  return matrix_.data() + row_ + column_*spacing();
10671 }
10673 //*************************************************************************************************
10674 
10675 
10676 //*************************************************************************************************
10686 template< typename MT > // Type of the dense matrix
10687 inline typename DenseSubmatrix<MT,aligned,true>::ConstPointer
10689 {
10690  return matrix_.data() + row_ + column_*spacing();
10691 }
10693 //*************************************************************************************************
10694 
10695 
10696 //*************************************************************************************************
10703 template< typename MT > // Type of the dense matrix
10706 {
10707  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
10708  return ( matrix_.begin( column_ + j ) + row_ );
10709 }
10711 //*************************************************************************************************
10712 
10713 
10714 //*************************************************************************************************
10721 template< typename MT > // Type of the dense matrix
10723  DenseSubmatrix<MT,aligned,true>::begin( size_t j ) const
10724 {
10725  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
10726  return ( matrix_.cbegin( column_ + j ) + row_ );
10727 }
10729 //*************************************************************************************************
10730 
10731 
10732 //*************************************************************************************************
10739 template< typename MT > // Type of the dense matrix
10741  DenseSubmatrix<MT,aligned,true>::cbegin( size_t j ) const
10742 {
10743  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
10744  return ( matrix_.cbegin( column_ + j ) + row_ );
10745 }
10747 //*************************************************************************************************
10748 
10749 
10750 //*************************************************************************************************
10757 template< typename MT > // Type of the dense matrix
10760 {
10761  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
10762  return ( matrix_.begin( column_ + j ) + row_ + m_ );
10763 }
10765 //*************************************************************************************************
10766 
10767 
10768 //*************************************************************************************************
10775 template< typename MT > // Type of the dense matrix
10777  DenseSubmatrix<MT,aligned,true>::end( size_t j ) const
10778 {
10779  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
10780  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
10781 }
10783 //*************************************************************************************************
10784 
10785 
10786 //*************************************************************************************************
10793 template< typename MT > // Type of the dense matrix
10795  DenseSubmatrix<MT,aligned,true>::cend( size_t j ) const
10796 {
10797  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
10798  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
10799 }
10801 //*************************************************************************************************
10802 
10803 
10804 
10805 
10806 //=================================================================================================
10807 //
10808 // ASSIGNMENT OPERATORS
10809 //
10810 //=================================================================================================
10811 
10812 //*************************************************************************************************
10823 template< typename MT > // Type of the dense matrix
10824 inline DenseSubmatrix<MT,aligned,true>&
10825  DenseSubmatrix<MT,aligned,true>::operator=( const ElementType& rhs )
10826 {
10827  const size_t jend( column_ + n_ );
10828 
10829  for( size_t j=column_; j<jend; ++j )
10830  {
10831  const size_t ibegin( ( IsLower<MT>::value )
10832  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
10833  ?( max( j+1UL, row_ ) )
10834  :( max( j, row_ ) ) )
10835  :( row_ ) );
10836  const size_t iend ( ( IsUpper<MT>::value )
10837  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
10838  ?( min( j, row_+m_ ) )
10839  :( min( j+1UL, row_+m_ ) ) )
10840  :( row_+m_ ) );
10841 
10842  for( size_t i=ibegin; i<iend; ++i )
10843  matrix_(i,j) = rhs;
10844  }
10845 
10846  return *this;
10847 }
10849 //*************************************************************************************************
10850 
10851 
10852 //*************************************************************************************************
10867 template< typename MT > // Type of the dense matrix
10868 inline DenseSubmatrix<MT,aligned,true>&
10869  DenseSubmatrix<MT,aligned,true>::operator=( const DenseSubmatrix& rhs )
10870 {
10873 
10874  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
10875  return *this;
10876 
10877  if( rows() != rhs.rows() || columns() != rhs.columns() )
10878  throw std::invalid_argument( "Submatrix sizes do not match" );
10879 
10880  if( !preservesInvariant( matrix_, rhs ) )
10881  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
10882 
10883  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
10884 
10885  if( rhs.canAlias( &matrix_ ) ) {
10886  const ResultType tmp( rhs );
10887  smpAssign( left, tmp );
10888  }
10889  else {
10890  smpAssign( left, rhs );
10891  }
10892 
10893  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
10894  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
10895  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
10896 
10897  return *this;
10898 }
10900 //*************************************************************************************************
10901 
10902 
10903 //*************************************************************************************************
10917 template< typename MT > // Type of the dense matrix
10918 template< typename MT2 // Type of the right-hand side matrix
10919  , bool SO > // Storage order of the right-hand side matrix
10920 inline DenseSubmatrix<MT,aligned,true>&
10921  DenseSubmatrix<MT,aligned,true>::operator=( const Matrix<MT2,SO>& rhs )
10922 {
10924 
10925  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
10926  throw std::invalid_argument( "Matrix sizes do not match" );
10927 
10928  typedef typename If< IsAdaptor<MT>, typename MT2::CompositeType, const MT2& >::Type Right;
10929  Right right( ~rhs );
10930 
10931  if( !preservesInvariant( matrix_, right ) )
10932  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
10933 
10934  if( IsSparseMatrix<MT2>::value )
10935  reset();
10936 
10937  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
10938 
10939  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
10940  const typename MT2::ResultType tmp( right );
10941  smpAssign( left, tmp );
10942  }
10943  else {
10944  smpAssign( left, right );
10945  }
10946 
10947  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
10948  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
10949  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
10950 
10951  return *this;
10952 }
10954 //*************************************************************************************************
10955 
10956 
10957 //*************************************************************************************************
10971 template< typename MT > // Type of the dense matrix
10972 template< typename MT2 // Type of the right-hand side matrix
10973  , bool SO > // Storage order of the right-hand side matrix
10974 inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
10975  , DenseSubmatrix<MT,aligned,true>& >::Type
10976  DenseSubmatrix<MT,aligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
10977 {
10981 
10982  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
10983 
10986 
10987  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
10988  throw std::invalid_argument( "Matrix sizes do not match" );
10989 
10990  if( !preservesInvariant( matrix_, ~rhs ) )
10991  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
10992 
10993  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
10994 
10995  if( ( IsSymmetric<MT>::value && hasOverlap() ) || (~rhs).canAlias( &matrix_ ) ) {
10996  const AddType tmp( *this + (~rhs) );
10997  smpAssign( left, tmp );
10998  }
10999  else {
11000  smpAddAssign( left, ~rhs );
11001  }
11002 
11003  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
11004  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
11005  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
11006 
11007  return *this;
11008 }
11010 //*************************************************************************************************
11011 
11012 
11013 //*************************************************************************************************
11027 template< typename MT > // Type of the dense matrix
11028 template< typename MT2 // Type of the right-hand side matrix
11029  , bool SO > // Storage order of the right-hand side matrix
11030 inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
11031  , DenseSubmatrix<MT,aligned,true>& >::Type
11032  DenseSubmatrix<MT,aligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
11033 {
11037 
11038  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
11039 
11042 
11043  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
11044  throw std::invalid_argument( "Matrix sizes do not match" );
11045 
11046  const AddType tmp( *this + (~rhs) );
11047 
11048  if( !preservesInvariant( matrix_, tmp ) )
11049  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
11050 
11051  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
11052 
11053  smpAssign( left, tmp );
11054 
11055  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
11056  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
11057  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
11058 
11059  return *this;
11060 }
11062 //*************************************************************************************************
11063 
11064 
11065 //*************************************************************************************************
11079 template< typename MT > // Type of the dense matrix
11080 template< typename MT2 // Type of the right-hand side matrix
11081  , bool SO > // Storage order of the right-hand side matrix
11082 inline typename DisableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
11083  , DenseSubmatrix<MT,aligned,true>& >::Type
11084  DenseSubmatrix<MT,aligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
11085 {
11089 
11090  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
11091 
11094 
11095  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
11096  throw std::invalid_argument( "Matrix sizes do not match" );
11097 
11098  if( !preservesInvariant( matrix_, ~rhs ) )
11099  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
11100 
11101  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
11102 
11103  if( ( IsSymmetric<MT>::value && hasOverlap() ) || (~rhs).canAlias( &matrix_ ) ) {
11104  const SubType tmp( *this - (~rhs ) );
11105  smpAssign( left, tmp );
11106  }
11107  else {
11108  smpSubAssign( left, ~rhs );
11109  }
11110 
11111  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
11112  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
11113  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
11114 
11115  return *this;
11116 }
11118 //*************************************************************************************************
11119 
11120 
11121 //*************************************************************************************************
11135 template< typename MT > // Type of the dense matrix
11136 template< typename MT2 // Type of the right-hand side matrix
11137  , bool SO > // Storage order of the right-hand side matrix
11138 inline typename EnableIf< And< IsAdaptor<MT>, RequiresEvaluation<MT2> >
11139  , DenseSubmatrix<MT,aligned,true>& >::Type
11140  DenseSubmatrix<MT,aligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
11141 {
11145 
11146  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
11147 
11150 
11151  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() )
11152  throw std::invalid_argument( "Matrix sizes do not match" );
11153 
11154  const SubType tmp( *this - (~rhs) );
11155 
11156  if( !preservesInvariant( matrix_, tmp ) )
11157  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
11158 
11159  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
11160 
11161  smpAssign( left, tmp );
11162 
11163  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
11164  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
11165  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
11166 
11167  return *this;
11168 }
11170 //*************************************************************************************************
11171 
11172 
11173 //*************************************************************************************************
11187 template< typename MT > // Type of the dense matrix
11188 template< typename MT2 // Type of the right-hand side matrix
11189  , bool SO > // Storage order of the right-hand side matrix
11190 inline DenseSubmatrix<MT,aligned,true>&
11191  DenseSubmatrix<MT,aligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
11192 {
11196 
11197  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
11198 
11201 
11202  if( columns() != (~rhs).rows() )
11203  throw std::invalid_argument( "Matrix sizes do not match" );
11204 
11205  const MultType tmp( *this * (~rhs) );
11206 
11207  if( !preservesInvariant( matrix_, tmp ) )
11208  throw std::invalid_argument( "Invalid assignment to matrix adaptor" );
11209 
11210  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
11211 
11212  smpAssign( left, tmp );
11213 
11214  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
11215  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
11216  BLAZE_INTERNAL_ASSERT( !IsSymmetric<MT>::value || isSymmetric( derestrict( matrix_ ) ), "Symmetry violation detected" );
11217 
11218  return *this;
11219 }
11221 //*************************************************************************************************
11222 
11223 
11224 //*************************************************************************************************
11235 template< typename MT > // Type of the dense matrix
11236 template< typename Other > // Data type of the right-hand side scalar
11237 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
11238  DenseSubmatrix<MT,aligned,true>::operator*=( Other rhs )
11239 {
11241 
11242  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
11243  smpAssign( left, (*this) * rhs );
11244 
11245  return *this;
11246 }
11248 //*************************************************************************************************
11249 
11250 
11251 //*************************************************************************************************
11264 template< typename MT > // Type of the dense matrix
11265 template< typename Other > // Data type of the right-hand side scalar
11266 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
11267  DenseSubmatrix<MT,aligned,true>::operator/=( Other rhs )
11268 {
11270 
11271  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
11272 
11273  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
11274  smpAssign( left, (*this) / rhs );
11275 
11276  return *this;
11277 }
11279 //*************************************************************************************************
11280 
11281 
11282 
11283 
11284 //=================================================================================================
11285 //
11286 // UTILITY FUNCTIONS
11287 //
11288 //=================================================================================================
11289 
11290 //*************************************************************************************************
11296 template< typename MT > // Type of the dense matrix
11297 inline size_t DenseSubmatrix<MT,aligned,true>::rows() const
11298 {
11299  return m_;
11300 }
11302 //*************************************************************************************************
11303 
11304 
11305 //*************************************************************************************************
11311 template< typename MT > // Type of the dense matrix
11312 inline size_t DenseSubmatrix<MT,aligned,true>::columns() const
11313 {
11314  return n_;
11315 }
11317 //*************************************************************************************************
11318 
11319 
11320 //*************************************************************************************************
11329 template< typename MT > // Type of the dense matrix
11330 inline size_t DenseSubmatrix<MT,aligned,true>::spacing() const
11331 {
11332  return matrix_.spacing();
11333 }
11335 //*************************************************************************************************
11336 
11337 
11338 //*************************************************************************************************
11344 template< typename MT > // Type of the dense matrix
11345 inline size_t DenseSubmatrix<MT,aligned,true>::capacity() const
11346 {
11347  return rows() * columns();
11348 }
11350 //*************************************************************************************************
11351 
11352 
11353 //*************************************************************************************************
11360 template< typename MT > // Type of the dense matrix
11361 inline size_t DenseSubmatrix<MT,aligned,true>::capacity( size_t j ) const
11362 {
11363  UNUSED_PARAMETER( j );
11364 
11365  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
11366 
11367  return rows();
11368 }
11370 //*************************************************************************************************
11371 
11372 
11373 //*************************************************************************************************
11379 template< typename MT > // Type of the dense matrix
11380 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros() const
11381 {
11382  const size_t iend( row_ + m_ );
11383  const size_t jend( column_ + n_ );
11384  size_t nonzeros( 0UL );
11385 
11386  for( size_t j=column_; j<jend; ++j )
11387  for( size_t i=row_; i<iend; ++i )
11388  if( !isDefault( matrix_(i,j) ) )
11389  ++nonzeros;
11390 
11391  return nonzeros;
11392 }
11394 //*************************************************************************************************
11395 
11396 
11397 //*************************************************************************************************
11404 template< typename MT > // Type of the dense matrix
11405 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros( size_t j ) const
11406 {
11407  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
11408 
11409  const size_t iend( row_ + m_ );
11410  size_t nonzeros( 0UL );
11411 
11412  for( size_t i=row_; i<iend; ++i )
11413  if( !isDefault( matrix_(i,column_+j) ) )
11414  ++nonzeros;
11415 
11416  return nonzeros;
11417 }
11419 //*************************************************************************************************
11420 
11421 
11422 //*************************************************************************************************
11428 template< typename MT > // Type of the dense matrix
11430 {
11431  using blaze::clear;
11432 
11433  for( size_t j=column_; j<column_+n_; ++j )
11434  {
11435  const size_t ibegin( ( IsLower<MT>::value )
11436  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
11437  ?( max( j+1UL, row_ ) )
11438  :( max( j, row_ ) ) )
11439  :( row_ ) );
11440  const size_t iend ( ( IsUpper<MT>::value )
11441  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
11442  ?( min( j, row_+m_ ) )
11443  :( min( j+1UL, row_+m_ ) ) )
11444  :( row_+m_ ) );
11445 
11446  for( size_t i=ibegin; i<iend; ++i )
11447  clear( matrix_(i,j) );
11448  }
11449 }
11451 //*************************************************************************************************
11452 
11453 
11454 //*************************************************************************************************
11461 template< typename MT > // Type of the dense matrix
11462 inline void DenseSubmatrix<MT,aligned,true>::reset( size_t j )
11463 {
11464  using blaze::clear;
11465 
11466  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
11467 
11468  const size_t ibegin( ( IsLower<MT>::value )
11469  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
11470  ?( max( j+1UL, row_ ) )
11471  :( max( j, row_ ) ) )
11472  :( row_ ) );
11473  const size_t iend ( ( IsUpper<MT>::value )
11474  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
11475  ?( min( j, row_+m_ ) )
11476  :( min( j+1UL, row_+m_ ) ) )
11477  :( row_+m_ ) );
11478 
11479  for( size_t i=ibegin; i<iend; ++i )
11480  clear( matrix_(i,column_+j) );
11481 }
11483 //*************************************************************************************************
11484 
11485 
11486 //*************************************************************************************************
11502 template< typename MT > // Type of the dense matrix
11503 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::transpose()
11504 {
11505  if( rows() != columns() )
11506  throw std::runtime_error( "Invalid transpose of a non-quadratic submatrix" );
11507 
11508  if( IsLower<MT>::value && ( row_ + 1UL < column_ + n_ ) )
11509  throw std::runtime_error( "Invalid transpose of a lower matrix" );
11510 
11511  if( IsUpper<MT>::value && ( column_ + 1UL < row_ + m_ ) )
11512  throw std::runtime_error( "Invalid transpose of an upper matrix" );
11513 
11514  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
11515  const ResultType tmp( trans(*this) );
11516  smpAssign( left, tmp );
11517 
11518  return *this;
11519 }
11521 //*************************************************************************************************
11522 
11523 
11524 //*************************************************************************************************
11535 template< typename MT > // Type of the dense matrix
11536 template< typename Other > // Data type of the scalar value
11537 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::scale( const Other& scalar )
11538 {
11540 
11541  const size_t jend( column_ + n_ );
11542 
11543  for( size_t j=column_; j<jend; ++j )
11544  {
11545  const size_t ibegin( ( IsLower<MT>::value )
11546  ?( ( IsStrictlyLower<MT>::value )
11547  ?( max( j+1UL, row_ ) )
11548  :( max( j, row_ ) ) )
11549  :( row_ ) );
11550  const size_t iend ( ( IsUpper<MT>::value )
11551  ?( ( IsStrictlyUpper<MT>::value )
11552  ?( min( j, row_+m_ ) )
11553  :( min( j+1UL, row_+m_ ) ) )
11554  :( row_+m_ ) );
11555 
11556  for( size_t i=ibegin; i<iend; ++i )
11557  matrix_(i,j) *= scalar;
11558  }
11559 
11560  return *this;
11561 }
11563 //*************************************************************************************************
11564 
11565 
11566 //*************************************************************************************************
11576 template< typename MT > // Type of the dense matrix
11578 {
11579  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value, "Unsymmetric matrix detected" );
11580 
11581  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
11582  return false;
11583  else return true;
11584 }
11586 //*************************************************************************************************
11587 
11588 
11589 //*************************************************************************************************
11601 template< typename MT > // Type of the dense matrix
11602 template< typename MT2 // Type of the left-hand side dense matrix
11603  , bool SO2 // Storage order of the left-hand side dense matrix
11604  , typename MT3 // Type of the right-hand side matrix
11605  , bool SO3 > // Storage order of the right-hand side matrix
11606 inline typename EnableIf< Not< IsAdaptor<MT2> >, bool >::Type
11607  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs )
11608 {
11609  UNUSED_PARAMETER( lhs, rhs );
11610 
11611  return true;
11612 }
11614 //*************************************************************************************************
11615 
11616 
11617 //*************************************************************************************************
11629 template< typename MT > // Type of the dense matrix
11630 template< typename MT2 // Type of the left-hand side dense matrix
11631  , bool SO2 // Storage order of the left-hand side dense matrix
11632  , typename MT3 // Type of the right-hand side matrix
11633  , bool SO3 > // Storage order of the right-hand side matrix
11634 inline typename EnableIf< And< IsSymmetric<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
11635  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const Matrix<MT3,SO3>& rhs )
11636 {
11638 
11639  UNUSED_PARAMETER( lhs );
11640 
11641  if( !hasOverlap() )
11642  return true;
11643 
11644  const bool lower( row_ > column_ );
11645  const size_t size ( min( row_ + m_, column_ + n_ ) - ( lower ? row_ : column_ ) );
11646 
11647  if( size < 2UL )
11648  return true;
11649 
11650  const size_t row ( lower ? 0UL : column_ - row_ );
11651  const size_t column( lower ? row_ - column_ : 0UL );
11652 
11653  return isSymmetric( submatrix( ~rhs, row, column, size, size ) );
11654 }
11656 //*************************************************************************************************
11657 
11658 
11659 //*************************************************************************************************
11672 template< typename MT > // Type of the dense matrix
11673 template< typename MT2 // Type of the left-hand side dense matrix
11674  , bool SO2 // Storage order of the left-hand side dense matrix
11675  , typename MT3 > // Type of the right-hand side dense matrix
11676 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
11677  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
11678 {
11680 
11681  UNUSED_PARAMETER( lhs );
11682 
11683  if( row_ + 1UL >= column_ + n_ )
11684  return true;
11685 
11686  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
11687  ?( column_ + n_ - row_ )
11688  :( column_ + n_ - row_ - 1UL ) );
11689  const size_t iend( min( ipos, m_ ) );
11690 
11691  for( size_t i=0UL; i<iend; ++i )
11692  {
11693  const bool containsDiagonal( row_+i >= column_ );
11694 
11695  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
11696  return false;
11697 
11698  const size_t jbegin( ( containsDiagonal )
11699  ?( ( IsStrictlyLower<MT2>::value )
11700  ?( row_ + i - column_ )
11701  :( row_ + i - column_ + 1UL ) )
11702  :( 0UL ) );
11703 
11704  for( size_t j=jbegin; j<n_; ++j ) {
11705  if( !isDefault( (~rhs)(i,j) ) )
11706  return false;
11707  }
11708  }
11709 
11710  return true;
11711 }
11713 //*************************************************************************************************
11714 
11715 
11716 //*************************************************************************************************
11729 template< typename MT > // Type of the dense matrix
11730 template< typename MT2 // Type of the left-hand side dense matrix
11731  , bool SO2 // Storage order of the left-hand side dense matrix
11732  , typename MT3 > // Type of the right-hand side dense matrix
11733 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
11734  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
11735 {
11737 
11738  UNUSED_PARAMETER( lhs );
11739 
11740  if( row_ + 1UL >= column_ + n_ )
11741  return true;
11742 
11743  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
11744  ?( row_ - column_ )
11745  :( row_ - column_ + 1UL ) );
11746  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
11747 
11748  for( size_t j=jbegin; j<n_; ++j )
11749  {
11750  const bool containsDiagonal( column_+j < row_+m_ );
11751 
11752  const size_t ipos( ( IsStrictlyLower<MT2>::value && containsDiagonal )
11753  ?( column_ + j - row_ + 1UL )
11754  :( column_ + j - row_ ) );
11755  const size_t iend( min( ipos, m_ ) );
11756 
11757  for( size_t i=0UL; i<iend; ++i ) {
11758  if( !isDefault( (~rhs)(i,j) ) )
11759  return false;
11760  }
11761 
11762  if( IsUniLower<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
11763  return false;
11764  }
11765 
11766  return true;
11767 }
11769 //*************************************************************************************************
11770 
11771 
11772 //*************************************************************************************************
11785 template< typename MT > // Type of the dense matrix
11786 template< typename MT2 // Type of the left-hand side dense matrix
11787  , bool SO2 // Storage order of the left-hand side dense matrix
11788  , typename MT3 > // Type of the right-hand side sparse matrix
11789 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
11790  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
11791 {
11793 
11794  UNUSED_PARAMETER( lhs );
11795 
11796  typedef typename MT3::ConstIterator RhsIterator;
11797 
11798  if( row_ + 1UL >= column_ + n_ )
11799  return true;
11800 
11801  const size_t ipos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
11802  ?( column_ + n_ - row_ )
11803  :( column_ + n_ - row_ - 1UL ) );
11804  const size_t iend( min( ipos, m_ ) );
11805 
11806  for( size_t i=0UL; i<iend; ++i )
11807  {
11808  const bool containsDiagonal( row_+i >= column_ );
11809 
11810  const size_t index( ( containsDiagonal )
11811  ?( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
11812  ?( row_ + i - column_ )
11813  :( row_ + i - column_ + 1UL ) )
11814  :( 0UL ) );
11815 
11816  const RhsIterator last( (~rhs).end(i) );
11817  RhsIterator element( (~rhs).lowerBound( i, index ) );
11818 
11819  if( IsUniLower<MT2>::value && containsDiagonal ) {
11820  if( element == last || ( element->index() != row_+i-column_ ) || !isOne( element->value() ) )
11821  return false;
11822  ++element;
11823  }
11824 
11825  for( ; element!=last; ++element ) {
11826  if( !isDefault( element->value() ) )
11827  return false;
11828  }
11829  }
11830 
11831  return true;
11832 }
11834 //*************************************************************************************************
11835 
11836 
11837 //*************************************************************************************************
11850 template< typename MT > // Type of the dense matrix
11851 template< typename MT2 // Type of the left-hand side dense matrix
11852  , bool SO2 // Storage order of the left-hand side dense matrix
11853  , typename MT3 > // Type of the right-hand side sparse matrix
11854 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
11855  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
11856 {
11858 
11859  UNUSED_PARAMETER( lhs );
11860 
11861  typedef typename MT3::ConstIterator RhsIterator;
11862 
11863  if( row_ + 1UL >= column_ + n_ )
11864  return true;
11865 
11866  const size_t jpos( ( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value )
11867  ?( row_ - column_ )
11868  :( row_ - column_ + 1UL ) );
11869  const size_t jbegin( ( row_ < column_ )?( 0UL ):( jpos ) );
11870 
11871  for( size_t j=jbegin; j<n_; ++j )
11872  {
11873  const bool containsDiagonal( column_+j < row_+m_ );
11874 
11875  const size_t index( ( IsStrictlyLower<MT2>::value && containsDiagonal )
11876  ?( column_ + j - row_ + 1UL )
11877  :( column_ + j - row_ ) );
11878  const RhsIterator last( (~rhs).lowerBound( min( index, m_ ), j ) );
11879 
11880  if( IsUniLower<MT2>::value && containsDiagonal &&
11881  ( last == (~rhs).end(j) || ( last->index() != column_+j-row_ ) || !isOne( last->value() ) ) ) {
11882  return false;
11883  }
11884 
11885  for( RhsIterator element=(~rhs).begin(j); element!=last; ++element ) {
11886  if( !isDefault( element->value() ) )
11887  return false;
11888  }
11889  }
11890 
11891  return true;
11892 }
11894 //*************************************************************************************************
11895 
11896 
11897 //*************************************************************************************************
11910 template< typename MT > // Type of the dense matrix
11911 template< typename MT2 // Type of the left-hand side dense matrix
11912  , bool SO2 // Storage order of the left-hand side dense matrix
11913  , typename MT3 > // Type of the right-hand side dense matrix
11914 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
11915  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
11916 {
11918 
11919  UNUSED_PARAMETER( lhs );
11920 
11921  if( column_ + 1UL >= row_ + m_ )
11922  return true;
11923 
11924  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
11925  ?( column_ - row_ )
11926  :( column_ - row_ + 1UL ) );
11927  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
11928 
11929  for( size_t i=ibegin; i<m_; ++i )
11930  {
11931  const bool containsDiagonal( row_+i < column_+n_ );
11932 
11933  const size_t jpos( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
11934  ?( row_ + i - column_ + 1UL )
11935  :( row_ + i - column_ ) );
11936  const size_t jend( min( jpos, n_ ) );
11937 
11938  for( size_t j=0UL; j<jend; ++j ) {
11939  if( !isDefault( (~rhs)(i,j) ) )
11940  return false;
11941  }
11942 
11943  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(i,row_+i-column_) ) )
11944  return false;
11945  }
11946 
11947  return true;
11948 }
11950 //*************************************************************************************************
11951 
11952 
11953 //*************************************************************************************************
11966 template< typename MT > // Type of the dense matrix
11967 template< typename MT2 // Type of the left-hand side dense matrix
11968  , bool SO2 // Storage order of the left-hand side dense matrix
11969  , typename MT3 > // Type of the right-hand side dense matrix
11970 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
11971  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
11972 {
11974 
11975  UNUSED_PARAMETER( lhs );
11976 
11977  if( column_ + 1UL >= row_ + m_ )
11978  return true;
11979 
11980  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
11981  ?( row_ + m_ - column_ )
11982  :( row_ + m_ - column_ - 1UL ) );
11983  const size_t jend( min( jpos, n_ ) );
11984 
11985  for( size_t j=0UL; j<jend; ++j )
11986  {
11987  const bool containsDiagonal( column_+j >= row_ );
11988 
11989  if( IsUniUpper<MT2>::value && containsDiagonal && !isOne( (~rhs)(column_+j-row_,j) ) )
11990  return false;
11991 
11992  const size_t ibegin( ( containsDiagonal )
11993  ?( ( IsStrictlyUpper<MT2>::value )
11994  ?( column_ + j - row_ )
11995  :( column_ + j - row_ + 1UL ) )
11996  :( 0UL ) );
11997 
11998  for( size_t i=ibegin; i<m_; ++i ) {
11999  if( !isDefault( (~rhs)(i,j) ) )
12000  return false;
12001  }
12002  }
12003 
12004  return true;
12005 }
12007 //*************************************************************************************************
12008 
12009 
12010 //*************************************************************************************************
12023 template< typename MT > // Type of the dense matrix
12024 template< typename MT2 // Type of the left-hand side dense matrix
12025  , bool SO2 // Storage order of the left-hand side dense matrix
12026  , typename MT3 > // Type of the right-hand side sparse matrix
12027 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
12028  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
12029 {
12031 
12032  UNUSED_PARAMETER( lhs );
12033 
12034  typedef typename MT3::ConstIterator RhsIterator;
12035 
12036  if( column_ + 1UL >= row_ + m_ )
12037  return true;
12038 
12039  const size_t ipos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
12040  ?( column_ - row_ )
12041  :( column_ - row_ + 1UL ) );
12042  const size_t ibegin( ( column_ < row_ )?( 0UL ):( ipos ) );
12043 
12044  for( size_t i=ibegin; i<m_; ++i )
12045  {
12046  const bool containsDiagonal( row_+i < column_+n_ );
12047 
12048  const size_t index( ( IsStrictlyUpper<MT2>::value && containsDiagonal )
12049  ?( row_ + i - column_ + 1UL )
12050  :( row_ + i - column_ ) );
12051  const RhsIterator last( (~rhs).lowerBound( i, min( index, n_ ) ) );
12052 
12053  if( IsUniUpper<MT2>::value && containsDiagonal &&
12054  ( last == (~rhs).end(i) || ( last->index() != row_+i-column_ ) || !isOne( last->value() ) ) ) {
12055  return false;
12056  }
12057 
12058  for( RhsIterator element=(~rhs).begin(i); element!=last; ++element ) {
12059  if( !isDefault( element->value() ) )
12060  return false;
12061  }
12062  }
12063 
12064  return true;
12065 }
12067 //*************************************************************************************************
12068 
12069 
12070 //*************************************************************************************************
12083 template< typename MT > // Type of the dense matrix
12084 template< typename MT2 // Type of the left-hand side dense matrix
12085  , bool SO2 // Storage order of the left-hand side dense matrix
12086  , typename MT3 > // Type of the right-hand side sparse matrix
12087 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
12088  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
12089 {
12091 
12092  UNUSED_PARAMETER( lhs );
12093 
12094  typedef typename MT3::ConstIterator RhsIterator;
12095 
12096  if( column_ + 1UL >= row_ + m_ )
12097  return true;
12098 
12099  const size_t jpos( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
12100  ?( row_ + m_ - column_ )
12101  :( row_ + m_ - column_ - 1UL ) );
12102  const size_t jend( min( jpos, n_ ) );
12103 
12104  for( size_t j=0UL; j<jend; ++j )
12105  {
12106  const bool containsDiagonal( column_+j >= row_ );
12107 
12108  const size_t index( ( containsDiagonal )
12109  ?( ( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value )
12110  ?( column_ + j - row_ )
12111  :( column_ + j - row_ + 1UL ) )
12112  :( 0UL ) );
12113 
12114  const RhsIterator last( (~rhs).end(j) );
12115  RhsIterator element( (~rhs).lowerBound( index, j ) );
12116 
12117  if( IsUniUpper<MT2>::value && containsDiagonal ) {
12118  if( element == last || ( element->index() != column_+j-row_ ) || !isOne( element->value() ) )
12119  return false;
12120  ++element;
12121  }
12122 
12123  for( ; element!=last; ++element ) {
12124  if( !isDefault( element->value() ) )
12125  return false;
12126  }
12127  }
12128 
12129  return true;
12130 }
12132 //*************************************************************************************************
12133 
12134 
12135 //*************************************************************************************************
12147 template< typename MT > // Type of the dense matrix
12148 template< typename MT2 // Type of the left-hand side dense matrix
12149  , bool SO2 // Storage order of the left-hand side dense matrix
12150  , typename MT3 > // Type of the right-hand side dense matrix
12151 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
12152  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,false>& rhs )
12153 {
12155 
12156  UNUSED_PARAMETER( lhs );
12157 
12158  for( size_t i=0UL; i<m_; ++i ) {
12159  for( size_t j=0UL; j<n_; ++j ) {
12160  if( ( row_ + i != column_ + j ) && !isDefault( (~rhs)(i,j) ) )
12161  return false;
12162  }
12163  }
12164 
12165  return true;
12166 }
12168 //*************************************************************************************************
12169 
12170 
12171 //*************************************************************************************************
12183 template< typename MT > // Type of the dense matrix
12184 template< typename MT2 // Type of the left-hand side dense matrix
12185  , bool SO2 // Storage order of the left-hand side dense matrix
12186  , typename MT3 > // Type of the right-hand side dense matrix
12187 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
12188  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const DenseMatrix<MT3,true>& rhs )
12189 {
12191 
12192  UNUSED_PARAMETER( lhs );
12193 
12194  for( size_t j=0UL; j<n_; ++j ) {
12195  for( size_t i=0UL; i<m_; ++i ) {
12196  if( ( column_ + j != row_ + i ) && !isDefault( (~rhs)(i,j) ) )
12197  return false;
12198  }
12199  }
12200 
12201  return true;
12202 }
12204 //*************************************************************************************************
12205 
12206 
12207 //*************************************************************************************************
12219 template< typename MT > // Type of the dense matrix
12220 template< typename MT2 // Type of the left-hand side dense matrix
12221  , bool SO2 // Storage order of the left-hand side dense matrix
12222  , typename MT3 > // Type of the right-hand side sparse matrix
12223 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
12224  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,false>& rhs )
12225 {
12227 
12228  UNUSED_PARAMETER( lhs );
12229 
12230  typedef typename MT3::ConstIterator RhsIterator;
12231 
12232  for( size_t i=0UL; i<m_; ++i ) {
12233  for( RhsIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
12234  if( ( row_ + i != column_ + element->index() ) && !isDefault( element->value() ) )
12235  return false;
12236  }
12237  }
12238 
12239  return true;
12240 }
12242 //*************************************************************************************************
12243 
12244 
12245 //*************************************************************************************************
12257 template< typename MT > // Type of the dense matrix
12258 template< typename MT2 // Type of the left-hand side dense matrix
12259  , bool SO2 // Storage order of the left-hand side dense matrix
12260  , typename MT3 > // Type of the right-hand side sparse matrix
12261 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
12262  DenseSubmatrix<MT,aligned,true>::preservesInvariant( const DenseMatrix<MT2,SO2>& lhs, const SparseMatrix<MT3,true>& rhs )
12263 {
12265 
12266  UNUSED_PARAMETER( lhs );
12267 
12268  typedef typename MT3::ConstIterator RhsIterator;
12269 
12270  for( size_t j=0UL; j<n_; ++j ) {
12271  for( RhsIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
12272  if( ( column_ + j != row_ + element->index() ) && !isDefault( element->value() ) )
12273  return false;
12274  }
12275  }
12276 
12277  return true;
12278 }
12280 //*************************************************************************************************
12281 
12282 
12283 
12284 
12285 //=================================================================================================
12286 //
12287 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
12288 //
12289 //=================================================================================================
12290 
12291 //*************************************************************************************************
12302 template< typename MT > // Type of the dense matrix
12303 template< typename Other > // Data type of the foreign expression
12304 inline bool DenseSubmatrix<MT,aligned,true>::canAlias( const Other* alias ) const
12305 {
12306  return matrix_.isAliased( alias );
12307 }
12309 //*************************************************************************************************
12310 
12311 
12312 //*************************************************************************************************
12323 template< typename MT > // Type of the dense matrix
12324 template< typename MT2 // Data type of the foreign dense submatrix
12325  , bool AF2 // Alignment flag of the foreign dense submatrix
12326  , bool SO2 > // Storage order of the foreign dense submatrix
12327 inline bool DenseSubmatrix<MT,aligned,true>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
12328 {
12329  return ( matrix_.isAliased( &alias->matrix_ ) &&
12330  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
12331  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
12332 }
12334 //*************************************************************************************************
12335 
12336 
12337 //*************************************************************************************************
12348 template< typename MT > // Type of the dense matrix
12349 template< typename Other > // Data type of the foreign expression
12350 inline bool DenseSubmatrix<MT,aligned,true>::isAliased( const Other* alias ) const
12351 {
12352  return matrix_.isAliased( alias );
12353 }
12355 //*************************************************************************************************
12356 
12357 
12358 //*************************************************************************************************
12369 template< typename MT > // Type of the dense matrix
12370 template< typename MT2 // Data type of the foreign dense submatrix
12371  , bool AF2 // Alignment flag of the foreign dense submatrix
12372  , bool SO2 > // Storage order of the foreign dense submatrix
12373 inline bool DenseSubmatrix<MT,aligned,true>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
12374 {
12375  return ( matrix_.isAliased( &alias->matrix_ ) &&
12376  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
12377  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
12378 }
12380 //*************************************************************************************************
12381 
12382 
12383 //*************************************************************************************************
12393 template< typename MT > // Type of the dense matrix
12395 {
12396  return true;
12397 }
12399 //*************************************************************************************************
12400 
12401 
12402 //*************************************************************************************************
12413 template< typename MT > // Type of the dense matrix
12415 {
12416  return ( columns() > SMP_DMATASSIGN_THRESHOLD );
12417 }
12419 //*************************************************************************************************
12420 
12421 
12422 //*************************************************************************************************
12438 template< typename MT > // Type of the dense matrix
12439 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
12440  DenseSubmatrix<MT,aligned,true>::load( size_t i, size_t j ) const
12441 {
12443 
12444  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
12445  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
12446  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
12447 
12448  return matrix_.load( row_+i, column_+j );
12449 }
12451 //*************************************************************************************************
12452 
12453 
12454 //*************************************************************************************************
12470 template< typename MT > // Type of the dense matrix
12471 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
12472  DenseSubmatrix<MT,aligned,true>::loadu( size_t i, size_t j ) const
12473 {
12475 
12476  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
12477  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
12478  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
12479 
12480  return matrix_.loadu( row_+i, column_+j );
12481 }
12483 //*************************************************************************************************
12484 
12485 
12486 //*************************************************************************************************
12502 template< typename MT > // Type of the dense matrix
12504  DenseSubmatrix<MT,aligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
12505 {
12507 
12508  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
12509  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
12510  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
12511 
12512  matrix_.store( row_+i, column_+j, value );
12513 }
12515 //*************************************************************************************************
12516 
12517 
12518 //*************************************************************************************************
12535 template< typename MT > // Type of the dense matrix
12537  DenseSubmatrix<MT,aligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
12538 {
12540 
12541  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
12542  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
12543  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
12544 
12545  matrix_.storeu( row_+i, column_+j, value );
12546 }
12548 //*************************************************************************************************
12549 
12550 
12551 //*************************************************************************************************
12568 template< typename MT > // Type of the dense matrix
12570  DenseSubmatrix<MT,aligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
12571 {
12573 
12574  BLAZE_INTERNAL_ASSERT( i < rows() , "Invalid row access index" );
12575  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
12576  BLAZE_INTERNAL_ASSERT( j < columns() , "Invalid column access index" );
12577 
12578  matrix_.stream( row_+i, column_+j, value );
12579 }
12581 //*************************************************************************************************
12582 
12583 
12584 //*************************************************************************************************
12596 template< typename MT > // Type of the dense matrix
12597 template< typename MT2 > // Type of the right-hand side dense matrix
12598 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
12599  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
12600 {
12602 
12603  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12604  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12605 
12606  const size_t ipos( m_ & size_t(-2) );
12607  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
12608 
12609  for( size_t j=0UL; j<n_; ++j ) {
12610  for( size_t i=0UL; i<ipos; i+=2UL ) {
12611  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
12612  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
12613  }
12614  if( ipos < m_ ) {
12615  matrix_(row_+ipos,column_+j) = (~rhs)(ipos,j);
12616  }
12617  }
12618 }
12620 //*************************************************************************************************
12621 
12622 
12623 //*************************************************************************************************
12635 template< typename MT > // Type of the dense matrix
12636 template< typename MT2 > // Type of the right-hand side dense matrix
12637 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
12638  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
12639 {
12642 
12643  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12644  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12645 
12646  if( useStreaming &&
12647  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
12648  !(~rhs).isAliased( &matrix_ ) )
12649  {
12650  for( size_t j=0UL; j<n_; ++j )
12651  for( size_t i=0UL; i<m_; i+=IT::size )
12652  stream( i, j, (~rhs).load(i,j) );
12653  }
12654  else
12655  {
12656  const size_t ipos( m_ & size_t(-IT::size*4) );
12657  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ipos, "Invalid end calculation" );
12658 
12659  for( size_t j=0UL; j<n_; ++j ) {
12660  typename MT2::ConstIterator it( (~rhs).begin(j) );
12661  for( size_t i=0UL; i<ipos; i+=IT::size*4UL ) {
12662  store( i , j, it.load() ); it += IT::size;
12663  store( i+IT::size , j, it.load() ); it += IT::size;
12664  store( i+IT::size*2UL, j, it.load() ); it += IT::size;
12665  store( i+IT::size*3UL, j, it.load() ); it += IT::size;
12666  }
12667  for( size_t i=ipos; i<m_; i+=IT::size, it+=IT::size ) {
12668  store( i, j, it.load() );
12669  }
12670  }
12671  }
12672 }
12674 //*************************************************************************************************
12675 
12676 
12677 //*************************************************************************************************
12689 template< typename MT > // Type of the dense matrix
12690 template< typename MT2 > // Type of the right-hand side dense matrix
12691 inline void DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
12692 {
12695 
12696  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12697  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12698 
12699  const size_t block( 16UL );
12700 
12701  for( size_t jj=0UL; jj<n_; jj+=block ) {
12702  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
12703  for( size_t ii=0UL; ii<m_; ii+=block ) {
12704  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
12705  for( size_t j=jj; j<jend; ++j ) {
12706  for( size_t i=ii; i<iend; ++i ) {
12707  matrix_(row_+i,column_+j) = (~rhs)(i,j);
12708  }
12709  }
12710  }
12711  }
12712 }
12714 //*************************************************************************************************
12715 
12716 
12717 //*************************************************************************************************
12729 template< typename MT > // Type of the dense matrix
12730 template< typename MT2 > // Type of the right-hand side sparse matrix
12731 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
12732 {
12734 
12735  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12736  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12737 
12738  for( size_t j=0UL; j<n_; ++j )
12739  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
12740  matrix_(row_+element->index(),column_+j) = element->value();
12741 }
12743 //*************************************************************************************************
12744 
12745 
12746 //*************************************************************************************************
12758 template< typename MT > // Type of the dense matrix
12759 template< typename MT2 > // Type of the right-hand side sparse matrix
12760 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
12761 {
12764 
12765  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12766  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12767 
12768  for( size_t i=0UL; i<m_; ++i )
12769  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
12770  matrix_(row_+i,column_+element->index()) = element->value();
12771 }
12773 //*************************************************************************************************
12774 
12775 
12776 //*************************************************************************************************
12788 template< typename MT > // Type of the dense matrix
12789 template< typename MT2 > // Type of the right-hand side dense matrix
12790 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
12791  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
12792 {
12794 
12795  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12796  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12797 
12798  const size_t ipos( m_ & size_t(-2) );
12799  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
12800 
12801  for( size_t j=0UL; j<n_; ++j ) {
12802  for( size_t i=0UL; i<ipos; i+=2UL ) {
12803  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
12804  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
12805  }
12806  if( ipos < m_ ) {
12807  matrix_(row_+ipos,column_+j) += (~rhs)(ipos,j);
12808  }
12809  }
12810 }
12812 //*************************************************************************************************
12813 
12814 
12815 //*************************************************************************************************
12827 template< typename MT > // Type of the dense matrix
12828 template< typename MT2 > // Type of the right-hand side dense matrix
12829 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
12830  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
12831 {
12834 
12835  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12836  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12837 
12838  const size_t ipos( m_ & size_t(-IT::size*4) );
12839  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ipos, "Invalid end calculation" );
12840 
12841  for( size_t j=0UL; j<n_; ++j ) {
12842  typename MT2::ConstIterator it( (~rhs).begin(j) );
12843  for( size_t i=0UL; i<ipos; i+=IT::size*4UL ) {
12844  store( i , j, load(i ,j) + it.load() ); it += IT::size;
12845  store( i+IT::size , j, load(i+IT::size ,j) + it.load() ); it += IT::size;
12846  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
12847  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
12848  }
12849  for( size_t i=ipos; i<m_; i+=IT::size, it+=IT::size ) {
12850  store( i, j, load(i,j) + it.load() );
12851  }
12852  }
12853 }
12855 //*************************************************************************************************
12856 
12857 
12858 //*************************************************************************************************
12870 template< typename MT > // Type of the dense matrix
12871 template< typename MT2 > // Type of the right-hand side dense matrix
12872 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
12873 {
12876 
12877  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12878  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12879 
12880  const size_t block( 16UL );
12881 
12882  for( size_t jj=0UL; jj<n_; jj+=block ) {
12883  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
12884  for( size_t ii=0UL; ii<m_; ii+=block ) {
12885  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
12886  for( size_t j=jj; j<jend; ++j ) {
12887  for( size_t i=ii; i<iend; ++i ) {
12888  matrix_(row_+i,column_+j) += (~rhs)(i,j);
12889  }
12890  }
12891  }
12892  }
12893 }
12895 //*************************************************************************************************
12896 
12897 
12898 //*************************************************************************************************
12910 template< typename MT > // Type of the dense matrix
12911 template< typename MT2 > // Type of the right-hand side sparse matrix
12912 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
12913 {
12915 
12916  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12917  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12918 
12919  for( size_t j=0UL; j<n_; ++j )
12920  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
12921  matrix_(row_+element->index(),column_+j) += element->value();
12922 }
12924 //*************************************************************************************************
12925 
12926 
12927 //*************************************************************************************************
12939 template< typename MT > // Type of the dense matrix
12940 template< typename MT2 > // Type of the right-hand side sparse matrix
12941 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
12942 {
12945 
12946  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12947  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12948 
12949  for( size_t i=0UL; i<m_; ++i )
12950  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
12951  matrix_(row_+i,column_+element->index()) += element->value();
12952 }
12954 //*************************************************************************************************
12955 
12956 
12957 //*************************************************************************************************
12969 template< typename MT > // Type of the dense matrix
12970 template< typename MT2 > // Type of the right-hand side dense matrix
12971 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
12972  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
12973 {
12975 
12976  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
12977  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
12978 
12979  const size_t ipos( m_ & size_t(-2) );
12980  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
12981 
12982  for( size_t j=0UL; j<n_; ++j ) {
12983  for( size_t i=0UL; i<ipos; i+=2UL ) {
12984  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
12985  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
12986  }
12987  if( ipos < m_ ) {
12988  matrix_(row_+ipos,column_+j) -= (~rhs)(ipos,j);
12989  }
12990  }
12991 }
12993 //*************************************************************************************************
12994 
12995 
12996 //*************************************************************************************************
13008 template< typename MT > // Type of the dense matrix
13009 template< typename MT2 > // Type of the right-hand side dense matrix
13010 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
13011  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
13012 {
13015 
13016  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
13017  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
13018 
13019  const size_t ipos( m_ & size_t(-IT::size*4) );
13020  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ipos, "Invalid end calculation" );
13021 
13022  for( size_t j=0UL; j<n_; ++j ) {
13023  typename MT2::ConstIterator it( (~rhs).begin(j) );
13024  for( size_t i=0UL; i<ipos; i+=IT::size*4UL ) {
13025  store( i , j, load(i ,j) - it.load() ); it += IT::size;
13026  store( i+IT::size , j, load(i+IT::size ,j) - it.load() ); it += IT::size;
13027  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
13028  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
13029  }
13030  for( size_t i=ipos; i<m_; i+=IT::size, it+=IT::size ) {
13031  store( i, j, load(i,j) - it.load() );
13032  }
13033  }
13034 }
13036 //*************************************************************************************************
13037 
13038 
13039 //*************************************************************************************************
13051 template< typename MT > // Type of the dense matrix
13052 template< typename MT2 > // Type of the right-hand side dense matrix
13053 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
13054 {
13057 
13058  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
13059  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
13060 
13061  const size_t block( 16UL );
13062 
13063  for( size_t jj=0UL; jj<n_; jj+=block ) {
13064  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
13065  for( size_t ii=0UL; ii<m_; ii+=block ) {
13066  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
13067  for( size_t j=jj; j<jend; ++j ) {
13068  for( size_t i=ii; i<iend; ++i ) {
13069  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
13070  }
13071  }
13072  }
13073  }
13074 }
13076 //*************************************************************************************************
13077 
13078 
13079 //*************************************************************************************************
13091 template< typename MT > // Type of the dense matrix
13092 template< typename MT2 > // Type of the right-hand side sparse matrix
13093 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
13094 {
13096 
13097  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
13098  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
13099 
13100  for( size_t j=0UL; j<n_; ++j )
13101  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
13102  matrix_(row_+element->index(),column_+j) -= element->value();
13103 }
13105 //*************************************************************************************************
13106 
13107 
13108 //*************************************************************************************************
13120 template< typename MT > // Type of the dense matrix
13121 template< typename MT2 > // Type of the right-hand side sparse matrix
13122 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
13123 {
13126 
13127  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
13128  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
13129 
13130  for( size_t i=0UL; i<m_; ++i )
13131  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
13132  matrix_(row_+i,column_+element->index()) -= element->value();
13133 }
13135 //*************************************************************************************************
13136 
13137 
13138 
13139 
13140 
13141 
13142 
13143 
13144 //=================================================================================================
13145 //
13146 // DENSESUBMATRIX OPERATORS
13147 //
13148 //=================================================================================================
13149 
13150 //*************************************************************************************************
13153 template< typename MT, bool AF, bool SO >
13154 inline void reset( DenseSubmatrix<MT,AF,SO>& dm );
13155 
13156 template< typename MT, bool AF, bool SO >
13157 inline void reset( DenseSubmatrix<MT,AF,SO>& dm, size_t i );
13158 
13159 template< typename MT, bool AF, bool SO >
13160 inline void clear( DenseSubmatrix<MT,AF,SO>& dm );
13161 
13162 template< typename MT, bool AF, bool SO >
13163 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm );
13164 
13165 template< typename MT, bool AF, bool SO >
13166 inline bool isSymmetric( const DenseSubmatrix<MT,AF,SO>& dm );
13167 
13168 template< typename MT, bool AF, bool SO >
13169 inline bool isLower( const DenseSubmatrix<MT,AF,SO>& dm );
13170 
13171 template< typename MT, bool AF, bool SO >
13172 inline bool isUpper( const DenseSubmatrix<MT,AF,SO>& dm );
13173 
13174 template< typename MT, bool AF, bool SO >
13175 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseMatrix<MT,SO>& b );
13176 
13177 template< typename MT, bool AF, bool SO >
13178 inline bool isSame( const DenseMatrix<MT,SO>& a, const DenseSubmatrix<MT,AF,SO>& b );
13179 
13180 template< typename MT, bool AF, bool SO >
13181 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseSubmatrix<MT,AF,SO>& b );
13183 //*************************************************************************************************
13184 
13185 
13186 //*************************************************************************************************
13193 template< typename MT // Type of the dense matrix
13194  , bool AF // Alignment flag
13195  , bool SO > // Storage order
13197 {
13198  dm.reset();
13199 }
13200 //*************************************************************************************************
13201 
13202 
13203 //*************************************************************************************************
13216 template< typename MT // Type of the dense matrix
13217  , bool AF // Alignment flag
13218  , bool SO > // Storage order
13219 inline void reset( DenseSubmatrix<MT,AF,SO>& dm, size_t i )
13220 {
13221  dm.reset( i );
13222 }
13223 //*************************************************************************************************
13224 
13225 
13226 //*************************************************************************************************
13235 template< typename MT // Type of the dense matrix
13236  , bool AF // Alignment flag
13237  , bool SO > // Storage order
13239 {
13240  dm.reset();
13241 }
13242 //*************************************************************************************************
13243 
13244 
13245 //*************************************************************************************************
13263 template< typename MT // Type of the dense matrix
13264  , bool AF // Alignment flag
13265  , bool SO > // Storage order
13266 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm )
13267 {
13268  using blaze::isDefault;
13269 
13270  if( SO == rowMajor ) {
13271  for( size_t i=0UL; i<(~dm).rows(); ++i )
13272  for( size_t j=0UL; j<(~dm).columns(); ++j )
13273  if( !isDefault( (~dm)(i,j) ) )
13274  return false;
13275  }
13276  else {
13277  for( size_t j=0UL; j<(~dm).columns(); ++j )
13278  for( size_t i=0UL; i<(~dm).rows(); ++i )
13279  if( !isDefault( (~dm)(i,j) ) )
13280  return false;
13281  }
13282 
13283  return true;
13284 }
13285 //*************************************************************************************************
13286 
13287 
13288 //*************************************************************************************************
13310 template< typename MT // Type of the dense matrix
13311  , bool AF // Alignment flag
13312  , bool SO > // Storage order
13313 inline bool isSymmetric( const DenseSubmatrix<MT,AF,SO>& dm )
13314 {
13315  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
13316 
13317  if( IsSymmetric<MT>::value && dm.row_ == dm.column_ && dm.m_ == dm.n_ )
13318  return true;
13319  else return isSymmetric( static_cast<const BaseType&>( dm ) );
13320 }
13321 //*************************************************************************************************
13322 
13323 
13324 //*************************************************************************************************
13356 template< typename MT // Type of the dense matrix
13357  , bool AF // Alignment flag
13358  , bool SO > // Storage order
13359 inline bool isLower( const DenseSubmatrix<MT,AF,SO>& dm )
13360 {
13361  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
13362 
13363  if( IsLower<MT>::value && dm.row_ == dm.column_ && dm.m_ == dm.n_ )
13364  return true;
13365  else return isLower( static_cast<const BaseType&>( dm ) );
13366 }
13367 //*************************************************************************************************
13368 
13369 
13370 //*************************************************************************************************
13402 template< typename MT // Type of the dense matrix
13403  , bool AF // Alignment flag
13404  , bool SO > // Storage order
13405 inline bool isUpper( const DenseSubmatrix<MT,AF,SO>& dm )
13406 {
13407  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
13408 
13409  if( IsUpper<MT>::value && dm.row_ == dm.column_ && dm.m_ == dm.n_ )
13410  return true;
13411  else return isUpper( static_cast<const BaseType&>( dm ) );
13412 }
13413 //*************************************************************************************************
13414 
13415 
13416 //*************************************************************************************************
13428 template< typename MT // Type of the dense matrix
13429  , bool AF // Alignment flag
13430  , bool SO > // Storage order
13431 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseMatrix<MT,SO>& b )
13432 {
13433  return ( isSame( a.matrix_, ~b ) && ( a.rows() == (~b).rows() ) && ( a.columns() == (~b).columns() ) );
13434 }
13435 //*************************************************************************************************
13436 
13437 
13438 //*************************************************************************************************
13450 template< typename MT // Type of the dense matrix
13451  , bool AF // Alignment flag
13452  , bool SO > // Storage order
13453 inline bool isSame( const DenseMatrix<MT,SO>& a, const DenseSubmatrix<MT,AF,SO>& b )
13454 {
13455  return ( isSame( ~a, b.matrix_ ) && ( (~a).rows() == b.rows() ) && ( (~a).columns() == b.columns() ) );
13456 }
13457 //*************************************************************************************************
13458 
13459 
13460 //*************************************************************************************************
13472 template< typename MT // Type of the dense matrix
13473  , bool AF // Alignment flag
13474  , bool SO > // Storage order
13476 {
13477  return ( isSame( a.matrix_, b.matrix_ ) &&
13478  ( a.row_ == b.row_ ) && ( a.column_ == b.column_ ) &&
13479  ( a.m_ == b.m_ ) && ( a.n_ == b.n_ ) );
13480 }
13481 //*************************************************************************************************
13482 
13483 
13484 //*************************************************************************************************
13499 template< typename MT // Type of the dense matrix
13500  , bool AF // Alignment flag
13501  , bool SO > // Storage order
13502 inline typename DerestrictTrait< DenseSubmatrix<MT,AF,SO> >::Type
13503  derestrict( DenseSubmatrix<MT,AF,SO>& dm )
13504 {
13505  typedef typename DerestrictTrait< DenseSubmatrix<MT,AF,SO> >::Type ReturnType;
13506  return ReturnType( derestrict( dm.matrix_ ), dm.row_, dm.column_, dm.m_, dm.n_ );
13507 }
13509 //*************************************************************************************************
13510 
13511 
13512 
13513 
13514 //=================================================================================================
13515 //
13516 // GLOBAL RESTRUCTURING OPERATORS
13517 //
13518 //=================================================================================================
13519 
13520 //*************************************************************************************************
13535 template< bool AF1 // Required alignment flag
13536  , typename MT // Type of the sparse submatrix
13537  , bool AF2 // Present alignment flag
13538  , bool SO > // Storage order
13539 inline const DenseSubmatrix<MT,AF1,SO>
13540  submatrix( const DenseSubmatrix<MT,AF2,SO>& dm, size_t row, size_t column, size_t m, size_t n )
13541 {
13543 
13544  if( ( row + m > dm.rows() ) || ( column + n > dm.columns() ) )
13545  throw std::invalid_argument( "Invalid submatrix specification" );
13546 
13547  return DenseSubmatrix<MT,AF1,SO>( dm.matrix_, dm.row_ + row, dm.column_ + column, m, n );
13548 }
13550 //*************************************************************************************************
13551 
13552 
13553 
13554 
13555 //=================================================================================================
13556 //
13557 // ISRESTRICTED SPECIALIZATIONS
13558 //
13559 //=================================================================================================
13560 
13561 //*************************************************************************************************
13563 template< typename MT, bool AF, bool SO >
13564 struct IsRestricted< DenseSubmatrix<MT,AF,SO> > : public If< IsRestricted<MT>, TrueType, FalseType >::Type
13565 {
13566  enum { value = IsRestricted<MT>::value };
13567  typedef typename If< IsRestricted<MT>, TrueType, FalseType >::Type Type;
13568 };
13570 //*************************************************************************************************
13571 
13572 
13573 
13574 
13575 //=================================================================================================
13576 //
13577 // DERESTRICTTRAIT SPECIALIZATIONS
13578 //
13579 //=================================================================================================
13580 
13581 //*************************************************************************************************
13583 template< typename MT, bool AF, bool SO >
13584 struct DerestrictTrait< DenseSubmatrix<MT,AF,SO> >
13585 {
13586  typedef DenseSubmatrix< typename RemoveReference< typename DerestrictTrait<MT>::Type >::Type, AF > Type;
13587 };
13589 //*************************************************************************************************
13590 
13591 
13592 
13593 
13594 //=================================================================================================
13595 //
13596 // HASCONSTDATAACCESS SPECIALIZATIONS
13597 //
13598 //=================================================================================================
13599 
13600 //*************************************************************************************************
13602 template< typename MT, bool AF, bool SO >
13603 struct HasConstDataAccess< DenseSubmatrix<MT,AF,SO> >
13604  : public If< HasConstDataAccess<MT>, TrueType, FalseType >::Type
13605 {
13606  enum { value = HasConstDataAccess<MT>::value };
13607  typedef typename If< HasConstDataAccess<MT>, TrueType, FalseType >::Type Type;
13608 };
13610 //*************************************************************************************************
13611 
13612 
13613 
13614 
13615 //=================================================================================================
13616 //
13617 // HASMUTABLEDATAACCESS SPECIALIZATIONS
13618 //
13619 //=================================================================================================
13620 
13621 //*************************************************************************************************
13623 template< typename MT, bool AF, bool SO >
13624 struct HasMutableDataAccess< DenseSubmatrix<MT,AF,SO> >
13625  : public If< HasMutableDataAccess<MT>, TrueType, FalseType >::Type
13626 {
13627  enum { value = HasMutableDataAccess<MT>::value };
13628  typedef typename If< HasMutableDataAccess<MT>, TrueType, FalseType >::Type Type;
13629 };
13631 //*************************************************************************************************
13632 
13633 
13634 
13635 
13636 //=================================================================================================
13637 //
13638 // SUBMATRIXTRAIT SPECIALIZATIONS
13639 //
13640 //=================================================================================================
13641 
13642 //*************************************************************************************************
13644 template< typename MT, bool AF, bool SO >
13645 struct SubmatrixTrait< DenseSubmatrix<MT,AF,SO> >
13646 {
13648 };
13650 //*************************************************************************************************
13651 
13652 
13653 
13654 
13655 //=================================================================================================
13656 //
13657 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
13658 //
13659 //=================================================================================================
13660 
13661 //*************************************************************************************************
13663 template< typename MT, bool AF1, bool SO, bool AF2 >
13664 struct SubmatrixExprTrait< DenseSubmatrix<MT,AF1,SO>, AF2 >
13665 {
13666  typedef DenseSubmatrix<MT,AF2,SO> Type;
13667 };
13669 //*************************************************************************************************
13670 
13671 
13672 //*************************************************************************************************
13674 template< typename MT, bool AF1, bool SO, bool AF2 >
13675 struct SubmatrixExprTrait< const DenseSubmatrix<MT,AF1,SO>, AF2 >
13676 {
13677  typedef DenseSubmatrix<MT,AF2,SO> Type;
13678 };
13680 //*************************************************************************************************
13681 
13682 
13683 //*************************************************************************************************
13685 template< typename MT, bool AF1, bool SO, bool AF2 >
13686 struct SubmatrixExprTrait< volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
13687 {
13688  typedef DenseSubmatrix<MT,AF2,SO> Type;
13689 };
13691 //*************************************************************************************************
13692 
13693 
13694 //*************************************************************************************************
13696 template< typename MT, bool AF1, bool SO, bool AF2 >
13697 struct SubmatrixExprTrait< const volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
13698 {
13699  typedef DenseSubmatrix<MT,AF2,SO> Type;
13700 };
13702 //*************************************************************************************************
13703 
13704 
13705 
13706 
13707 //=================================================================================================
13708 //
13709 // ROWTRAIT SPECIALIZATIONS
13710 //
13711 //=================================================================================================
13712 
13713 //*************************************************************************************************
13715 template< typename MT, bool AF, bool SO >
13716 struct RowTrait< DenseSubmatrix<MT,AF,SO> >
13717 {
13718  typedef typename RowTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
13719 };
13721 //*************************************************************************************************
13722 
13723 
13724 
13725 
13726 //=================================================================================================
13727 //
13728 // COLUMNTRAIT SPECIALIZATIONS
13729 //
13730 //=================================================================================================
13731 
13732 //*************************************************************************************************
13734 template< typename MT, bool AF, bool SO >
13735 struct ColumnTrait< DenseSubmatrix<MT,AF,SO> >
13736 {
13737  typedef typename ColumnTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
13738 };
13740 //*************************************************************************************************
13741 
13742 } // namespace blaze
13743 
13744 #endif
Constraint on the data type.
IfTrue< useConst, ConstPointer, ElementType * >::Type Pointer
Pointer to a non-constant submatrix value.
Definition: DenseSubmatrix.h:518
void stream(size_t i, size_t j, const IntrinsicType &value)
Aligned, non-temporal store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:3283
Constraint on the data type.
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
DenseSubmatrix & transpose()
Transposing the submatrix.
Definition: DenseSubmatrix.h:2199
IteratorCategory iterator_category
The iterator category.
Definition: DenseSubmatrix.h:545
ReferenceType reference
Reference return type.
Definition: DenseSubmatrix.h:548
const size_t column_
The first column of the submatrix.
Definition: DenseSubmatrix.h:1144
Header file for mathematical functions.
const size_t rest_
The number of remaining elements in an unaligned intrinsic operation.
Definition: DenseSubmatrix.h:1147
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: DenseSubmatrix.h:3000
size_t rest() const
Access to the number of remaining elements beyond the final iterator.
Definition: DenseSubmatrix.h:851
#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
IfTrue< useConst, ConstIterator, SubmatrixIterator< typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseSubmatrix.h:881
Header file for the subvector/submatrix alignment flag values.
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
Header file for the subtraction trait.
Header file for basic type definitions.
std::iterator_traits< IteratorType >::difference_type DifferenceType
Difference between two iterators.
Definition: DenseSubmatrix.h:542
DifferenceType difference_type
Difference between two iterators.
Definition: DenseSubmatrix.h:549
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:264
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type stream(T *address, const sse_int16_t &value)
Aligned, non-temporal store of a vector of 2-byte integral values.
Definition: Stream.h:76
Header file for the row trait.
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
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
Header file for the IsSparseMatrix type trait.
SubmatrixIterator(IteratorType iterator, IteratorType finalIterator, size_t remainingElements, bool isMemoryAligned)
Constructor of the SubmatrixIterator class.
Definition: DenseSubmatrix.h:571
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:209
Header file for the IsDiagonal type trait.
#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
#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
Reference operator()(size_t i, size_t j)
2D-access to the dense submatrix elements.
Definition: DenseSubmatrix.h:1274
bool operator<=(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:763
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b)
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:946
Header file for the IsSame and IsStrictlySame type traits.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:692
bool hasOverlap() const
Checking whether there exists an overlap in the context of a symmetric matrix.
Definition: DenseSubmatrix.h:2273
DenseSubmatrix(Operand matrix, size_t row, size_t column, size_t m, size_t n)
The constructor for DenseSubmatrix.
Definition: DenseSubmatrix.h:1238
bool isAligned() const
Returns whether the submatrix is properly aligned in memory.
Definition: DenseSubmatrix.h:3090
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1428
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: DenseSubmatrix.h:3046
const bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Streaming.h:50
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:821
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1476
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2665
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2507
ReferenceType operator*() const
Direct access to the element at the current iterator position.
Definition: DenseSubmatrix.h:665
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
const size_t n_
The number of columns of the submatrix.
Definition: DenseSubmatrix.h:1146
const size_t row_
The first row of the submatrix.
Definition: DenseSubmatrix.h:1143
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
Header file for the And class template.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:118
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:118
CompressedMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:259
const ElementType * ConstPointer
Pointer to a constant submatrix value.
Definition: DenseSubmatrix.h:515
SubmatrixIterator(const SubmatrixIterator< IteratorType2 > &it)
Conversion constructor from different SubmatrixIterator instances.
Definition: DenseSubmatrix.h:586
void reset()
Reset to the default initial values.
Definition: DenseSubmatrix.h:2120
MT::ElementType ElementType
Type of the submatrix elements.
Definition: DenseSubmatrix.h:503
size_t columns() const
Returns the number of columns of the dense submatrix.
Definition: DenseSubmatrix.h:1991
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:118
Header file for the RequiresEvaluation type trait.
bool isAligned() const
Access to the iterator's memory alignment flag.
Definition: DenseSubmatrix.h:861
Pointer data()
Low-level data access to the submatrix elements.
Definition: DenseSubmatrix.h:1317
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1405
size_t rows() const
Returns the number of rows of the dense submatrix.
Definition: DenseSubmatrix.h:1976
Header file for the IsUniLower type trait.
SubmatrixIterator()
Default constructor of the SubmatrixIterator class.
Definition: DenseSubmatrix.h:555
Base class for all submatrices.The Submatrix class serves as a tag for all submatrices (i...
Definition: Submatrix.h:64
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:964
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
friend const SubmatrixIterator operator+(size_t inc, const SubmatrixIterator &it)
Addition between an integral value and a SubmatrixIterator.
Definition: DenseSubmatrix.h:809
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:861
Constraint on the data type.
DenseSubmatrix & operator=(const ElementType &rhs)
Homogenous assignment to all submatrix elements.
Definition: DenseSubmatrix.h:1506
const bool aligned
Alignment flag for aligned subvectors and submatrices.
Definition: AlignmentFlag.h:83
Compile time check for data types with restricted data access.This type trait tests whether the given...
Definition: IsRestricted.h:82
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: DenseSubmatrix.h:500
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1357
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
ValueType value_type
Type of the underlying elements.
Definition: DenseSubmatrix.h:546
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:85
Pointer data()
Low-level data access to the array elements.
Definition: AlignedArray.h:441
bool operator<(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:741
std::iterator_traits< IteratorType >::reference ReferenceType
Reference return type.
Definition: DenseSubmatrix.h:539
IntrinsicType loadu(size_t i, size_t j) const
Unaligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:3164
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type 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
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, sse_int16_t >::Type loadu(const T *address)
Loads a vector of 2-byte integral values.
Definition: Loadu.h:76
Header file for nested template disabiguation.
Header file for the If class template.
Compile time assertion.
IntrinsicType load() const
Aligned load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:680
Constraint on the data type.
Header file for the IsFloatingPoint type trait.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
SubmatrixIterator< typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: DenseSubmatrix.h:878
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
SubmatrixIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DenseSubmatrix.h:600
Header file for the Or class template.
bool operator==(const SubmatrixIterator &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:719
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type store(T *address, const sse_int16_t &value)
Aligned store of a vector of 2-byte integral values.
Definition: Store.h:80
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1602
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
const DenseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: DenseSubmatrix.h:506
const size_t SMP_DMATASSIGN_THRESHOLD
SMP dense matrix assignment threshold.This threshold specifies when an assignment with a simple dense...
Definition: Thresholds.h:690
IntrinsicTrait< typename MT::ElementType > IT
Intrinsic trait for the matrix element type.
Definition: DenseSubmatrix.h:483
Header file for the IsLower type trait.
IntrinsicType load(size_t i, size_t j) const
Aligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:3137
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:79
bool operator!=(const SubmatrixIterator &rhs) const
Inequality comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:730
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.
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: DenseSubmatrix.h:634
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
SubmatrixIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DenseSubmatrix.h:612
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
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: DenseSubmatrix.h:502
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2505
const size_t final_
The final index for unaligned intrinsic operations.
Definition: DenseSubmatrix.h:1148
Constraint on the data type.
std::iterator_traits< IteratorType >::value_type ValueType
Type of the underlying elements.
Definition: DenseSubmatrix.h:533
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2509
System settings for streaming (non-temporal stores)
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:841
Header file for the IsAdaptor type trait.
Header file for the isOne shim.
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:85
Operand matrix_
The dense matrix containing the submatrix.
Definition: DenseSubmatrix.h:1142
Header file for the DerestrictTrait class template.
const bool unaligned
Alignment flag for unaligned subvectors and submatrices.
Definition: AlignmentFlag.h:63
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, sse_int16_t >::Type load(const T *address)
Loads a vector of 2-byte integral values.
Definition: Load.h:79
Constraint on the data type.
IteratorType iterator_
Iterator to the current submatrix element.
Definition: DenseSubmatrix.h:868
Header file for the IsNumeric type trait.
Header file for the HasConstDataAccess type trait.
DenseSubmatrix< MT, AF, SO > This
Type of this DenseSubmatrix instance.
Definition: DenseSubmatrix.h:499
const bool spacing
Adding an additional spacing line between two log messages.This setting gives the opportunity to add ...
Definition: Logging.h:70
bool isAligned_
Memory alignment flag.
Definition: DenseSubmatrix.h:871
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
EnableIf< IsDenseMatrix< MT1 > >::Type smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
#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
Header file for the SubmatrixExprTrait class template.
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2506
Header file for the IsConst type trait.
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:749
IntrinsicType loadu() const
Unaligned load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:695
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:150
EnableIf< IsDenseMatrix< MT1 > >::Type smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
DifferenceType operator-(const SubmatrixIterator &rhs) const
Calculating the number of elements between two iterators.
Definition: DenseSubmatrix.h:785
Base template for the MultTrait class.
Definition: MultTrait.h:150
Header file for the addition trait.
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
Header file for the division trait.
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: DenseSubmatrix.h:623
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: DenseSubmatrix.h:505
Header file for the submatrix trait.
If< IsExpression< MT >, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: DenseSubmatrix.h:480
#define BLAZE_CONSTRAINT_MUST_NOT_BE_RESTRICTED(T)
Constraint on the data type.In case the given data type T does have a restricted data access...
Definition: Restricted.h:118
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Iterator over the elements of the sparse submatrix.
Definition: DenseSubmatrix.h:525
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type storeu(T *address, const sse_int16_t &value)
Unaligned store of a vector of 2-byte integral values.
Definition: Storeu.h:77
const bool isAligned_
Memory alignment flag.
Definition: DenseSubmatrix.h:1153
Header file for the AlignedArray implementation.
Header file for the cache size of the target architecture.
std::iterator_traits< IteratorType >::iterator_category IteratorCategory
The iterator category.
Definition: DenseSubmatrix.h:530
Compile time type negation.The Not class template negates the given compile time condition. In case the given condition would evaluate to true, the nested member enumeration is set to false and vice versa:
Definition: Not.h:70
bool operator>(const SubmatrixIterator &rhs) const
Greater-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:752
#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 column trait.
Header file for the isDefault shim.
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DenseSubmatrix.h:501
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:87
Constraint on the data type.
PointerType pointer
Pointer return type.
Definition: DenseSubmatrix.h:547
Constraint on the data type.
size_t capacity() const
Returns the maximum capacity of the dense submatrix.
Definition: DenseSubmatrix.h:2026
Header file for the HasMutableDataAccess type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:118
Evaluation of the return type of the derestrict function.Via this type trait it is possible to evalua...
Definition: DerestrictTrait.h:74
Header file for the IsReference type trait.
const SubmatrixIterator operator--(int)
Post-decrement operator.
Definition: DenseSubmatrix.h:655
Header file for the RemoveReference type trait.
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
IteratorType final_
The final iterator for intrinsic operations.
Definition: DenseSubmatrix.h:869
void storeu(size_t i, size_t j, const IntrinsicType &value)
Unaligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:3237
IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: DenseSubmatrix.h:512
Header file for all intrinsic functionality.
IteratorType final() const
Access to the final position of the submatrix iterator.
Definition: DenseSubmatrix.h:841
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
size_t nonZeros() const
Returns the number of non-zero elements in the dense submatrix.
Definition: DenseSubmatrix.h:2066
IteratorType base() const
Access to the current position of the submatrix iterator.
Definition: DenseSubmatrix.h:831
IT::Type IntrinsicType
Intrinsic type of the submatrix elements.
Definition: DenseSubmatrix.h:504
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2666
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: DenseSubmatrix.h:509
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
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:937
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
boost::false_type FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:260
EnableIf< IsDenseMatrix< MT1 > >::Type smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
size_t rest_
The number of remaining elements beyond the final iterator.
Definition: DenseSubmatrix.h:870
std::iterator_traits< IteratorType >::pointer PointerType
Pointer return type.
Definition: DenseSubmatrix.h:536
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2502
View on a specific submatrix of a dense matrix.The DenseSubmatrix template represents a view on a spe...
Definition: DenseSubmatrix.h:474
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 canSMPAssign() const
Returns whether the submatrix can be used in SMP assignments.
Definition: DenseSubmatrix.h:3110
Compile time type check.This class tests whether the given template parameter T is a reference type (...
Definition: IsReference.h:94
size_t spacing() const
Returns the spacing between the beginning of two rows/columns.
Definition: DenseSubmatrix.h:2011
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
Implementation of a static array with a fixed alignment.The AlignedArray class template represents a ...
Definition: AlignedArray.h:264
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2508
Base template for the SubTrait class.
Definition: SubTrait.h:150
Header file for the Submatrix base class.
const size_t m_
The number of rows of the submatrix.
Definition: DenseSubmatrix.h:1145
Header file for the IsUpper type trait.
boost::true_type TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
void store(size_t i, size_t j, const IntrinsicType &value)
Aligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:3211
#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
friend const SubmatrixIterator operator-(const SubmatrixIterator &it, size_t dec)
Subtraction between a SubmatrixIterator and an integral value.
Definition: DenseSubmatrix.h:821
const size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
EnableIf< IsNumeric< Type >, bool >::Type isOne(const Type &v)
Returns whether the given value/object represents the numeric value 1.
Definition: IsOne.h:80
Header file for the IsRestricted type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
SubmatrixIterator & operator--()
Pre-decrement operator.
Definition: DenseSubmatrix.h:644
#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
bool operator>=(const SubmatrixIterator &rhs) const
Greater-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:774
Compile time type selection.The IfTrue class template selects one of the two given types T1 and T2 de...
Definition: If.h:59
Header file for the IsExpression type trait class.
friend const SubmatrixIterator operator+(const SubmatrixIterator &it, size_t inc)
Addition between a SubmatrixIterator and an integral value.
Definition: DenseSubmatrix.h:797
Constraint on the data type.
Header file for the FunctionTrace class.
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