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>
58 #include <blaze/math/Functions.h>
59 #include <blaze/math/Intrinsics.h>
61 #include <blaze/math/shims/Clear.h>
91 #include <blaze/system/Blocking.h>
92 #include <blaze/system/CacheSize.h>
93 #include <blaze/system/Inline.h>
97 #include <blaze/util/Assert.h>
101 #include <blaze/util/DisableIf.h>
102 #include <blaze/util/EnableIf.h>
103 #include <blaze/util/Exception.h>
105 #include <blaze/util/mpl/And.h>
106 #include <blaze/util/mpl/If.h>
107 #include <blaze/util/mpl/Not.h>
108 #include <blaze/util/mpl/Or.h>
109 #include <blaze/util/Null.h>
110 #include <blaze/util/Template.h>
111 #include <blaze/util/Types.h>
118 #include <blaze/util/Unused.h>
120 
121 
122 namespace blaze {
123 
124 //=================================================================================================
125 //
126 // CLASS DEFINITION
127 //
128 //=================================================================================================
129 
130 //*************************************************************************************************
477 template< typename MT // Type of the dense matrix
478  , bool AF = unaligned // Alignment flag
479  , bool SO = IsColumnMajorMatrix<MT>::value > // Storage order
480 class DenseSubmatrix : public DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO >
481  , private Submatrix
482 {
483  private:
484  //**Type definitions****************************************************************************
486  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
487 
490  //**********************************************************************************************
491 
492  public:
493  //**Type definitions****************************************************************************
498  typedef typename MT::ElementType ElementType;
499  typedef typename IT::Type IntrinsicType;
500  typedef typename MT::ReturnType ReturnType;
501  typedef const DenseSubmatrix& CompositeType;
502 
505 
507  typedef typename If< IsConst<MT>, ConstReference, typename MT::Reference >::Type Reference;
508 
510  typedef const ElementType* ConstPointer;
511 
514  , ConstPointer, ElementType* >::Type Pointer;
515  //**********************************************************************************************
516 
517  //**SubmatrixIterator class definition**********************************************************
520  template< typename IteratorType > // Type of the dense matrix iterator
522  {
523  public:
524  //**Type definitions*************************************************************************
526  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
527 
529  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
530 
532  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
533 
535  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
536 
538  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
539 
540  // STL iterator requirements
541  typedef IteratorCategory iterator_category;
542  typedef ValueType value_type;
543  typedef PointerType pointer;
544  typedef ReferenceType reference;
545  typedef DifferenceType difference_type;
546  //*******************************************************************************************
547 
548  //**Constructor******************************************************************************
552  : iterator_ ( ) // Iterator to the current submatrix element
553  , isAligned_( false ) // Memory alignment flag
554  {}
555  //*******************************************************************************************
556 
557  //**Constructor******************************************************************************
563  inline SubmatrixIterator( IteratorType iterator, bool isMemoryAligned )
564  : iterator_ ( iterator ) // Iterator to the current submatrix element
565  , isAligned_( isMemoryAligned ) // Memory alignment flag
566  {}
567  //*******************************************************************************************
568 
569  //**Constructor******************************************************************************
574  template< typename IteratorType2 >
576  : iterator_ ( it.base() ) // Iterator to the current submatrix element
577  , isAligned_( it.isAligned() ) // Memory alignment flag
578  {}
579  //*******************************************************************************************
580 
581  //**Addition assignment operator*************************************************************
587  inline SubmatrixIterator& operator+=( size_t inc ) {
588  iterator_ += inc;
589  return *this;
590  }
591  //*******************************************************************************************
592 
593  //**Subtraction assignment operator**********************************************************
599  inline SubmatrixIterator& operator-=( size_t dec ) {
600  iterator_ -= dec;
601  return *this;
602  }
603  //*******************************************************************************************
604 
605  //**Prefix increment operator****************************************************************
611  ++iterator_;
612  return *this;
613  }
614  //*******************************************************************************************
615 
616  //**Postfix increment operator***************************************************************
621  inline const SubmatrixIterator operator++( int ) {
623  }
624  //*******************************************************************************************
625 
626  //**Prefix decrement operator****************************************************************
632  --iterator_;
633  return *this;
634  }
635  //*******************************************************************************************
636 
637  //**Postfix decrement operator***************************************************************
642  inline const SubmatrixIterator operator--( int ) {
644  }
645  //*******************************************************************************************
646 
647  //**Element access operator******************************************************************
652  inline ReferenceType operator*() const {
653  return *iterator_;
654  }
655  //*******************************************************************************************
656 
657  //**Load function****************************************************************************
667  inline IntrinsicType load() const {
668  if( isAligned_ )
669  return loada();
670  else
671  return loadu();
672  }
673  //*******************************************************************************************
674 
675  //**Loada function***************************************************************************
685  inline IntrinsicType loada() const {
686  return iterator_.loada();
687  }
688  //*******************************************************************************************
689 
690  //**Loadu function***************************************************************************
700  inline IntrinsicType loadu() const {
701  return iterator_.loadu();
702  }
703  //*******************************************************************************************
704 
705  //**Equality operator************************************************************************
711  inline bool operator==( const SubmatrixIterator& rhs ) const {
712  return iterator_ == rhs.iterator_;
713  }
714  //*******************************************************************************************
715 
716  //**Inequality operator**********************************************************************
722  inline bool operator!=( const SubmatrixIterator& rhs ) const {
723  return iterator_ != rhs.iterator_;
724  }
725  //*******************************************************************************************
726 
727  //**Less-than operator***********************************************************************
733  inline bool operator<( const SubmatrixIterator& rhs ) const {
734  return iterator_ < rhs.iterator_;
735  }
736  //*******************************************************************************************
737 
738  //**Greater-than operator********************************************************************
744  inline bool operator>( const SubmatrixIterator& rhs ) const {
745  return iterator_ > rhs.iterator_;
746  }
747  //*******************************************************************************************
748 
749  //**Less-or-equal-than operator**************************************************************
755  inline bool operator<=( const SubmatrixIterator& rhs ) const {
756  return iterator_ <= rhs.iterator_;
757  }
758  //*******************************************************************************************
759 
760  //**Greater-or-equal-than operator***********************************************************
766  inline bool operator>=( const SubmatrixIterator& rhs ) const {
767  return iterator_ >= rhs.iterator_;
768  }
769  //*******************************************************************************************
770 
771  //**Subtraction operator*********************************************************************
777  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
778  return iterator_ - rhs.iterator_;
779  }
780  //*******************************************************************************************
781 
782  //**Addition operator************************************************************************
789  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
790  return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
791  }
792  //*******************************************************************************************
793 
794  //**Addition operator************************************************************************
801  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
802  return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
803  }
804  //*******************************************************************************************
805 
806  //**Subtraction operator*********************************************************************
813  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
814  return SubmatrixIterator( it.iterator_ - dec, it.isAligned_ );
815  }
816  //*******************************************************************************************
817 
818  //**Base function****************************************************************************
823  inline IteratorType base() const {
824  return iterator_;
825  }
826  //*******************************************************************************************
827 
828  //**IsAligned function***********************************************************************
833  inline bool isAligned() const {
834  return isAligned_;
835  }
836  //*******************************************************************************************
837 
838  private:
839  //**Member variables*************************************************************************
840  IteratorType iterator_;
841  bool isAligned_;
842  //*******************************************************************************************
843  };
844  //**********************************************************************************************
845 
846  //**Type definitions****************************************************************************
849 
851  typedef typename If< IsConst<MT>, ConstIterator, SubmatrixIterator<typename MT::Iterator> >::Type Iterator;
852  //**********************************************************************************************
853 
854  //**Compilation flags***************************************************************************
856  enum { vectorizable = MT::vectorizable };
857 
859  enum { smpAssignable = MT::smpAssignable };
860  //**********************************************************************************************
861 
862  //**Constructors********************************************************************************
865  explicit inline DenseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
866  // No explicitly declared copy constructor.
868  //**********************************************************************************************
869 
870  //**Destructor**********************************************************************************
871  // No explicitly declared destructor.
872  //**********************************************************************************************
873 
874  //**Data access functions***********************************************************************
877  inline Reference operator()( size_t i, size_t j );
878  inline ConstReference operator()( size_t i, size_t j ) const;
879  inline Reference at( size_t i, size_t j );
880  inline ConstReference at( size_t i, size_t j ) const;
881  inline Pointer data ();
882  inline ConstPointer data () const;
883  inline Pointer data ( size_t i );
884  inline ConstPointer data ( size_t i ) const;
885  inline Iterator begin ( size_t i );
886  inline ConstIterator begin ( size_t i ) const;
887  inline ConstIterator cbegin( size_t i ) const;
888  inline Iterator end ( size_t i );
889  inline ConstIterator end ( size_t i ) const;
890  inline ConstIterator cend ( size_t i ) const;
892  //**********************************************************************************************
893 
894  //**Assignment operators************************************************************************
897  inline DenseSubmatrix& operator=( const ElementType& rhs );
898  inline DenseSubmatrix& operator=( const DenseSubmatrix& rhs );
899 
900  template< typename MT2, bool SO2 >
901  inline DenseSubmatrix& operator=( const Matrix<MT2,SO2>& rhs );
902 
903  template< typename MT2, bool SO2 >
904  inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
905  operator+=( const Matrix<MT2,SO2>& rhs );
906 
907  template< typename MT2, bool SO2 >
908  inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
909  operator+=( const Matrix<MT2,SO2>& rhs );
910 
911  template< typename MT2, bool SO2 >
912  inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
913  operator-=( const Matrix<MT2,SO2>& rhs );
914 
915  template< typename MT2, bool SO2 >
916  inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
917  operator-=( const Matrix<MT2,SO2>& rhs );
918 
919  template< typename MT2, bool SO2 >
920  inline DenseSubmatrix& operator*=( const Matrix<MT2,SO2>& rhs );
921 
922  template< typename Other >
923  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
924  operator*=( Other rhs );
925 
926  template< typename Other >
927  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
928  operator/=( Other rhs );
930  //**********************************************************************************************
931 
932  //**Utility functions***************************************************************************
935  inline size_t row() const;
936  inline size_t rows() const;
937  inline size_t column() const;
938  inline size_t columns() const;
939  inline size_t spacing() const;
940  inline size_t capacity() const;
941  inline size_t capacity( size_t i ) const;
942  inline size_t nonZeros() const;
943  inline size_t nonZeros( size_t i ) const;
944  inline void reset();
945  inline void reset( size_t i );
946  inline DenseSubmatrix& transpose();
947  inline DenseSubmatrix& ctranspose();
948  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
950  //**********************************************************************************************
951 
952  private:
953  //**********************************************************************************************
955  template< typename MT2 >
957  struct VectorizedAssign {
958  enum { value = useOptimizedKernels &&
959  vectorizable && MT2::vectorizable &&
960  IsSame<ElementType,typename MT2::ElementType>::value };
961  };
963  //**********************************************************************************************
964 
965  //**********************************************************************************************
967  template< typename MT2 >
969  struct VectorizedAddAssign {
970  enum { value = useOptimizedKernels &&
971  vectorizable && MT2::vectorizable &&
972  IsSame<ElementType,typename MT2::ElementType>::value &&
973  IntrinsicTrait<ElementType>::addition };
974  };
976  //**********************************************************************************************
977 
978  //**********************************************************************************************
980  template< typename MT2 >
982  struct VectorizedSubAssign {
983  enum { value = useOptimizedKernels &&
984  vectorizable && MT2::vectorizable &&
985  IsSame<ElementType,typename MT2::ElementType>::value &&
986  IntrinsicTrait<ElementType>::subtraction };
987  };
989  //**********************************************************************************************
990 
991  public:
992  //**Expression template evaluation functions****************************************************
995  template< typename Other >
996  inline bool canAlias( const Other* alias ) const;
997 
998  template< typename MT2, bool AF2, bool SO2 >
999  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
1000 
1001  template< typename Other >
1002  inline bool isAliased( const Other* alias ) const;
1003 
1004  template< typename MT2, bool AF2, bool SO2 >
1005  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
1006 
1007  inline bool isAligned () const;
1008  inline bool canSMPAssign() const;
1009 
1010  inline IntrinsicType load ( size_t i, size_t j ) const;
1011  inline IntrinsicType loada( size_t i, size_t j ) const;
1012  inline IntrinsicType loadu( size_t i, size_t j ) const;
1013 
1014  inline void store ( size_t i, size_t j, const IntrinsicType& value );
1015  inline void storea( size_t i, size_t j, const IntrinsicType& value );
1016  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
1017  inline void stream( size_t i, size_t j, const IntrinsicType& value );
1018 
1019  template< typename MT2 >
1020  inline typename DisableIf< VectorizedAssign<MT2> >::Type
1021  assign( const DenseMatrix<MT2,SO>& rhs );
1022 
1023  template< typename MT2 >
1024  inline typename EnableIf< VectorizedAssign<MT2> >::Type
1025  assign( const DenseMatrix<MT2,SO>& rhs );
1026 
1027  template< typename MT2 > inline void assign( const DenseMatrix<MT2,!SO>& rhs );
1028  template< typename MT2 > inline void assign( const SparseMatrix<MT2,SO>& rhs );
1029  template< typename MT2 > inline void assign( const SparseMatrix<MT2,!SO>& rhs );
1030 
1031  template< typename MT2 >
1032  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
1033  addAssign( const DenseMatrix<MT2,SO>& rhs );
1034 
1035  template< typename MT2 >
1036  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
1037  addAssign( const DenseMatrix<MT2,SO>& rhs );
1038 
1039  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,!SO>& rhs );
1040  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,SO>& rhs );
1041  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,!SO>& rhs );
1042 
1043  template< typename MT2 >
1044  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
1045  subAssign( const DenseMatrix<MT2,SO>& rhs );
1046 
1047  template< typename MT2 >
1048  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
1049  subAssign( const DenseMatrix<MT2,SO>& rhs );
1050 
1051  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,!SO>& rhs );
1052  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,SO>& rhs );
1053  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,!SO>& rhs );
1055  //**********************************************************************************************
1056 
1057  private:
1058  //**Utility functions***************************************************************************
1061  inline bool hasOverlap() const;
1063  //**********************************************************************************************
1064 
1065  //**Member variables****************************************************************************
1068  Operand matrix_;
1069  const size_t row_;
1070  const size_t column_;
1071  const size_t m_;
1072  const size_t n_;
1073  const bool isAligned_;
1074 
1081  //**********************************************************************************************
1082 
1083  //**Friend declarations*************************************************************************
1085  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
1086 
1087  template< bool AF1, typename MT2, bool AF2, bool SO2 >
1088  friend const DenseSubmatrix<MT2,AF1,SO2>
1089  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
1090 
1091  template< typename MT2, bool AF2, bool SO2 >
1092  friend bool isIntact( const DenseSubmatrix<MT2,AF2,SO2>& dm );
1093 
1094  template< typename MT2, bool AF2, bool SO2 >
1095  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
1096 
1097  template< typename MT2, bool AF2, bool SO2 >
1098  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
1099 
1100  template< typename MT2, bool AF2, bool SO2 >
1101  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
1102 
1103  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
1104  friend bool tryAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
1105  size_t row, size_t column );
1106 
1107  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
1108  friend bool tryAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
1109  size_t row, size_t column );
1110 
1111  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
1112  friend bool tryAddAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
1113  size_t row, size_t column );
1114 
1115  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
1116  friend bool tryAddAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
1117  size_t row, size_t column );
1118 
1119  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
1120  friend bool trySubAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
1121  size_t row, size_t column );
1122 
1123  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
1124  friend bool trySubAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
1125  size_t row, size_t column );
1126 
1127  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
1128  friend bool tryMultAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
1129  size_t row, size_t column );
1130 
1131  template< typename MT2, bool AF2, bool SO2 >
1132  friend typename DerestrictTrait< DenseSubmatrix<MT2,AF2,SO2> >::Type
1133  derestrict( DenseSubmatrix<MT2,AF2,SO2>& dm );
1135  //**********************************************************************************************
1136 
1137  //**Compile time checks*************************************************************************
1147  //**********************************************************************************************
1148 };
1149 //*************************************************************************************************
1150 
1151 
1152 
1153 
1154 //=================================================================================================
1155 //
1156 // CONSTRUCTOR
1157 //
1158 //=================================================================================================
1159 
1160 //*************************************************************************************************
1173 template< typename MT // Type of the dense matrix
1174  , bool AF // Alignment flag
1175  , bool SO > // Storage order
1176 inline DenseSubmatrix<MT,AF,SO>::DenseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
1177  : matrix_ ( matrix ) // The dense matrix containing the submatrix
1178  , row_ ( rindex ) // The first row of the submatrix
1179  , column_ ( cindex ) // The first column of the submatrix
1180  , m_ ( m ) // The number of rows of the submatrix
1181  , n_ ( n ) // The number of columns of the submatrix
1182  , isAligned_( vectorizable && matrix.data() != NULL && checkAlignment( data() ) &&
1183  ( m < 2UL || ( matrix.spacing() & size_t(-IT::size) ) == 0UL ) )
1184 {
1185  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
1186  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
1187  }
1188 }
1189 //*************************************************************************************************
1190 
1191 
1192 
1193 
1194 //=================================================================================================
1195 //
1196 // DATA ACCESS FUNCTIONS
1197 //
1198 //=================================================================================================
1199 
1200 //*************************************************************************************************
1210 template< typename MT // Type of the dense matrix
1211  , bool AF // Alignment flag
1212  , bool SO > // Storage order
1215 {
1216  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1217  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1218 
1219  return matrix_(row_+i,column_+j);
1220 }
1221 //*************************************************************************************************
1222 
1223 
1224 //*************************************************************************************************
1234 template< typename MT // Type of the dense matrix
1235  , bool AF // Alignment flag
1236  , bool SO > // Storage order
1238  DenseSubmatrix<MT,AF,SO>::operator()( size_t i, size_t j ) const
1239 {
1240  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
1241  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1242 
1243  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
1244 }
1245 //*************************************************************************************************
1246 
1247 
1248 //*************************************************************************************************
1259 template< typename MT // Type of the dense matrix
1260  , bool AF // Alignment flag
1261  , bool SO > // Storage order
1263  DenseSubmatrix<MT,AF,SO>::at( size_t i, size_t j )
1264 {
1265  if( i >= rows() ) {
1266  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1267  }
1268  if( j >= columns() ) {
1269  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1270  }
1271  return (*this)(i,j);
1272 }
1273 //*************************************************************************************************
1274 
1275 
1276 //*************************************************************************************************
1287 template< typename MT // Type of the dense matrix
1288  , bool AF // Alignment flag
1289  , bool SO > // Storage order
1291  DenseSubmatrix<MT,AF,SO>::at( size_t i, size_t j ) const
1292 {
1293  if( i >= rows() ) {
1294  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1295  }
1296  if( j >= columns() ) {
1297  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1298  }
1299  return (*this)(i,j);
1300 }
1301 //*************************************************************************************************
1302 
1303 
1304 //*************************************************************************************************
1313 template< typename MT // Type of the dense matrix
1314  , bool AF // Alignment flag
1315  , bool SO > // Storage order
1317 {
1318  return matrix_.data() + row_*spacing() + column_;
1319 }
1320 //*************************************************************************************************
1321 
1322 
1323 //*************************************************************************************************
1332 template< typename MT // Type of the dense matrix
1333  , bool AF // Alignment flag
1334  , bool SO > // Storage order
1336 {
1337  return matrix_.data() + row_*spacing() + column_;
1338 }
1339 //*************************************************************************************************
1340 
1341 
1342 //*************************************************************************************************
1350 template< typename MT // Type of the dense matrix
1351  , bool AF // Alignment flag
1352  , bool SO > // Storage order
1354 {
1355  return matrix_.data() + (row_+i)*spacing() + column_;
1356 }
1357 //*************************************************************************************************
1358 
1359 
1360 //*************************************************************************************************
1368 template< typename MT // Type of the dense matrix
1369  , bool AF // Alignment flag
1370  , bool SO > // Storage order
1372 {
1373  return matrix_.data() + (row_+i)*spacing() + column_;
1374 }
1375 //*************************************************************************************************
1376 
1377 
1378 //*************************************************************************************************
1389 template< typename MT // Type of the dense matrix
1390  , bool AF // Alignment flag
1391  , bool SO > // Storage order
1393 {
1394  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1395  return Iterator( matrix_.begin( row_ + i ) + column_, isAligned_ );
1396 }
1397 //*************************************************************************************************
1398 
1399 
1400 //*************************************************************************************************
1411 template< typename MT // Type of the dense matrix
1412  , bool AF // Alignment flag
1413  , bool SO > // Storage order
1416 {
1417  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1418  return ConstIterator( matrix_.cbegin( row_ + i ) + column_, isAligned_ );
1419 }
1420 //*************************************************************************************************
1421 
1422 
1423 //*************************************************************************************************
1434 template< typename MT // Type of the dense matrix
1435  , bool AF // Alignment flag
1436  , bool SO > // Storage order
1439 {
1440  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1441  return ConstIterator( matrix_.cbegin( row_ + i ) + column_, isAligned_ );
1442 }
1443 //*************************************************************************************************
1444 
1445 
1446 //*************************************************************************************************
1457 template< typename MT // Type of the dense matrix
1458  , bool AF // Alignment flag
1459  , bool SO > // Storage order
1461 {
1462  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1463  return Iterator( matrix_.begin( row_ + i ) + column_ + n_, isAligned_ );
1464 }
1465 //*************************************************************************************************
1466 
1467 
1468 //*************************************************************************************************
1479 template< typename MT // Type of the dense matrix
1480  , bool AF // Alignment flag
1481  , bool SO > // Storage order
1484 {
1485  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1486  return ConstIterator( matrix_.cbegin( row_ + i ) + column_ + n_, isAligned_ );
1487 }
1488 //*************************************************************************************************
1489 
1490 
1491 //*************************************************************************************************
1502 template< typename MT // Type of the dense matrix
1503  , bool AF // Alignment flag
1504  , bool SO > // Storage order
1507 {
1508  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
1509  return ConstIterator( matrix_.cbegin( row_ + i ) + column_ + n_, isAligned_ );
1510 }
1511 //*************************************************************************************************
1512 
1513 
1514 
1515 
1516 //=================================================================================================
1517 //
1518 // ASSIGNMENT OPERATORS
1519 //
1520 //=================================================================================================
1521 
1522 //*************************************************************************************************
1532 template< typename MT // Type of the dense matrix
1533  , bool AF // Alignment flag
1534  , bool SO > // Storage order
1536 {
1537  const size_t iend( row_ + m_ );
1538 
1539  for( size_t i=row_; i<iend; ++i )
1540  {
1541  const size_t jbegin( ( IsUpper<MT>::value )
1543  ?( max( i+1UL, column_ ) )
1544  :( max( i, column_ ) ) )
1545  :( column_ ) );
1546  const size_t jend ( ( IsLower<MT>::value )
1548  ?( min( i, column_+n_ ) )
1549  :( min( i+1UL, column_+n_ ) ) )
1550  :( column_+n_ ) );
1551 
1552  for( size_t j=jbegin; j<jend; ++j )
1553  matrix_(i,j) = rhs;
1554  }
1555 
1556  return *this;
1557 }
1558 //*************************************************************************************************
1559 
1560 
1561 //*************************************************************************************************
1575 template< typename MT // Type of the dense matrix
1576  , bool AF // Alignment flag
1577  , bool SO > // Storage order
1579 {
1582 
1583  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
1584  return *this;
1585 
1586  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
1587  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
1588  }
1589 
1590  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
1591  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1592  }
1593 
1594  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1595 
1596  if( rhs.canAlias( &matrix_ ) ) {
1597  const ResultType tmp( rhs );
1598  smpAssign( left, tmp );
1599  }
1600  else {
1601  smpAssign( left, rhs );
1602  }
1603 
1604  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1605 
1606  return *this;
1607 }
1608 //*************************************************************************************************
1609 
1610 
1611 //*************************************************************************************************
1625 template< typename MT // Type of the dense matrix
1626  , bool AF // Alignment flag
1627  , bool SO > // Storage order
1628 template< typename MT2 // Type of the right-hand side matrix
1629  , bool SO2 > // Storage order of the right-hand side matrix
1631 {
1633 
1634  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1635  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1636  }
1637 
1638  typedef typename If< IsRestricted<MT>, typename MT2::CompositeType, const MT2& >::Type Right;
1639  Right right( ~rhs );
1640 
1641  if( !tryAssign( matrix_, right, row_, column_ ) ) {
1642  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1643  }
1644 
1646  reset();
1647 
1648  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1649 
1650  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1651  const typename MT2::ResultType tmp( right );
1652  smpAssign( left, tmp );
1653  }
1654  else {
1655  smpAssign( left, right );
1656  }
1657 
1658  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1659 
1660  return *this;
1661 }
1662 //*************************************************************************************************
1663 
1664 
1665 //*************************************************************************************************
1678 template< typename MT // Type of the dense matrix
1679  , bool AF // Alignment flag
1680  , bool SO > // Storage order
1681 template< typename MT2 // Type of the right-hand side matrix
1682  , bool SO2 > // Storage order of the right-hand side matrix
1684  , DenseSubmatrix<MT,AF,SO>& >::Type
1686 {
1690 
1691  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
1692 
1695 
1696  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1697  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1698  }
1699 
1700  if( !tryAddAssign( matrix_, ~rhs, row_, column_ ) ) {
1701  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1702  }
1703 
1704  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1705 
1706  if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
1707  (~rhs).canAlias( &matrix_ ) ) {
1708  const AddType tmp( *this + (~rhs) );
1709  smpAssign( left, tmp );
1710  }
1711  else {
1712  smpAddAssign( left, ~rhs );
1713  }
1714 
1715  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1716 
1717  return *this;
1718 }
1719 //*************************************************************************************************
1720 
1721 
1722 //*************************************************************************************************
1735 template< typename MT // Type of the dense matrix
1736  , bool AF // Alignment flag
1737  , bool SO > // Storage order
1738 template< typename MT2 // Type of the right-hand side matrix
1739  , bool SO2 > // Storage order of the right-hand side matrix
1740 inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
1741  , DenseSubmatrix<MT,AF,SO>& >::Type
1743 {
1747 
1748  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
1749 
1752 
1753  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1754  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1755  }
1756 
1757  const AddType tmp( *this + (~rhs) );
1758 
1759  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1760  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1761  }
1762 
1763  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1764 
1765  smpAssign( left, tmp );
1766 
1767  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1768 
1769  return *this;
1770 }
1771 //*************************************************************************************************
1772 
1773 
1774 //*************************************************************************************************
1787 template< typename MT // Type of the dense matrix
1788  , bool AF // Alignment flag
1789  , bool SO > // Storage order
1790 template< typename MT2 // Type of the right-hand side matrix
1791  , bool SO2 > // Storage order of the right-hand side matrix
1792 inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
1793  , DenseSubmatrix<MT,AF,SO>& >::Type
1795 {
1799 
1800  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
1801 
1804 
1805  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1806  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1807  }
1808 
1809  if( !trySubAssign( matrix_, ~rhs, row_, column_ ) ) {
1810  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1811  }
1812 
1813  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1814 
1815  if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
1816  (~rhs).canAlias( &matrix_ ) ) {
1817  const SubType tmp( *this - (~rhs ) );
1818  smpAssign( left, tmp );
1819  }
1820  else {
1821  smpSubAssign( left, ~rhs );
1822  }
1823 
1824  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1825 
1826  return *this;
1827 }
1828 //*************************************************************************************************
1829 
1830 
1831 //*************************************************************************************************
1844 template< typename MT // Type of the dense matrix
1845  , bool AF // Alignment flag
1846  , bool SO > // Storage order
1847 template< typename MT2 // Type of the right-hand side matrix
1848  , bool SO2 > // Storage order of the right-hand side matrix
1849 inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
1850  , DenseSubmatrix<MT,AF,SO>& >::Type
1852 {
1856 
1857  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
1858 
1861 
1862  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1863  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1864  }
1865 
1866  const SubType tmp( *this - (~rhs) );
1867 
1868  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1869  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1870  }
1871 
1872  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1873 
1874  smpAssign( left, tmp );
1875 
1876  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1877 
1878  return *this;
1879 }
1880 //*************************************************************************************************
1881 
1882 
1883 //*************************************************************************************************
1896 template< typename MT // Type of the dense matrix
1897  , bool AF // Alignment flag
1898  , bool SO > // Storage order
1899 template< typename MT2 // Type of the right-hand side matrix
1900  , bool SO2 > // Storage order of the right-hand side matrix
1902 {
1906 
1907  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
1908 
1911 
1912  if( columns() != (~rhs).rows() ) {
1913  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1914  }
1915 
1916  const MultType tmp( *this * (~rhs) );
1917 
1918  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
1919  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1920  }
1921 
1922  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1923 
1924  smpAssign( left, tmp );
1925 
1926  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1927 
1928  return *this;
1929 }
1930 //*************************************************************************************************
1931 
1932 
1933 //*************************************************************************************************
1943 template< typename MT // Type of the dense matrix
1944  , bool AF // Alignment flag
1945  , bool SO > // Storage order
1946 template< typename Other > // Data type of the right-hand side scalar
1947 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1949 {
1951 
1952  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1953  smpAssign( left, (*this) * rhs );
1954 
1955  return *this;
1956 }
1957 //*************************************************************************************************
1958 
1959 
1960 //*************************************************************************************************
1972 template< typename MT // Type of the dense matrix
1973  , bool AF // Alignment flag
1974  , bool SO > // Storage order
1975 template< typename Other > // Data type of the right-hand side scalar
1976 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,AF,SO> >::Type&
1978 {
1980 
1981  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1982 
1983  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1984  smpAssign( left, (*this) / rhs );
1985 
1986  return *this;
1987 }
1988 //*************************************************************************************************
1989 
1990 
1991 
1992 
1993 //=================================================================================================
1994 //
1995 // UTILITY FUNCTIONS
1996 //
1997 //=================================================================================================
1998 
1999 //*************************************************************************************************
2004 template< typename MT // Type of the dense matrix
2005  , bool AF // Alignment flag
2006  , bool SO > // Storage order
2007 inline size_t DenseSubmatrix<MT,AF,SO>::row() const
2008 {
2009  return row_;
2010 }
2011 //*************************************************************************************************
2012 
2013 
2014 //*************************************************************************************************
2019 template< typename MT // Type of the dense matrix
2020  , bool AF // Alignment flag
2021  , bool SO > // Storage order
2022 inline size_t DenseSubmatrix<MT,AF,SO>::rows() const
2023 {
2024  return m_;
2025 }
2026 //*************************************************************************************************
2027 
2028 
2029 //*************************************************************************************************
2034 template< typename MT // Type of the dense matrix
2035  , bool AF // Alignment flag
2036  , bool SO > // Storage order
2038 {
2039  return column_;
2040 }
2041 //*************************************************************************************************
2042 
2043 
2044 //*************************************************************************************************
2049 template< typename MT // Type of the dense matrix
2050  , bool AF // Alignment flag
2051  , bool SO > // Storage order
2053 {
2054  return n_;
2055 }
2056 //*************************************************************************************************
2057 
2058 
2059 //*************************************************************************************************
2069 template< typename MT // Type of the dense matrix
2070  , bool AF // Alignment flag
2071  , bool SO > // Storage order
2073 {
2074  return matrix_.spacing();
2075 }
2076 //*************************************************************************************************
2077 
2078 
2079 //*************************************************************************************************
2084 template< typename MT // Type of the dense matrix
2085  , bool AF // Alignment flag
2086  , bool SO > // Storage order
2088 {
2089  return rows() * columns();
2090 }
2091 //*************************************************************************************************
2092 
2093 
2094 //*************************************************************************************************
2105 template< typename MT // Type of the dense matrix
2106  , bool AF // Alignment flag
2107  , bool SO > // Storage order
2108 inline size_t DenseSubmatrix<MT,AF,SO>::capacity( size_t i ) const
2109 {
2110  UNUSED_PARAMETER( i );
2111 
2112  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2113 
2114  return columns();
2115 }
2116 //*************************************************************************************************
2117 
2118 
2119 //*************************************************************************************************
2124 template< typename MT // Type of the dense matrix
2125  , bool AF // Alignment flag
2126  , bool SO > // Storage order
2128 {
2129  const size_t iend( row_ + m_ );
2130  const size_t jend( column_ + n_ );
2131  size_t nonzeros( 0UL );
2132 
2133  for( size_t i=row_; i<iend; ++i )
2134  for( size_t j=column_; j<jend; ++j )
2135  if( !isDefault( matrix_(i,j) ) )
2136  ++nonzeros;
2137 
2138  return nonzeros;
2139 }
2140 //*************************************************************************************************
2141 
2142 
2143 //*************************************************************************************************
2154 template< typename MT // Type of the dense matrix
2155  , bool AF // Alignment flag
2156  , bool SO > // Storage order
2157 inline size_t DenseSubmatrix<MT,AF,SO>::nonZeros( size_t i ) const
2158 {
2159  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2160 
2161  const size_t jend( column_ + n_ );
2162  size_t nonzeros( 0UL );
2163 
2164  for( size_t j=column_; j<jend; ++j )
2165  if( !isDefault( matrix_(row_+i,j) ) )
2166  ++nonzeros;
2167 
2168  return nonzeros;
2169 }
2170 //*************************************************************************************************
2171 
2172 
2173 //*************************************************************************************************
2178 template< typename MT // Type of the dense matrix
2179  , bool AF // Alignment flag
2180  , bool SO > // Storage order
2182 {
2183  using blaze::clear;
2184 
2185  for( size_t i=row_; i<row_+m_; ++i )
2186  {
2187  const size_t jbegin( ( IsUpper<MT>::value )
2189  ?( max( i+1UL, column_ ) )
2190  :( max( i, column_ ) ) )
2191  :( column_ ) );
2192  const size_t jend ( ( IsLower<MT>::value )
2194  ?( min( i, column_+n_ ) )
2195  :( min( i+1UL, column_+n_ ) ) )
2196  :( column_+n_ ) );
2197 
2198  for( size_t j=jbegin; j<jend; ++j )
2199  clear( matrix_(i,j) );
2200  }
2201 }
2202 //*************************************************************************************************
2203 
2204 
2205 //*************************************************************************************************
2216 template< typename MT // Type of the dense matrix
2217  , bool AF // Alignment flag
2218  , bool SO > // Storage order
2219 inline void DenseSubmatrix<MT,AF,SO>::reset( size_t i )
2220 {
2221  using blaze::clear;
2222 
2223  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
2224 
2225  const size_t jbegin( ( IsUpper<MT>::value )
2227  ?( max( i+1UL, column_ ) )
2228  :( max( i, column_ ) ) )
2229  :( column_ ) );
2230  const size_t jend ( ( IsLower<MT>::value )
2232  ?( min( i, column_+n_ ) )
2233  :( min( i+1UL, column_+n_ ) ) )
2234  :( column_+n_ ) );
2235 
2236  for( size_t j=jbegin; j<jend; ++j )
2237  clear( matrix_(row_+i,j) );
2238 }
2239 //*************************************************************************************************
2240 
2241 
2242 //*************************************************************************************************
2259 template< typename MT // Type of the dense matrix
2260  , bool AF // Alignment flag
2261  , bool SO > // Storage order
2263 {
2264  if( m_ != n_ ) {
2265  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2266  }
2267 
2268  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
2269  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2270  }
2271 
2272  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
2273  const ResultType tmp( trans( *this ) );
2274  smpAssign( left, tmp );
2275 
2276  return *this;
2277 }
2278 //*************************************************************************************************
2279 
2280 
2281 //*************************************************************************************************
2298 template< typename MT // Type of the dense matrix
2299  , bool AF // Alignment flag
2300  , bool SO > // Storage order
2302 {
2303  if( m_ != n_ ) {
2304  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
2305  }
2306 
2307  if( !tryAssign( matrix_, ctrans( *this ), row_, column_ ) ) {
2308  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
2309  }
2310 
2311  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
2312  const ResultType tmp( ctrans( *this ) );
2313  smpAssign( left, tmp );
2314 
2315  return *this;
2316 }
2317 //*************************************************************************************************
2318 
2319 
2320 //*************************************************************************************************
2330 template< typename MT // Type of the dense matrix
2331  , bool AF // Alignment flag
2332  , bool SO > // Storage order
2333 template< typename Other > // Data type of the scalar value
2335 {
2337 
2338  const size_t iend( row_ + m_ );
2339 
2340  for( size_t i=row_; i<iend; ++i )
2341  {
2342  const size_t jbegin( ( IsUpper<MT>::value )
2344  ?( max( i+1UL, column_ ) )
2345  :( max( i, column_ ) ) )
2346  :( column_ ) );
2347  const size_t jend ( ( IsLower<MT>::value )
2349  ?( min( i, column_+n_ ) )
2350  :( min( i+1UL, column_+n_ ) ) )
2351  :( column_+n_ ) );
2352 
2353  for( size_t j=jbegin; j<jend; ++j )
2354  matrix_(i,j) *= scalar;
2355  }
2356 
2357  return *this;
2358 }
2359 //*************************************************************************************************
2360 
2361 
2362 //*************************************************************************************************
2371 template< typename MT // Type of the dense matrix
2372  , bool AF // Alignment flag
2373  , bool SO > // Storage order
2375 {
2376  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
2377 
2378  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
2379  return false;
2380  else return true;
2381 }
2382 //*************************************************************************************************
2383 
2384 
2385 
2386 
2387 //=================================================================================================
2388 //
2389 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2390 //
2391 //=================================================================================================
2392 
2393 //*************************************************************************************************
2403 template< typename MT // Type of the dense matrix
2404  , bool AF // Alignment flag
2405  , bool SO > // Storage order
2406 template< typename Other > // Data type of the foreign expression
2407 inline bool DenseSubmatrix<MT,AF,SO>::canAlias( const Other* alias ) const
2408 {
2409  return matrix_.isAliased( alias );
2410 }
2411 //*************************************************************************************************
2412 
2413 
2414 //*************************************************************************************************
2424 template< typename MT // Type of the dense matrix
2425  , bool AF // Alignment flag
2426  , bool SO > // Storage order
2427 template< typename MT2 // Data type of the foreign dense submatrix
2428  , bool AF2 // Alignment flag of the foreign dense submatrix
2429  , bool SO2 > // Storage order of the foreign dense submatrix
2431 {
2432  return ( matrix_.isAliased( &alias->matrix_ ) &&
2433  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
2434  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
2435 }
2436 //*************************************************************************************************
2437 
2438 
2439 //*************************************************************************************************
2449 template< typename MT // Type of the dense matrix
2450  , bool AF // Alignment flag
2451  , bool SO > // Storage order
2452 template< typename Other > // Data type of the foreign expression
2453 inline bool DenseSubmatrix<MT,AF,SO>::isAliased( const Other* alias ) const
2454 {
2455  return matrix_.isAliased( alias );
2456 }
2457 //*************************************************************************************************
2458 
2459 
2460 //*************************************************************************************************
2470 template< typename MT // Type of the dense matrix
2471  , bool AF // Alignment flag
2472  , bool SO > // Storage order
2473 template< typename MT2 // Data type of the foreign dense submatrix
2474  , bool AF2 // Alignment flag of the foreign dense submatrix
2475  , bool SO2 > // Storage order of the foreign dense submatrix
2477 {
2478  return ( matrix_.isAliased( &alias->matrix_ ) &&
2479  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
2480  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
2481 }
2482 //*************************************************************************************************
2483 
2484 
2485 //*************************************************************************************************
2494 template< typename MT // Type of the dense matrix
2495  , bool AF // Alignment flag
2496  , bool SO > // Storage order
2498 {
2499  return isAligned_;
2500 }
2501 //*************************************************************************************************
2502 
2503 
2504 //*************************************************************************************************
2514 template< typename MT // Type of the dense matrix
2515  , bool AF // Alignment flag
2516  , bool SO > // Storage order
2518 {
2519  return ( rows() > SMP_DMATASSIGN_THRESHOLD );
2520 }
2521 //*************************************************************************************************
2522 
2523 
2524 //*************************************************************************************************
2539 template< typename MT // Type of the dense matrix
2540  , bool AF // Alignment flag
2541  , bool SO > // Storage order
2543  DenseSubmatrix<MT,AF,SO>::load( size_t i, size_t j ) const
2544 {
2545  if( isAligned_ )
2546  return loada( i, j );
2547  else
2548  return loadu( i, j );
2549 }
2550 //*************************************************************************************************
2551 
2552 
2553 //*************************************************************************************************
2569 template< typename MT // Type of the dense matrix
2570  , bool AF // Alignment flag
2571  , bool SO > // Storage order
2573  DenseSubmatrix<MT,AF,SO>::loada( size_t i, size_t j ) const
2574 {
2576 
2577  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
2578  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
2579  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
2580  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2581 
2582  return matrix_.loada( row_+i, column_+j );
2583 }
2584 //*************************************************************************************************
2585 
2586 
2587 //*************************************************************************************************
2603 template< typename MT // Type of the dense matrix
2604  , bool AF // Alignment flag
2605  , bool SO > // Storage order
2607  DenseSubmatrix<MT,AF,SO>::loadu( size_t i, size_t j ) const
2608 {
2610 
2611  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
2612  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
2613  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
2614  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2615 
2616  return matrix_.loadu( row_+i, column_+j );
2617 }
2618 //*************************************************************************************************
2619 
2620 
2621 //*************************************************************************************************
2637 template< typename MT // Type of the dense matrix
2638  , bool AF // Alignment flag
2639  , bool SO > // Storage order
2640 inline void DenseSubmatrix<MT,AF,SO>::store( size_t i, size_t j, const IntrinsicType& value )
2641 {
2642  if( isAligned_ )
2643  storea( i, j, value );
2644  else
2645  storeu( i, j, value );
2646 }
2647 //*************************************************************************************************
2648 
2649 
2650 //*************************************************************************************************
2666 template< typename MT // Type of the dense matrix
2667  , bool AF // Alignment flag
2668  , bool SO > // Storage order
2669 inline void DenseSubmatrix<MT,AF,SO>::storea( size_t i, size_t j, const IntrinsicType& value )
2670 {
2672 
2673  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
2674  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
2675  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
2676  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2677 
2678  matrix_.storea( row_+i, column_+j, value );
2679 }
2680 //*************************************************************************************************
2681 
2682 
2683 //*************************************************************************************************
2699 template< typename MT // Type of the dense matrix
2700  , bool AF // Alignment flag
2701  , bool SO > // Storage order
2702 inline void DenseSubmatrix<MT,AF,SO>::storeu( size_t i, size_t j, const IntrinsicType& value )
2703 {
2705 
2706  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
2707  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
2708  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
2709  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2710 
2711  matrix_.storeu( row_+i, column_+j, value );
2712 }
2713 //*************************************************************************************************
2714 
2715 
2716 //*************************************************************************************************
2733 template< typename MT // Type of the dense matrix
2734  , bool AF // Alignment flag
2735  , bool SO > // Storage order
2736 inline void DenseSubmatrix<MT,AF,SO>::stream( size_t i, size_t j, const IntrinsicType& value )
2737 {
2739 
2740  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
2741  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
2742  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
2743  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2744 
2745  if( isAligned_ )
2746  matrix_.stream( row_+i, column_+j, value );
2747  else
2748  matrix_.storeu( row_+i, column_+j, value );
2749 }
2750 //*************************************************************************************************
2751 
2752 
2753 //*************************************************************************************************
2764 template< typename MT // Type of the dense matrix
2765  , bool AF // Alignment flag
2766  , bool SO > // Storage order
2767 template< typename MT2 > // Type of the right-hand side dense matrix
2768 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
2770 {
2771  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2772  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2773 
2774  const size_t jpos( n_ & size_t(-2) );
2775  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2776 
2777  for( size_t i=0UL; i<m_; ++i ) {
2778  for( size_t j=0UL; j<jpos; j+=2UL ) {
2779  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
2780  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
2781  }
2782  if( jpos < n_ ) {
2783  matrix_(row_+i,column_+jpos) = (~rhs)(i,jpos);
2784  }
2785  }
2786 }
2787 //*************************************************************************************************
2788 
2789 
2790 //*************************************************************************************************
2801 template< typename MT // Type of the dense matrix
2802  , bool AF // Alignment flag
2803  , bool SO > // Storage order
2804 template< typename MT2 > // Type of the right-hand side dense matrix
2805 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
2807 {
2809 
2810  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2811  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2812 
2813  const size_t jpos( n_ & size_t(-IT::size) );
2814  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size) ) ) == jpos, "Invalid end calculation" );
2815 
2816  if( useStreaming && isAligned_ &&
2817  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2818  !(~rhs).isAliased( &matrix_ ) )
2819  {
2820  for( size_t i=0UL; i<m_; ++i )
2821  {
2822  size_t j( 0UL );
2823 
2824  for( ; j<jpos; j+=IT::size ) {
2825  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
2826  }
2827  for( ; j<n_; ++j ) {
2828  matrix_(row_+i,column_+j) = (~rhs)(i,j);
2829  }
2830  }
2831  }
2832  else
2833  {
2834  for( size_t i=0UL; i<m_; ++i )
2835  {
2836  size_t j( 0UL );
2837  typename MT2::ConstIterator it( (~rhs).begin(i) );
2838 
2839  for( ; (j+IT::size*3UL) < jpos; j+=IT::size*4UL ) {
2840  store( i, j , it.load() ); it += IT::size;
2841  store( i, j+IT::size , it.load() ); it += IT::size;
2842  store( i, j+IT::size*2UL, it.load() ); it += IT::size;
2843  store( i, j+IT::size*3UL, it.load() ); it += IT::size;
2844  }
2845  for( ; j<jpos; j+=IT::size, it+=IT::size ) {
2846  store( i, j, it.load() );
2847  }
2848  for( ; j<n_; ++j, ++it ) {
2849  matrix_(row_+i,column_+j) = *it;
2850  }
2851  }
2852  }
2853 }
2854 //*************************************************************************************************
2855 
2856 
2857 //*************************************************************************************************
2868 template< typename MT // Type of the dense matrix
2869  , bool AF // Alignment flag
2870  , bool SO > // Storage order
2871 template< typename MT2 > // Type of the right-hand side dense matrix
2873 {
2875 
2876  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2877  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2878 
2879  const size_t block( BLOCK_SIZE );
2880 
2881  for( size_t ii=0UL; ii<m_; ii+=block ) {
2882  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2883  for( size_t jj=0UL; jj<n_; jj+=block ) {
2884  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2885  for( size_t i=ii; i<iend; ++i ) {
2886  for( size_t j=jj; j<jend; ++j ) {
2887  matrix_(row_+i,column_+j) = (~rhs)(i,j);
2888  }
2889  }
2890  }
2891  }
2892 }
2893 //*************************************************************************************************
2894 
2895 
2896 //*************************************************************************************************
2907 template< typename MT // Type of the dense matrix
2908  , bool AF // Alignment flag
2909  , bool SO > // Storage order
2910 template< typename MT2 > // Type of the right-hand side sparse matrix
2912 {
2913  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2914  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2915 
2916  for( size_t i=0UL; i<m_; ++i )
2917  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2918  matrix_(row_+i,column_+element->index()) = element->value();
2919 }
2920 //*************************************************************************************************
2921 
2922 
2923 //*************************************************************************************************
2934 template< typename MT // Type of the dense matrix
2935  , bool AF // Alignment flag
2936  , bool SO > // Storage order
2937 template< typename MT2 > // Type of the right-hand side sparse matrix
2939 {
2941 
2942  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2943  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2944 
2945  for( size_t j=0UL; j<n_; ++j )
2946  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2947  matrix_(row_+element->index(),column_+j) = element->value();
2948 }
2949 //*************************************************************************************************
2950 
2951 
2952 //*************************************************************************************************
2963 template< typename MT // Type of the dense matrix
2964  , bool AF // Alignment flag
2965  , bool SO > // Storage order
2966 template< typename MT2 > // Type of the right-hand side dense matrix
2967 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
2969 {
2970  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2971  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2972 
2973  const size_t jpos( n_ & size_t(-2) );
2974  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2975 
2976  for( size_t i=0UL; i<m_; ++i ) {
2977  for( size_t j=0UL; j<jpos; j+=2UL ) {
2978  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
2979  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
2980  }
2981  if( jpos < n_ ) {
2982  matrix_(row_+i,column_+jpos) += (~rhs)(i,jpos);
2983  }
2984  }
2985 }
2986 //*************************************************************************************************
2987 
2988 
2989 //*************************************************************************************************
3000 template< typename MT // Type of the dense matrix
3001  , bool AF // Alignment flag
3002  , bool SO > // Storage order
3003 template< typename MT2 > // Type of the right-hand side dense matrix
3004 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
3006 {
3008 
3009  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3010  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3011 
3012  for( size_t i=0UL; i<m_; ++i )
3013  {
3014  const size_t jbegin( ( IsUpper<MT2>::value )
3015  ?( ( IsStrictlyUpper<MT2>::value ? i+1UL : i ) & size_t(-IT::size) )
3016  :( 0UL ) );
3017  const size_t jend ( ( IsLower<MT2>::value )
3018  ?( IsStrictlyLower<MT2>::value ? i : i+1UL )
3019  :( n_ ) );
3020  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3021 
3022  const size_t jpos( jend & size_t(-IT::size) );
3023  BLAZE_INTERNAL_ASSERT( ( jend - ( jend % (IT::size) ) ) == jpos, "Invalid end calculation" );
3024 
3025  size_t j( jbegin );
3026  typename MT2::ConstIterator it( (~rhs).begin(i) );
3027 
3028  for( ; (j+IT::size*3UL) < jpos; j+=IT::size*4UL ) {
3029  store( i, j , load(i,j ) + it.load() ); it += IT::size;
3030  store( i, j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
3031  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
3032  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
3033  }
3034  for( ; j<jpos; j+=IT::size, it+=IT::size ) {
3035  store( i, j, load(i,j) + it.load() );
3036  }
3037  for( ; j<jend; ++j, ++it ) {
3038  matrix_(row_+i,column_+j) += *it;
3039  }
3040  }
3041 }
3042 //*************************************************************************************************
3043 
3044 
3045 //*************************************************************************************************
3056 template< typename MT // Type of the dense matrix
3057  , bool AF // Alignment flag
3058  , bool SO > // Storage order
3059 template< typename MT2 > // Type of the right-hand side dense matrix
3061 {
3063 
3064  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3065  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3066 
3067  const size_t block( BLOCK_SIZE );
3068 
3069  for( size_t ii=0UL; ii<m_; ii+=block ) {
3070  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3071  for( size_t jj=0UL; jj<n_; jj+=block ) {
3072  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3073  for( size_t i=ii; i<iend; ++i ) {
3074  for( size_t j=jj; j<jend; ++j ) {
3075  matrix_(row_+i,column_+j) += (~rhs)(i,j);
3076  }
3077  }
3078  }
3079  }
3080 }
3081 //*************************************************************************************************
3082 
3083 
3084 //*************************************************************************************************
3095 template< typename MT // Type of the dense matrix
3096  , bool AF // Alignment flag
3097  , bool SO > // Storage order
3098 template< typename MT2 > // Type of the right-hand side sparse matrix
3100 {
3101  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3102  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3103 
3104  for( size_t i=0UL; i<m_; ++i )
3105  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3106  matrix_(row_+i,column_+element->index()) += element->value();
3107 }
3108 //*************************************************************************************************
3109 
3110 
3111 //*************************************************************************************************
3122 template< typename MT // Type of the dense matrix
3123  , bool AF // Alignment flag
3124  , bool SO > // Storage order
3125 template< typename MT2 > // Type of the right-hand side sparse matrix
3127 {
3129 
3130  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3131  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3132 
3133  for( size_t j=0UL; j<n_; ++j )
3134  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3135  matrix_(row_+element->index(),column_+j) += element->value();
3136 }
3137 //*************************************************************************************************
3138 
3139 
3140 //*************************************************************************************************
3151 template< typename MT // Type of the dense matrix
3152  , bool AF // Alignment flag
3153  , bool SO > // Storage order
3154 template< typename MT2 > // Type of the right-hand side dense matrix
3155 inline typename DisableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
3157 {
3158  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3159  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3160 
3161  const size_t jpos( n_ & size_t(-2) );
3162  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
3163 
3164  for( size_t i=0UL; i<m_; ++i ) {
3165  for( size_t j=0UL; j<jpos; j+=2UL ) {
3166  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
3167  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
3168  }
3169  if( jpos < n_ ) {
3170  matrix_(row_+i,column_+jpos) -= (~rhs)(i,jpos);
3171  }
3172  }
3173 }
3174 //*************************************************************************************************
3175 
3176 
3177 //*************************************************************************************************
3188 template< typename MT // Type of the dense matrix
3189  , bool AF // Alignment flag
3190  , bool SO > // Storage order
3191 template< typename MT2 > // Type of the right-hand side dense matrix
3192 inline typename EnableIf< typename DenseSubmatrix<MT,AF,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
3194 {
3196 
3197  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3198  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3199 
3200  for( size_t i=0UL; i<m_; ++i )
3201  {
3202  const size_t jbegin( ( IsUpper<MT2>::value )
3203  ?( ( IsStrictlyUpper<MT2>::value ? i+1UL : i ) & size_t(-IT::size) )
3204  :( 0UL ) );
3205  const size_t jend ( ( IsLower<MT2>::value )
3206  ?( IsStrictlyLower<MT2>::value ? i : i+1UL )
3207  :( n_ ) );
3208  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3209 
3210  const size_t jpos( jend & size_t(-IT::size) );
3211  BLAZE_INTERNAL_ASSERT( ( jend - ( jend % (IT::size) ) ) == jpos, "Invalid end calculation" );
3212 
3213  size_t j( jbegin );
3214  typename MT2::ConstIterator it( (~rhs).begin(i) );
3215 
3216  for( ; (j+IT::size*3UL) < jpos; j+=IT::size*4UL ) {
3217  store( i, j , load(i,j ) - it.load() ); it += IT::size;
3218  store( i, j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
3219  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
3220  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
3221  }
3222  for( ; j<jpos; j+=IT::size, it+=IT::size ) {
3223  store( i, j, load(i,j) - it.load() );
3224  }
3225  for( ; j<jend; ++j, ++it ) {
3226  matrix_(row_+i,column_+j) -= *it;
3227  }
3228  }
3229 }
3230 //*************************************************************************************************
3231 
3232 
3233 //*************************************************************************************************
3244 template< typename MT // Type of the dense matrix
3245  , bool AF // Alignment flag
3246  , bool SO > // Storage order
3247 template< typename MT2 > // Type of the right-hand side dense matrix
3249 {
3251 
3252  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3253  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3254 
3255  const size_t block( BLOCK_SIZE );
3256 
3257  for( size_t ii=0UL; ii<m_; ii+=block ) {
3258  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3259  for( size_t jj=0UL; jj<n_; jj+=block ) {
3260  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3261  for( size_t i=ii; i<iend; ++i ) {
3262  for( size_t j=jj; j<jend; ++j ) {
3263  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
3264  }
3265  }
3266  }
3267  }
3268 }
3269 //*************************************************************************************************
3270 
3271 
3272 //*************************************************************************************************
3283 template< typename MT // Type of the dense matrix
3284  , bool AF // Alignment flag
3285  , bool SO > // Storage order
3286 template< typename MT2 > // Type of the right-hand side sparse matrix
3288 {
3289  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3290  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3291 
3292  for( size_t i=0UL; i<m_; ++i )
3293  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3294  matrix_(row_+i,column_+element->index()) -= element->value();
3295 }
3296 //*************************************************************************************************
3297 
3298 
3299 //*************************************************************************************************
3310 template< typename MT // Type of the dense matrix
3311  , bool AF // Alignment flag
3312  , bool SO > // Storage order
3313 template< typename MT2 > // Type of the right-hand side sparse matrix
3315 {
3317 
3318  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3319  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3320 
3321  for( size_t j=0UL; j<n_; ++j )
3322  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3323  matrix_(row_+element->index(),column_+j) -= element->value();
3324 }
3325 //*************************************************************************************************
3326 
3327 
3328 
3329 
3330 
3331 
3332 
3333 
3334 //=================================================================================================
3335 //
3336 // CLASS TEMPLATE SPECIALIZATION FOR UNALIGNED COLUMN-MAJOR MATRICES
3337 //
3338 //=================================================================================================
3339 
3340 //*************************************************************************************************
3348 template< typename MT > // Type of the dense matrix
3349 class DenseSubmatrix<MT,unaligned,true> : public DenseMatrix< DenseSubmatrix<MT,unaligned,true>, true >
3350  , private Submatrix
3351 {
3352  private:
3353  //**Type definitions****************************************************************************
3355  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
3356 
3359  //**********************************************************************************************
3360 
3361  public:
3362  //**Type definitions****************************************************************************
3364  typedef typename SubmatrixTrait<MT>::Type ResultType;
3365  typedef typename ResultType::OppositeType OppositeType;
3366  typedef typename ResultType::TransposeType TransposeType;
3367  typedef typename MT::ElementType ElementType;
3368  typedef typename IT::Type IntrinsicType;
3369  typedef typename MT::ReturnType ReturnType;
3370  typedef const DenseSubmatrix& CompositeType;
3371 
3373  typedef typename MT::ConstReference ConstReference;
3374 
3376  typedef typename If< IsConst<MT>, ConstReference, typename MT::Reference >::Type Reference;
3377 
3379  typedef const ElementType* ConstPointer;
3380 
3383  , ConstPointer, ElementType* >::Type Pointer;
3384  //**********************************************************************************************
3385 
3386  //**SubmatrixIterator class definition**********************************************************
3389  template< typename IteratorType > // Type of the dense matrix iterator
3390  class SubmatrixIterator
3391  {
3392  public:
3393  //**Type definitions*************************************************************************
3395  typedef typename std::iterator_traits<IteratorType>::iterator_category IteratorCategory;
3396 
3398  typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
3399 
3401  typedef typename std::iterator_traits<IteratorType>::pointer PointerType;
3402 
3404  typedef typename std::iterator_traits<IteratorType>::reference ReferenceType;
3405 
3407  typedef typename std::iterator_traits<IteratorType>::difference_type DifferenceType;
3408 
3409  // STL iterator requirements
3410  typedef IteratorCategory iterator_category;
3411  typedef ValueType value_type;
3412  typedef PointerType pointer;
3413  typedef ReferenceType reference;
3414  typedef DifferenceType difference_type;
3415  //*******************************************************************************************
3416 
3417  //**Constructor******************************************************************************
3420  inline SubmatrixIterator()
3421  : iterator_ ( ) // Iterator to the current submatrix element
3422  , isAligned_( false ) // Memory alignment flag
3423  {}
3424  //*******************************************************************************************
3425 
3426  //**Constructor******************************************************************************
3434  inline SubmatrixIterator( IteratorType iterator, bool isMemoryAligned )
3435  : iterator_ ( iterator ) // Iterator to the current submatrix element
3436  , isAligned_( isMemoryAligned ) // Memory alignment flag
3437  {}
3438  //*******************************************************************************************
3439 
3440  //**Constructor******************************************************************************
3445  template< typename IteratorType2 >
3446  inline SubmatrixIterator( const SubmatrixIterator<IteratorType2>& it )
3447  : iterator_ ( it.base() ) // Iterator to the current submatrix element
3448  , isAligned_( it.isAligned() ) // Memory alignment flag
3449  {}
3450  //*******************************************************************************************
3451 
3452  //**Addition assignment operator*************************************************************
3458  inline SubmatrixIterator& operator+=( size_t inc ) {
3459  iterator_ += inc;
3460  return *this;
3461  }
3462  //*******************************************************************************************
3463 
3464  //**Subtraction assignment operator**********************************************************
3470  inline SubmatrixIterator& operator-=( size_t dec ) {
3471  iterator_ -= dec;
3472  return *this;
3473  }
3474  //*******************************************************************************************
3475 
3476  //**Prefix increment operator****************************************************************
3481  inline SubmatrixIterator& operator++() {
3482  ++iterator_;
3483  return *this;
3484  }
3485  //*******************************************************************************************
3486 
3487  //**Postfix increment operator***************************************************************
3492  inline const SubmatrixIterator operator++( int ) {
3493  return SubmatrixIterator( iterator_++, isAligned_ );
3494  }
3495  //*******************************************************************************************
3496 
3497  //**Prefix decrement operator****************************************************************
3502  inline SubmatrixIterator& operator--() {
3503  --iterator_;
3504  return *this;
3505  }
3506  //*******************************************************************************************
3507 
3508  //**Postfix decrement operator***************************************************************
3513  inline const SubmatrixIterator operator--( int ) {
3514  return SubmatrixIterator( iterator_--, isAligned_ );
3515  }
3516  //*******************************************************************************************
3517 
3518  //**Element access operator******************************************************************
3523  inline ReferenceType operator*() const {
3524  return *iterator_;
3525  }
3526  //*******************************************************************************************
3527 
3528  //**Load function****************************************************************************
3538  inline IntrinsicType load() const {
3539  if( isAligned_ )
3540  return loada();
3541  else
3542  return loadu();
3543  }
3544  //*******************************************************************************************
3545 
3546  //**Loada function***************************************************************************
3556  inline IntrinsicType loada() const {
3557  return iterator_.loada();
3558  }
3559  //*******************************************************************************************
3560 
3561  //**Loadu function***************************************************************************
3571  inline IntrinsicType loadu() const {
3572  return iterator_.loadu();
3573  }
3574  //*******************************************************************************************
3575 
3576  //**Equality operator************************************************************************
3582  inline bool operator==( const SubmatrixIterator& rhs ) const {
3583  return iterator_ == rhs.iterator_;
3584  }
3585  //*******************************************************************************************
3586 
3587  //**Inequality operator**********************************************************************
3593  inline bool operator!=( const SubmatrixIterator& rhs ) const {
3594  return iterator_ != rhs.iterator_;
3595  }
3596  //*******************************************************************************************
3597 
3598  //**Less-than operator***********************************************************************
3604  inline bool operator<( const SubmatrixIterator& rhs ) const {
3605  return iterator_ < rhs.iterator_;
3606  }
3607  //*******************************************************************************************
3608 
3609  //**Greater-than operator********************************************************************
3615  inline bool operator>( const SubmatrixIterator& rhs ) const {
3616  return iterator_ > rhs.iterator_;
3617  }
3618  //*******************************************************************************************
3619 
3620  //**Less-or-equal-than operator**************************************************************
3626  inline bool operator<=( const SubmatrixIterator& rhs ) const {
3627  return iterator_ <= rhs.iterator_;
3628  }
3629  //*******************************************************************************************
3630 
3631  //**Greater-or-equal-than operator***********************************************************
3637  inline bool operator>=( const SubmatrixIterator& rhs ) const {
3638  return iterator_ >= rhs.iterator_;
3639  }
3640  //*******************************************************************************************
3641 
3642  //**Subtraction operator*********************************************************************
3648  inline DifferenceType operator-( const SubmatrixIterator& rhs ) const {
3649  return iterator_ - rhs.iterator_;
3650  }
3651  //*******************************************************************************************
3652 
3653  //**Addition operator************************************************************************
3660  friend inline const SubmatrixIterator operator+( const SubmatrixIterator& it, size_t inc ) {
3661  return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
3662  }
3663  //*******************************************************************************************
3664 
3665  //**Addition operator************************************************************************
3672  friend inline const SubmatrixIterator operator+( size_t inc, const SubmatrixIterator& it ) {
3673  return SubmatrixIterator( it.iterator_ + inc, it.isAligned_ );
3674  }
3675  //*******************************************************************************************
3676 
3677  //**Subtraction operator*********************************************************************
3684  friend inline const SubmatrixIterator operator-( const SubmatrixIterator& it, size_t dec ) {
3685  return SubmatrixIterator( it.iterator_ - dec, it.isAligned_ );
3686  }
3687  //*******************************************************************************************
3688 
3689  //**Base function****************************************************************************
3694  inline IteratorType base() const {
3695  return iterator_;
3696  }
3697  //*******************************************************************************************
3698 
3699  //**IsAligned function***********************************************************************
3704  inline bool isAligned() const {
3705  return isAligned_;
3706  }
3707  //*******************************************************************************************
3708 
3709  private:
3710  //**Member variables*************************************************************************
3711  IteratorType iterator_;
3712  bool isAligned_;
3713  //*******************************************************************************************
3714  };
3715  //**********************************************************************************************
3716 
3717  //**Type definitions****************************************************************************
3719  typedef SubmatrixIterator<typename MT::ConstIterator> ConstIterator;
3720 
3722  typedef typename If< IsConst<MT>, ConstIterator, SubmatrixIterator<typename MT::Iterator> >::Type Iterator;
3723  //**********************************************************************************************
3724 
3725  //**Compilation flags***************************************************************************
3727  enum { vectorizable = MT::vectorizable };
3728 
3730  enum { smpAssignable = MT::smpAssignable };
3731  //**********************************************************************************************
3732 
3733  //**Constructors********************************************************************************
3736  explicit inline DenseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
3737  // No explicitly declared copy constructor.
3739  //**********************************************************************************************
3740 
3741  //**Destructor**********************************************************************************
3742  // No explicitly declared destructor.
3743  //**********************************************************************************************
3744 
3745  //**Data access functions***********************************************************************
3748  inline Reference operator()( size_t i, size_t j );
3749  inline ConstReference operator()( size_t i, size_t j ) const;
3750  inline Reference at( size_t i, size_t j );
3751  inline ConstReference at( size_t i, size_t j ) const;
3752  inline Pointer data ();
3753  inline ConstPointer data () const;
3754  inline Pointer data ( size_t j );
3755  inline ConstPointer data ( size_t j ) const;
3756  inline Iterator begin ( size_t j );
3757  inline ConstIterator begin ( size_t j ) const;
3758  inline ConstIterator cbegin( size_t j ) const;
3759  inline Iterator end ( size_t j );
3760  inline ConstIterator end ( size_t j ) const;
3761  inline ConstIterator cend ( size_t j ) const;
3763  //**********************************************************************************************
3764 
3765  //**Assignment operators************************************************************************
3768  inline DenseSubmatrix& operator=( const ElementType& rhs );
3769  inline DenseSubmatrix& operator=( const DenseSubmatrix& rhs );
3770 
3771  template< typename MT2, bool SO >
3772  inline DenseSubmatrix& operator=( const Matrix<MT2,SO>& rhs );
3773 
3774  template< typename MT2, bool SO >
3775  inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
3776  operator+=( const Matrix<MT2,SO>& rhs );
3777 
3778  template< typename MT2, bool SO >
3779  inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
3780  operator+=( const Matrix<MT2,SO>& rhs );
3781 
3782  template< typename MT2, bool SO >
3783  inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
3784  operator-=( const Matrix<MT2,SO>& rhs );
3785 
3786  template< typename MT2, bool SO >
3787  inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
3788  operator-=( const Matrix<MT2,SO>& rhs );
3789 
3790  template< typename MT2, bool SO >
3791  inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
3792 
3793  template< typename Other >
3794  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
3795  operator*=( Other rhs );
3796 
3797  template< typename Other >
3798  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
3799  operator/=( Other rhs );
3801  //**********************************************************************************************
3802 
3803  //**Utility functions***************************************************************************
3806  inline size_t row() const;
3807  inline size_t rows() const;
3808  inline size_t column() const;
3809  inline size_t columns() const;
3810  inline size_t spacing() const;
3811  inline size_t capacity() const;
3812  inline size_t capacity( size_t i ) const;
3813  inline size_t nonZeros() const;
3814  inline size_t nonZeros( size_t i ) const;
3815  inline void reset();
3816  inline void reset( size_t i );
3817  inline DenseSubmatrix& transpose();
3818  inline DenseSubmatrix& ctranspose();
3819  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
3821  //**********************************************************************************************
3822 
3823  private:
3824  //**********************************************************************************************
3826  template< typename MT2 >
3827  struct VectorizedAssign {
3828  enum { value = useOptimizedKernels &&
3829  vectorizable && MT2::vectorizable &&
3830  IsSame<ElementType,typename MT2::ElementType>::value };
3831  };
3832  //**********************************************************************************************
3833 
3834  //**********************************************************************************************
3836  template< typename MT2 >
3837  struct VectorizedAddAssign {
3838  enum { value = useOptimizedKernels &&
3839  vectorizable && MT2::vectorizable &&
3840  IsSame<ElementType,typename MT2::ElementType>::value &&
3841  IntrinsicTrait<ElementType>::addition };
3842  };
3843  //**********************************************************************************************
3844 
3845  //**********************************************************************************************
3847  template< typename MT2 >
3848  struct VectorizedSubAssign {
3849  enum { value = useOptimizedKernels &&
3850  vectorizable && MT2::vectorizable &&
3851  IsSame<ElementType,typename MT2::ElementType>::value &&
3852  IntrinsicTrait<ElementType>::subtraction };
3853  };
3854  //**********************************************************************************************
3855 
3856  public:
3857  //**Expression template evaluation functions****************************************************
3860  template< typename Other >
3861  inline bool canAlias( const Other* alias ) const;
3862 
3863  template< typename MT2, bool AF2, bool SO2 >
3864  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
3865 
3866  template< typename Other >
3867  inline bool isAliased( const Other* alias ) const;
3868 
3869  template< typename MT2, bool AF2, bool SO2 >
3870  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
3871 
3872  inline bool isAligned () const;
3873  inline bool canSMPAssign() const;
3874 
3875  inline IntrinsicType load ( size_t i, size_t j ) const;
3876  inline IntrinsicType loada( size_t i, size_t j ) const;
3877  inline IntrinsicType loadu( size_t i, size_t j ) const;
3878 
3879  inline void store ( size_t i, size_t j, const IntrinsicType& value );
3880  inline void storea( size_t i, size_t j, const IntrinsicType& value );
3881  inline void storeu( size_t i, size_t j, const IntrinsicType& value );
3882  inline void stream( size_t i, size_t j, const IntrinsicType& value );
3883 
3884  template< typename MT2 >
3885  inline typename DisableIf< VectorizedAssign<MT2> >::Type
3886  assign( const DenseMatrix<MT2,true>& rhs );
3887 
3888  template< typename MT2 >
3889  inline typename EnableIf< VectorizedAssign<MT2> >::Type
3890  assign( const DenseMatrix<MT2,true>& rhs );
3891 
3892  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3893  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3894  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3895 
3896  template< typename MT2 >
3897  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
3898  addAssign( const DenseMatrix<MT2,true>& rhs );
3899 
3900  template< typename MT2 >
3901  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
3902  addAssign( const DenseMatrix<MT2,true>& rhs );
3903 
3904  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3905  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3906  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3907 
3908  template< typename MT2 >
3909  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
3910  subAssign( const DenseMatrix<MT2,true>& rhs );
3911 
3912  template< typename MT2 >
3913  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
3914  subAssign( const DenseMatrix<MT2,true>& rhs );
3915 
3916  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3917  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3918  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3920  //**********************************************************************************************
3921 
3922  private:
3923  //**Utility functions***************************************************************************
3926  inline bool hasOverlap() const;
3928  //**********************************************************************************************
3929 
3930  //**Member variables****************************************************************************
3933  Operand matrix_;
3934  const size_t row_;
3935  const size_t column_;
3936  const size_t m_;
3937  const size_t n_;
3938  const bool isAligned_;
3939 
3946  //**********************************************************************************************
3947 
3948  //**Friend declarations*************************************************************************
3949  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
3950 
3951  template< bool AF1, typename MT2, bool AF2, bool SO2 >
3952  friend const DenseSubmatrix<MT2,AF1,SO2>
3953  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
3954 
3955  template< typename MT2, bool AF2, bool SO2 >
3956  friend bool isIntact( const DenseSubmatrix<MT2,AF2,SO2>& dm );
3957 
3958  template< typename MT2, bool AF2, bool SO2 >
3959  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
3960 
3961  template< typename MT2, bool AF2, bool SO2 >
3962  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
3963 
3964  template< typename MT2, bool AF2, bool SO2 >
3965  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
3966 
3967  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
3968  friend bool tryAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3969  size_t row, size_t column );
3970 
3971  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
3972  friend bool tryAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
3973  size_t row, size_t column );
3974 
3975  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
3976  friend bool tryAddAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3977  size_t row, size_t column );
3978 
3979  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
3980  friend bool tryAddAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
3981  size_t row, size_t column );
3982 
3983  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
3984  friend bool trySubAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3985  size_t row, size_t column );
3986 
3987  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
3988  friend bool trySubAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
3989  size_t row, size_t column );
3990 
3991  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
3992  friend bool tryMultAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
3993  size_t row, size_t column );
3994 
3995  template< typename MT2, bool AF2, bool SO2 >
3996  friend typename DerestrictTrait< DenseSubmatrix<MT2,AF2,SO2> >::Type
3997  derestrict( DenseSubmatrix<MT2,AF2,SO2>& dm );
3998  //**********************************************************************************************
3999 
4000  //**Compile time checks*************************************************************************
4008  //**********************************************************************************************
4009 };
4011 //*************************************************************************************************
4012 
4013 
4014 
4015 
4016 //=================================================================================================
4017 //
4018 // CONSTRUCTOR
4019 //
4020 //=================================================================================================
4021 
4022 //*************************************************************************************************
4036 template< typename MT > // Type of the dense matrix
4037 inline DenseSubmatrix<MT,unaligned,true>::DenseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
4038  : matrix_ ( matrix ) // The dense matrix containing the submatrix
4039  , row_ ( rindex ) // The first row of the submatrix
4040  , column_ ( cindex ) // The first column of the submatrix
4041  , m_ ( m ) // The number of rows of the submatrix
4042  , n_ ( n ) // The number of columns of the submatrix
4043  , isAligned_( vectorizable && matrix.data() != NULL && checkAlignment( data() ) &&
4044  ( n < 2UL || ( matrix.spacing() & size_t(-IT::size) ) == 0UL ) )
4045 {
4046  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
4047  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
4048  }
4049 }
4051 //*************************************************************************************************
4052 
4053 
4054 
4055 
4056 //=================================================================================================
4057 //
4058 // DATA ACCESS FUNCTIONS
4059 //
4060 //=================================================================================================
4061 
4062 //*************************************************************************************************
4073 template< typename MT > // Type of the dense matrix
4075  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j )
4076 {
4077  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4078  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4079 
4080  return matrix_(row_+i,column_+j);
4081 }
4083 //*************************************************************************************************
4084 
4085 
4086 //*************************************************************************************************
4097 template< typename MT > // Type of the dense matrix
4099  DenseSubmatrix<MT,unaligned,true>::operator()( size_t i, size_t j ) const
4100 {
4101  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
4102  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4103 
4104  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
4105 }
4107 //*************************************************************************************************
4108 
4109 
4110 //*************************************************************************************************
4122 template< typename MT > // Type of the dense matrix
4124  DenseSubmatrix<MT,unaligned,true>::at( size_t i, size_t j )
4125 {
4126  if( i >= rows() ) {
4127  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4128  }
4129  if( j >= columns() ) {
4130  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4131  }
4132  return (*this)(i,j);
4133 }
4135 //*************************************************************************************************
4136 
4137 
4138 //*************************************************************************************************
4150 template< typename MT > // Type of the dense matrix
4152  DenseSubmatrix<MT,unaligned,true>::at( size_t i, size_t j ) const
4153 {
4154  if( i >= rows() ) {
4155  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4156  }
4157  if( j >= columns() ) {
4158  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4159  }
4160  return (*this)(i,j);
4161 }
4163 //*************************************************************************************************
4164 
4165 
4166 //*************************************************************************************************
4176 template< typename MT > // Type of the dense matrix
4177 inline typename DenseSubmatrix<MT,unaligned,true>::Pointer
4179 {
4180  return matrix_.data() + row_ + column_*spacing();
4181 }
4183 //*************************************************************************************************
4184 
4185 
4186 //*************************************************************************************************
4196 template< typename MT > // Type of the dense matrix
4197 inline typename DenseSubmatrix<MT,unaligned,true>::ConstPointer
4199 {
4200  return matrix_.data() + row_ + column_*spacing();
4201 }
4203 //*************************************************************************************************
4204 
4205 
4206 //*************************************************************************************************
4215 template< typename MT > // Type of the dense matrix
4216 inline typename DenseSubmatrix<MT,unaligned,true>::Pointer
4218 {
4219  return matrix_.data() + row_ + (column_+j)*spacing();
4220 }
4222 //*************************************************************************************************
4223 
4224 
4225 //*************************************************************************************************
4234 template< typename MT > // Type of the dense matrix
4235 inline typename DenseSubmatrix<MT,unaligned,true>::ConstPointer
4236  DenseSubmatrix<MT,unaligned,true>::data( size_t j ) const
4237 {
4238  return matrix_.data() + row_ + (column_+j)*spacing();
4239 }
4241 //*************************************************************************************************
4242 
4243 
4244 //*************************************************************************************************
4251 template< typename MT > // Type of the dense matrix
4254 {
4255  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4256  return Iterator( matrix_.begin( column_ + j ) + row_, isAligned_ );
4257 }
4259 //*************************************************************************************************
4260 
4261 
4262 //*************************************************************************************************
4269 template< typename MT > // Type of the dense matrix
4272 {
4273  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4274  return ConstIterator( matrix_.cbegin( column_ + j ) + row_, isAligned_ );
4275 }
4277 //*************************************************************************************************
4278 
4279 
4280 //*************************************************************************************************
4287 template< typename MT > // Type of the dense matrix
4290 {
4291  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4292  return ConstIterator( matrix_.cbegin( column_ + j ) + row_, isAligned_ );
4293 }
4295 //*************************************************************************************************
4296 
4297 
4298 //*************************************************************************************************
4305 template< typename MT > // Type of the dense matrix
4308 {
4309  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4310  return Iterator( matrix_.begin( column_ + j ) + row_ + m_, isAligned_ );
4311 }
4313 //*************************************************************************************************
4314 
4315 
4316 //*************************************************************************************************
4323 template< typename MT > // Type of the dense matrix
4325  DenseSubmatrix<MT,unaligned,true>::end( size_t j ) const
4326 {
4327  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4328  return ConstIterator( matrix_.cbegin( column_ + j ) + row_ + m_, isAligned_ );
4329 }
4331 //*************************************************************************************************
4332 
4333 
4334 //*************************************************************************************************
4341 template< typename MT > // Type of the dense matrix
4343  DenseSubmatrix<MT,unaligned,true>::cend( size_t j ) const
4344 {
4345  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
4346  return ConstIterator( matrix_.cbegin( column_ + j ) + row_ + m_, isAligned_ );
4347 }
4349 //*************************************************************************************************
4350 
4351 
4352 
4353 
4354 //=================================================================================================
4355 //
4356 // ASSIGNMENT OPERATORS
4357 //
4358 //=================================================================================================
4359 
4360 //*************************************************************************************************
4371 template< typename MT > // Type of the dense matrix
4372 inline DenseSubmatrix<MT,unaligned,true>&
4373  DenseSubmatrix<MT,unaligned,true>::operator=( const ElementType& rhs )
4374 {
4375  const size_t jend( column_ + n_ );
4376 
4377  for( size_t j=column_; j<jend; ++j )
4378  {
4379  const size_t ibegin( ( IsLower<MT>::value )
4380  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4381  ?( max( j+1UL, row_ ) )
4382  :( max( j, row_ ) ) )
4383  :( row_ ) );
4384  const size_t iend ( ( IsUpper<MT>::value )
4385  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4386  ?( min( j, row_+m_ ) )
4387  :( min( j+1UL, row_+m_ ) ) )
4388  :( row_+m_ ) );
4389 
4390  for( size_t i=ibegin; i<iend; ++i )
4391  matrix_(i,j) = rhs;
4392  }
4393 
4394  return *this;
4395 }
4397 //*************************************************************************************************
4398 
4399 
4400 //*************************************************************************************************
4415 template< typename MT > // Type of the dense matrix
4416 inline DenseSubmatrix<MT,unaligned,true>&
4417  DenseSubmatrix<MT,unaligned,true>::operator=( const DenseSubmatrix& rhs )
4418 {
4421 
4422  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
4423  return *this;
4424 
4425  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
4426  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
4427  }
4428 
4429  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
4430  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4431  }
4432 
4433  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4434 
4435  if( rhs.canAlias( &matrix_ ) ) {
4436  const ResultType tmp( rhs );
4437  smpAssign( left, tmp );
4438  }
4439  else {
4440  smpAssign( left, rhs );
4441  }
4442 
4443  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4444 
4445  return *this;
4446 }
4448 //*************************************************************************************************
4449 
4450 
4451 //*************************************************************************************************
4466 template< typename MT > // Type of the dense matrix
4467 template< typename MT2 // Type of the right-hand side matrix
4468  , bool SO > // Storage order of the right-hand side matrix
4469 inline DenseSubmatrix<MT,unaligned,true>&
4470  DenseSubmatrix<MT,unaligned,true>::operator=( const Matrix<MT2,SO>& rhs )
4471 {
4473 
4474  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4475  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4476  }
4477 
4478  typedef typename If< IsRestricted<MT>, typename MT2::CompositeType, const MT2& >::Type Right;
4479  Right right( ~rhs );
4480 
4481  if( !tryAssign( matrix_, right, row_, column_ ) ) {
4482  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4483  }
4484 
4485  if( IsSparseMatrix<MT2>::value )
4486  reset();
4487 
4488  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4489 
4490  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4491  const typename MT2::ResultType tmp( right );
4492  smpAssign( left, tmp );
4493  }
4494  else {
4495  smpAssign( left, right );
4496  }
4497 
4498  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4499 
4500  return *this;
4501 }
4503 //*************************************************************************************************
4504 
4505 
4506 //*************************************************************************************************
4520 template< typename MT > // Type of the dense matrix
4521 template< typename MT2 // Type of the right-hand side matrix
4522  , bool SO > // Storage order of the right-hand side matrix
4523 inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
4524  , DenseSubmatrix<MT,unaligned,true>& >::Type
4525  DenseSubmatrix<MT,unaligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
4526 {
4530 
4531  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4532 
4535 
4536  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4537  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4538  }
4539 
4540  if( !tryAddAssign( matrix_, ~rhs, row_, column_ ) ) {
4541  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4542  }
4543 
4544  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4545 
4546  if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
4547  (~rhs).canAlias( &matrix_ ) ) {
4548  const AddType tmp( *this + (~rhs) );
4549  smpAssign( left, tmp );
4550  }
4551  else {
4552  smpAddAssign( left, ~rhs );
4553  }
4554 
4555  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4556 
4557  return *this;
4558 }
4560 //*************************************************************************************************
4561 
4562 
4563 //*************************************************************************************************
4577 template< typename MT > // Type of the dense matrix
4578 template< typename MT2 // Type of the right-hand side matrix
4579  , bool SO > // Storage order of the right-hand side matrix
4580 inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
4581  , DenseSubmatrix<MT,unaligned,true>& >::Type
4582  DenseSubmatrix<MT,unaligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
4583 {
4587 
4588  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
4589 
4592 
4593  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4594  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4595  }
4596 
4597  const AddType tmp( *this + (~rhs) );
4598 
4599  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
4600  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4601  }
4602 
4603  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4604 
4605  smpAssign( left, tmp );
4606 
4607  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4608 
4609  return *this;
4610 }
4612 //*************************************************************************************************
4613 
4614 
4615 //*************************************************************************************************
4629 template< typename MT > // Type of the dense matrix
4630 template< typename MT2 // Type of the right-hand side matrix
4631  , bool SO > // Storage order of the right-hand side matrix
4632 inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
4633  , DenseSubmatrix<MT,unaligned,true>& >::Type
4634  DenseSubmatrix<MT,unaligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
4635 {
4639 
4640  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4641 
4644 
4645  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4646  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4647  }
4648 
4649  if( !trySubAssign( matrix_, ~rhs, row_, column_ ) ) {
4650  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4651  }
4652 
4653  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4654 
4655  if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
4656  (~rhs).canAlias( &matrix_ ) ) {
4657  const SubType tmp( *this - (~rhs ) );
4658  smpAssign( left, tmp );
4659  }
4660  else {
4661  smpSubAssign( left, ~rhs );
4662  }
4663 
4664  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4665 
4666  return *this;
4667 }
4669 //*************************************************************************************************
4670 
4671 
4672 //*************************************************************************************************
4686 template< typename MT > // Type of the dense matrix
4687 template< typename MT2 // Type of the right-hand side matrix
4688  , bool SO > // Storage order of the right-hand side matrix
4689 inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
4690  , DenseSubmatrix<MT,unaligned,true>& >::Type
4691  DenseSubmatrix<MT,unaligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
4692 {
4696 
4697  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
4698 
4701 
4702  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4703  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4704  }
4705 
4706  const SubType tmp( *this - (~rhs) );
4707 
4708  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
4709  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4710  }
4711 
4712  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4713 
4714  smpAssign( left, tmp );
4715 
4716  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4717 
4718  return *this;
4719 }
4721 //*************************************************************************************************
4722 
4723 
4724 //*************************************************************************************************
4738 template< typename MT > // Type of the dense matrix
4739 template< typename MT2 // Type of the right-hand side matrix
4740  , bool SO > // Storage order of the right-hand side matrix
4741 inline DenseSubmatrix<MT,unaligned,true>&
4742  DenseSubmatrix<MT,unaligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
4743 {
4747 
4748  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
4749 
4752 
4753  if( columns() != (~rhs).rows() ) {
4754  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4755  }
4756 
4757  const MultType tmp( *this * (~rhs) );
4758 
4759  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
4760  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4761  }
4762 
4763  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4764 
4765  smpAssign( left, tmp );
4766 
4767  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4768 
4769  return *this;
4770 }
4772 //*************************************************************************************************
4773 
4774 
4775 //*************************************************************************************************
4786 template< typename MT > // Type of the dense matrix
4787 template< typename Other > // Data type of the right-hand side scalar
4788 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
4789  DenseSubmatrix<MT,unaligned,true>::operator*=( Other rhs )
4790 {
4792 
4793  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4794  smpAssign( left, (*this) * rhs );
4795 
4796  return *this;
4797 }
4799 //*************************************************************************************************
4800 
4801 
4802 //*************************************************************************************************
4815 template< typename MT > // Type of the dense matrix
4816 template< typename Other > // Data type of the right-hand side scalar
4817 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,unaligned,true> >::Type&
4818  DenseSubmatrix<MT,unaligned,true>::operator/=( Other rhs )
4819 {
4821 
4822  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4823 
4824  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4825  smpAssign( left, (*this) / rhs );
4826 
4827  return *this;
4828 }
4830 //*************************************************************************************************
4831 
4832 
4833 
4834 
4835 //=================================================================================================
4836 //
4837 // UTILITY FUNCTIONS
4838 //
4839 //=================================================================================================
4840 
4841 //*************************************************************************************************
4847 template< typename MT > // Type of the dense matrix
4848 inline size_t DenseSubmatrix<MT,unaligned,true>::row() const
4849 {
4850  return row_;
4851 }
4853 //*************************************************************************************************
4854 
4855 
4856 //*************************************************************************************************
4862 template< typename MT > // Type of the dense matrix
4863 inline size_t DenseSubmatrix<MT,unaligned,true>::rows() const
4864 {
4865  return m_;
4866 }
4868 //*************************************************************************************************
4869 
4870 
4871 //*************************************************************************************************
4877 template< typename MT > // Type of the dense matrix
4878 inline size_t DenseSubmatrix<MT,unaligned,true>::column() const
4879 {
4880  return column_;
4881 }
4883 //*************************************************************************************************
4884 
4885 
4886 //*************************************************************************************************
4892 template< typename MT > // Type of the dense matrix
4893 inline size_t DenseSubmatrix<MT,unaligned,true>::columns() const
4894 {
4895  return n_;
4896 }
4898 //*************************************************************************************************
4899 
4900 
4901 //*************************************************************************************************
4910 template< typename MT > // Type of the dense matrix
4911 inline size_t DenseSubmatrix<MT,unaligned,true>::spacing() const
4912 {
4913  return matrix_.spacing();
4914 }
4916 //*************************************************************************************************
4917 
4918 
4919 //*************************************************************************************************
4925 template< typename MT > // Type of the dense matrix
4926 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity() const
4927 {
4928  return rows() * columns();
4929 }
4931 //*************************************************************************************************
4932 
4933 
4934 //*************************************************************************************************
4941 template< typename MT > // Type of the dense matrix
4942 inline size_t DenseSubmatrix<MT,unaligned,true>::capacity( size_t j ) const
4943 {
4944  UNUSED_PARAMETER( j );
4945 
4946  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4947 
4948  return rows();
4949 }
4951 //*************************************************************************************************
4952 
4953 
4954 //*************************************************************************************************
4960 template< typename MT > // Type of the dense matrix
4961 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros() const
4962 {
4963  const size_t iend( row_ + m_ );
4964  const size_t jend( column_ + n_ );
4965  size_t nonzeros( 0UL );
4966 
4967  for( size_t j=column_; j<jend; ++j )
4968  for( size_t i=row_; i<iend; ++i )
4969  if( !isDefault( matrix_(i,j) ) )
4970  ++nonzeros;
4971 
4972  return nonzeros;
4973 }
4975 //*************************************************************************************************
4976 
4977 
4978 //*************************************************************************************************
4985 template< typename MT > // Type of the dense matrix
4986 inline size_t DenseSubmatrix<MT,unaligned,true>::nonZeros( size_t j ) const
4987 {
4988  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4989 
4990  const size_t iend( row_ + m_ );
4991  size_t nonzeros( 0UL );
4992 
4993  for( size_t i=row_; i<iend; ++i )
4994  if( !isDefault( matrix_(i,column_+j) ) )
4995  ++nonzeros;
4996 
4997  return nonzeros;
4998 }
5000 //*************************************************************************************************
5001 
5002 
5003 //*************************************************************************************************
5009 template< typename MT > // Type of the dense matrix
5011 {
5012  using blaze::clear;
5013 
5014  for( size_t j=column_; j<column_+n_; ++j )
5015  {
5016  const size_t ibegin( ( IsLower<MT>::value )
5017  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
5018  ?( max( j+1UL, row_ ) )
5019  :( max( j, row_ ) ) )
5020  :( row_ ) );
5021  const size_t iend ( ( IsUpper<MT>::value )
5022  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
5023  ?( min( j, row_+m_ ) )
5024  :( min( j+1UL, row_+m_ ) ) )
5025  :( row_+m_ ) );
5026 
5027  for( size_t i=ibegin; i<iend; ++i )
5028  clear( matrix_(i,j) );
5029  }
5030 }
5032 //*************************************************************************************************
5033 
5034 
5035 //*************************************************************************************************
5042 template< typename MT > // Type of the dense matrix
5043 inline void DenseSubmatrix<MT,unaligned,true>::reset( size_t j )
5044 {
5045  using blaze::clear;
5046 
5047  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5048 
5049  const size_t ibegin( ( IsLower<MT>::value )
5050  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
5051  ?( max( j+1UL, row_ ) )
5052  :( max( j, row_ ) ) )
5053  :( row_ ) );
5054  const size_t iend ( ( IsUpper<MT>::value )
5055  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
5056  ?( min( j, row_+m_ ) )
5057  :( min( j+1UL, row_+m_ ) ) )
5058  :( row_+m_ ) );
5059 
5060  for( size_t i=ibegin; i<iend; ++i )
5061  clear( matrix_(i,column_+j) );
5062 }
5064 //*************************************************************************************************
5065 
5066 
5067 //*************************************************************************************************
5085 template< typename MT > // Type of the dense matrix
5086 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::transpose()
5087 {
5088  if( m_ != n_ ) {
5089  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
5090  }
5091 
5092  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
5093  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
5094  }
5095 
5096  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5097  const ResultType tmp( trans( *this ) );
5098  smpAssign( left, tmp );
5099 
5100  return *this;
5101 }
5103 //*************************************************************************************************
5104 
5105 
5106 //*************************************************************************************************
5124 template< typename MT > // Type of the dense matrix
5125 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::ctranspose()
5126 {
5127  if( m_ != n_ ) {
5128  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
5129  }
5130 
5131  if( !tryAssign( matrix_, ctrans( *this ), row_, column_ ) ) {
5132  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
5133  }
5134 
5135  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5136  const ResultType tmp( ctrans( *this ) );
5137  smpAssign( left, tmp );
5138 
5139  return *this;
5140 }
5142 //*************************************************************************************************
5143 
5144 
5145 //*************************************************************************************************
5156 template< typename MT > // Type of the dense matrix
5157 template< typename Other > // Data type of the scalar value
5158 inline DenseSubmatrix<MT,unaligned,true>& DenseSubmatrix<MT,unaligned,true>::scale( const Other& scalar )
5159 {
5161 
5162  const size_t jend( column_ + n_ );
5163 
5164  for( size_t j=column_; j<jend; ++j )
5165  {
5166  const size_t ibegin( ( IsLower<MT>::value )
5167  ?( ( IsStrictlyLower<MT>::value )
5168  ?( max( j+1UL, row_ ) )
5169  :( max( j, row_ ) ) )
5170  :( row_ ) );
5171  const size_t iend ( ( IsUpper<MT>::value )
5172  ?( ( IsStrictlyUpper<MT>::value )
5173  ?( min( j, row_+m_ ) )
5174  :( min( j+1UL, row_+m_ ) ) )
5175  :( row_+m_ ) );
5176 
5177  for( size_t i=ibegin; i<iend; ++i )
5178  matrix_(i,j) *= scalar;
5179  }
5180 
5181  return *this;
5182 }
5184 //*************************************************************************************************
5185 
5186 
5187 //*************************************************************************************************
5197 template< typename MT > // Type of the dense matrix
5199 {
5200  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
5201 
5202  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
5203  return false;
5204  else return true;
5205 }
5207 //*************************************************************************************************
5208 
5209 
5210 
5211 
5212 //=================================================================================================
5213 //
5214 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5215 //
5216 //=================================================================================================
5217 
5218 //*************************************************************************************************
5229 template< typename MT > // Type of the dense matrix
5230 template< typename Other > // Data type of the foreign expression
5231 inline bool DenseSubmatrix<MT,unaligned,true>::canAlias( const Other* alias ) const
5232 {
5233  return matrix_.isAliased( alias );
5234 }
5236 //*************************************************************************************************
5237 
5238 
5239 //*************************************************************************************************
5250 template< typename MT > // Type of the dense matrix
5251 template< typename MT2 // Data type of the foreign dense submatrix
5252  , bool AF2 // Alignment flag of the foreign dense submatrix
5253  , bool SO2 > // Storage order of the foreign dense submatrix
5254 inline bool DenseSubmatrix<MT,unaligned,true>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
5255 {
5256  return ( matrix_.isAliased( &alias->matrix_ ) &&
5257  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
5258  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
5259 }
5261 //*************************************************************************************************
5262 
5263 
5264 //*************************************************************************************************
5275 template< typename MT > // Type of the dense matrix
5276 template< typename Other > // Data type of the foreign expression
5277 inline bool DenseSubmatrix<MT,unaligned,true>::isAliased( const Other* alias ) const
5278 {
5279  return matrix_.isAliased( alias );
5280 }
5282 //*************************************************************************************************
5283 
5284 
5285 //*************************************************************************************************
5296 template< typename MT > // Type of the dense matrix
5297 template< typename MT2 // Data type of the foreign dense submatrix
5298  , bool AF2 // Alignment flag of the foreign dense submatrix
5299  , bool SO2 > // Storage order of the foreign dense submatrix
5300 inline bool DenseSubmatrix<MT,unaligned,true>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
5301 {
5302  return ( matrix_.isAliased( &alias->matrix_ ) &&
5303  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
5304  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
5305 }
5307 //*************************************************************************************************
5308 
5309 
5310 //*************************************************************************************************
5320 template< typename MT > // Type of the dense matrix
5322 {
5323  return isAligned_;
5324 }
5326 //*************************************************************************************************
5327 
5328 
5329 //*************************************************************************************************
5340 template< typename MT > // Type of the dense matrix
5342 {
5343  return ( columns() > SMP_DMATASSIGN_THRESHOLD );
5344 }
5346 //*************************************************************************************************
5347 
5348 
5349 //*************************************************************************************************
5364 template< typename MT > // Type of the dense matrix
5365 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
5366  DenseSubmatrix<MT,unaligned,true>::load( size_t i, size_t j ) const
5367 {
5368  if( isAligned_ )
5369  return loada( i, j );
5370  else
5371  return loadu( i, j );
5372 }
5374 //*************************************************************************************************
5375 
5376 
5377 //*************************************************************************************************
5393 template< typename MT > // Type of the dense matrix
5394 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
5395  DenseSubmatrix<MT,unaligned,true>::loada( size_t i, size_t j ) const
5396 {
5398 
5399  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
5400  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
5401  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
5402  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
5403 
5404  return matrix_.loada( row_+i, column_+j );
5405 }
5407 //*************************************************************************************************
5408 
5409 
5410 //*************************************************************************************************
5426 template< typename MT > // Type of the dense matrix
5427 inline typename DenseSubmatrix<MT,unaligned,true>::IntrinsicType
5428  DenseSubmatrix<MT,unaligned,true>::loadu( size_t i, size_t j ) const
5429 {
5431 
5432  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
5433  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
5434  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
5435  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
5436 
5437  return matrix_.loadu( row_+i, column_+j );
5438 }
5440 //*************************************************************************************************
5441 
5442 
5443 //*************************************************************************************************
5459 template< typename MT > // Type of the dense matrix
5460 inline void DenseSubmatrix<MT,unaligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
5461 {
5462  if( isAligned_ )
5463  storea( i, j, value );
5464  else
5465  storeu( i, j, value );
5466 }
5468 //*************************************************************************************************
5469 
5470 
5471 //*************************************************************************************************
5487 template< typename MT > // Type of the dense matrix
5488 inline void DenseSubmatrix<MT,unaligned,true>::storea( size_t i, size_t j, const IntrinsicType& value )
5489 {
5491 
5492  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
5493  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
5494  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
5495  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
5496 
5497  matrix_.storea( row_+i, column_+j, value );
5498 }
5500 //*************************************************************************************************
5501 
5502 
5503 //*************************************************************************************************
5520 template< typename MT > // Type of the dense matrix
5521 inline void DenseSubmatrix<MT,unaligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
5522 {
5524 
5525  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
5526  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
5527  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
5528  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
5529 
5530  matrix_.storeu( row_+i, column_+j, value );
5531 }
5533 //*************************************************************************************************
5534 
5535 
5536 //*************************************************************************************************
5553 template< typename MT > // Type of the dense matrix
5554 inline void DenseSubmatrix<MT,unaligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
5555 {
5557 
5558  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
5559  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
5560  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
5561  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
5562 
5563  if( isAligned_ )
5564  matrix_.stream( row_+i, column_+j, value );
5565  else
5566  matrix_.storeu( row_+i, column_+j, value );
5567 }
5569 //*************************************************************************************************
5570 
5571 
5572 //*************************************************************************************************
5584 template< typename MT > // Type of the dense matrix
5585 template< typename MT2 > // Type of the right-hand side dense matrix
5586 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
5587  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
5588 {
5589  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5590  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5591 
5592  const size_t ipos( m_ & size_t(-2) );
5593  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5594 
5595  for( size_t j=0UL; j<n_; ++j ) {
5596  for( size_t i=0UL; i<ipos; i+=2UL ) {
5597  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
5598  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
5599  }
5600  if( ipos < m_ ) {
5601  matrix_(row_+ipos,column_+j) = (~rhs)(ipos,j);
5602  }
5603  }
5604 }
5606 //*************************************************************************************************
5607 
5608 
5609 //*************************************************************************************************
5621 template< typename MT > // Type of the dense matrix
5622 template< typename MT2 > // Type of the right-hand side dense matrix
5623 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
5624  DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
5625 {
5627 
5628  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5629  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5630 
5631  const size_t ipos( m_ & size_t(-IT::size) );
5632  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size) ) ) == ipos, "Invalid end calculation" );
5633 
5634  if( useStreaming && isAligned_ &&
5635  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
5636  !(~rhs).isAliased( &matrix_ ) )
5637  {
5638  for( size_t j=0UL; j<n_; ++j )
5639  {
5640  size_t i( 0UL );
5641 
5642  for( ; i<ipos; i+=IT::size ) {
5643  matrix_.stream( row_+i, column_+j, (~rhs).load(i,j) );
5644  }
5645  for( ; i<m_; ++i ) {
5646  matrix_(row_+i,column_+j) = (~rhs)(i,j);
5647  }
5648  }
5649  }
5650  else
5651  {
5652  for( size_t j=0UL; j<n_; ++j )
5653  {
5654  size_t i( 0UL );
5655  typename MT2::ConstIterator it( (~rhs).begin(j) );
5656 
5657  for( ; (i+IT::size*3UL) < ipos; i+=IT::size*4UL ) {
5658  store( i , j, it.load() ); it += IT::size;
5659  store( i+IT::size , j, it.load() ); it += IT::size;
5660  store( i+IT::size*2UL, j, it.load() ); it += IT::size;
5661  store( i+IT::size*3UL, j, it.load() ); it += IT::size;
5662  }
5663  for( ; i<ipos; i+=IT::size, it+=IT::size ) {
5664  store( i, j, it.load() );
5665  }
5666  for( ; i<m_; ++i, ++it ) {
5667  matrix_(row_+i,column_+j) = (~rhs)(i,j);
5668  }
5669  }
5670  }
5671 }
5673 //*************************************************************************************************
5674 
5675 
5676 //*************************************************************************************************
5688 template< typename MT > // Type of the dense matrix
5689 template< typename MT2 > // Type of the right-hand side dense matrix
5690 inline void DenseSubmatrix<MT,unaligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
5691 {
5693 
5694  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5695  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5696 
5697  const size_t block( BLOCK_SIZE );
5698 
5699  for( size_t jj=0UL; jj<n_; jj+=block ) {
5700  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
5701  for( size_t ii=0UL; ii<m_; ii+=block ) {
5702  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
5703  for( size_t j=jj; j<jend; ++j ) {
5704  for( size_t i=ii; i<iend; ++i ) {
5705  matrix_(row_+i,column_+j) = (~rhs)(i,j);
5706  }
5707  }
5708  }
5709  }
5710 }
5712 //*************************************************************************************************
5713 
5714 
5715 //*************************************************************************************************
5727 template< typename MT > // Type of the dense matrix
5728 template< typename MT2 > // Type of the right-hand side sparse matrix
5729 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
5730 {
5731  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5732  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5733 
5734  for( size_t j=0UL; j<n_; ++j )
5735  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5736  matrix_(row_+element->index(),column_+j) = element->value();
5737 }
5739 //*************************************************************************************************
5740 
5741 
5742 //*************************************************************************************************
5754 template< typename MT > // Type of the dense matrix
5755 template< typename MT2 > // Type of the right-hand side sparse matrix
5756 inline void DenseSubmatrix<MT,unaligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
5757 {
5759 
5760  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5761  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5762 
5763  for( size_t i=0UL; i<m_; ++i )
5764  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5765  matrix_(row_+i,column_+element->index()) = element->value();
5766 }
5768 //*************************************************************************************************
5769 
5770 
5771 //*************************************************************************************************
5783 template< typename MT > // Type of the dense matrix
5784 template< typename MT2 > // Type of the right-hand side dense matrix
5785 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
5786  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
5787 {
5788  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5789  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5790 
5791  const size_t ipos( m_ & size_t(-2) );
5792  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5793 
5794  for( size_t j=0UL; j<n_; ++j ) {
5795  for( size_t i=0UL; i<ipos; i+=2UL ) {
5796  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
5797  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
5798  }
5799  if( ipos < m_ ) {
5800  matrix_(row_+ipos,column_+j) += (~rhs)(ipos,j);
5801  }
5802  }
5803 }
5805 //*************************************************************************************************
5806 
5807 
5808 //*************************************************************************************************
5820 template< typename MT > // Type of the dense matrix
5821 template< typename MT2 > // Type of the right-hand side dense matrix
5822 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
5823  DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
5824 {
5826 
5827  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5828  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5829 
5830  for( size_t j=0UL; j<n_; ++j )
5831  {
5832  const size_t ibegin( ( IsLower<MT>::value )
5833  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
5834  :( 0UL ) );
5835  const size_t iend ( ( IsUpper<MT>::value )
5836  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5837  :( m_ ) );
5838  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5839 
5840  const size_t ipos( iend & size_t(-IT::size) );
5841  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (IT::size) ) ) == ipos, "Invalid end calculation" );
5842 
5843  size_t i( ibegin );
5844  typename MT2::ConstIterator it( (~rhs).begin(j) );
5845 
5846  for( ; (i+IT::size*3UL) < ipos; i+=IT::size*4UL ) {
5847  store( i , j, load(i ,j) + it.load() ); it += IT::size;
5848  store( i+IT::size , j, load(i+IT::size ,j) + it.load() ); it += IT::size;
5849  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
5850  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
5851  }
5852  for( ; i<ipos; i+=IT::size, it+=IT::size ) {
5853  store( i, j, load(i,j) + it.load() );
5854  }
5855  for( ; i<iend; ++i, ++it ) {
5856  matrix_(row_+i,column_+j) += *it;
5857  }
5858  }
5859 }
5861 //*************************************************************************************************
5862 
5863 
5864 //*************************************************************************************************
5876 template< typename MT > // Type of the dense matrix
5877 template< typename MT2 > // Type of the right-hand side dense matrix
5878 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
5879 {
5881 
5882  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5883  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5884 
5885  const size_t block( BLOCK_SIZE );
5886 
5887  for( size_t jj=0UL; jj<n_; jj+=block ) {
5888  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
5889  for( size_t ii=0UL; ii<m_; ii+=block ) {
5890  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
5891  for( size_t j=jj; j<jend; ++j ) {
5892  for( size_t i=ii; i<iend; ++i ) {
5893  matrix_(row_+i,column_+j) += (~rhs)(i,j);
5894  }
5895  }
5896  }
5897  }
5898 }
5900 //*************************************************************************************************
5901 
5902 
5903 //*************************************************************************************************
5915 template< typename MT > // Type of the dense matrix
5916 template< typename MT2 > // Type of the right-hand side sparse matrix
5917 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
5918 {
5919  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5920  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5921 
5922  for( size_t j=0UL; j<n_; ++j )
5923  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5924  matrix_(row_+element->index(),column_+j) += element->value();
5925 }
5927 //*************************************************************************************************
5928 
5929 
5930 //*************************************************************************************************
5942 template< typename MT > // Type of the dense matrix
5943 template< typename MT2 > // Type of the right-hand side sparse matrix
5944 inline void DenseSubmatrix<MT,unaligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
5945 {
5947 
5948  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5949  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5950 
5951  for( size_t i=0UL; i<m_; ++i )
5952  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5953  matrix_(row_+i,column_+element->index()) += element->value();
5954 }
5956 //*************************************************************************************************
5957 
5958 
5959 //*************************************************************************************************
5971 template< typename MT > // Type of the dense matrix
5972 template< typename MT2 > // Type of the right-hand side dense matrix
5973 inline typename DisableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
5974  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
5975 {
5976  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5977  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5978 
5979  const size_t ipos( m_ & size_t(-2) );
5980  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5981 
5982  for( size_t j=0UL; j<n_; ++j ) {
5983  for( size_t i=0UL; i<ipos; i+=2UL ) {
5984  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
5985  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
5986  }
5987  if( ipos < m_ ) {
5988  matrix_(row_+ipos,column_+j) -= (~rhs)(ipos,j);
5989  }
5990  }
5991 }
5993 //*************************************************************************************************
5994 
5995 
5996 //*************************************************************************************************
6008 template< typename MT > // Type of the dense matrix
6009 template< typename MT2 > // Type of the right-hand side dense matrix
6010 inline typename EnableIf< typename DenseSubmatrix<MT,unaligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
6011  DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
6012 {
6014 
6015  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6016  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6017 
6018  for( size_t j=0UL; j<n_; ++j )
6019  {
6020  const size_t ibegin( ( IsLower<MT>::value )
6021  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
6022  :( 0UL ) );
6023  const size_t iend ( ( IsUpper<MT>::value )
6024  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6025  :( m_ ) );
6026  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6027 
6028  const size_t ipos( iend & size_t(-IT::size) );
6029  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (IT::size) ) ) == ipos, "Invalid end calculation" );
6030 
6031  size_t i( ibegin );
6032  typename MT2::ConstIterator it( (~rhs).begin(j) );
6033 
6034  for( ; (i+IT::size*3UL) < ipos; i+=IT::size*4UL ) {
6035  store( i , j, load(i ,j) - it.load() ); it += IT::size;
6036  store( i+IT::size , j, load(i+IT::size ,j) - it.load() ); it += IT::size;
6037  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
6038  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
6039  }
6040  for( ; i<ipos; i+=IT::size, it+=IT::size ) {
6041  store( i, j, load(i,j) - it.load() );
6042  }
6043  for( ; i<iend; ++i, ++it ) {
6044  matrix_(row_+i,column_+j) -= *it;
6045  }
6046  }
6047 }
6049 //*************************************************************************************************
6050 
6051 
6052 //*************************************************************************************************
6064 template< typename MT > // Type of the dense matrix
6065 template< typename MT2 > // Type of the right-hand side dense matrix
6066 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
6067 {
6069 
6070  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6071  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6072 
6073  const size_t block( BLOCK_SIZE );
6074 
6075  for( size_t jj=0UL; jj<n_; jj+=block ) {
6076  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
6077  for( size_t ii=0UL; ii<m_; ii+=block ) {
6078  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
6079  for( size_t j=jj; j<jend; ++j ) {
6080  for( size_t i=ii; i<iend; ++i ) {
6081  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
6082  }
6083  }
6084  }
6085  }
6086 }
6088 //*************************************************************************************************
6089 
6090 
6091 //*************************************************************************************************
6103 template< typename MT > // Type of the dense matrix
6104 template< typename MT2 > // Type of the right-hand side sparse matrix
6105 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
6106 {
6107  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6108  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6109 
6110  for( size_t j=0UL; j<n_; ++j )
6111  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6112  matrix_(row_+element->index(),column_+j) -= element->value();
6113 }
6115 //*************************************************************************************************
6116 
6117 
6118 //*************************************************************************************************
6130 template< typename MT > // Type of the dense matrix
6131 template< typename MT2 > // Type of the right-hand side sparse matrix
6132 inline void DenseSubmatrix<MT,unaligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
6133 {
6135 
6136  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6137  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6138 
6139  for( size_t i=0UL; i<m_; ++i )
6140  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6141  matrix_(row_+i,column_+element->index()) -= element->value();
6142 }
6144 //*************************************************************************************************
6145 
6146 
6147 
6148 
6149 
6150 
6151 
6152 
6153 //=================================================================================================
6154 //
6155 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED ROW-MAJOR SUBMATRICES
6156 //
6157 //=================================================================================================
6158 
6159 //*************************************************************************************************
6167 template< typename MT > // Type of the dense matrix
6168 class DenseSubmatrix<MT,aligned,false> : public DenseMatrix< DenseSubmatrix<MT,aligned,false>, false >
6169  , private Submatrix
6170 {
6171  private:
6172  //**Type definitions****************************************************************************
6174  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
6175 
6177  typedef IntrinsicTrait<typename MT::ElementType> IT;
6178  //**********************************************************************************************
6179 
6180  public:
6181  //**Type definitions****************************************************************************
6182  typedef DenseSubmatrix<MT,aligned,false> This;
6183  typedef typename SubmatrixTrait<MT>::Type ResultType;
6184  typedef typename ResultType::OppositeType OppositeType;
6185  typedef typename ResultType::TransposeType TransposeType;
6186  typedef typename MT::ElementType ElementType;
6187  typedef typename IT::Type IntrinsicType;
6188  typedef typename MT::ReturnType ReturnType;
6189  typedef const DenseSubmatrix& CompositeType;
6190 
6192  typedef typename MT::ConstReference ConstReference;
6193 
6195  typedef typename If< IsConst<MT>, ConstReference, typename MT::Reference >::Type Reference;
6196 
6198  typedef const ElementType* ConstPointer;
6199 
6201  typedef typename If< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >
6202  , ConstPointer, ElementType* >::Type Pointer;
6203 
6205  typedef typename MT::ConstIterator ConstIterator;
6206 
6208  typedef typename If< IsConst<MT>, ConstIterator, typename MT::Iterator >::Type Iterator;
6209  //**********************************************************************************************
6210 
6211  //**Compilation flags***************************************************************************
6213  enum { vectorizable = MT::vectorizable };
6214 
6216  enum { smpAssignable = MT::smpAssignable };
6217  //**********************************************************************************************
6218 
6219  //**Constructors********************************************************************************
6222  explicit inline DenseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
6223  // No explicitly declared copy constructor.
6225  //**********************************************************************************************
6226 
6227  //**Destructor**********************************************************************************
6228  // No explicitly declared destructor.
6229  //**********************************************************************************************
6230 
6231  //**Data access functions***********************************************************************
6234  inline Reference operator()( size_t i, size_t j );
6235  inline ConstReference operator()( size_t i, size_t j ) const;
6236  inline Reference at( size_t i, size_t j );
6237  inline ConstReference at( size_t i, size_t j ) const;
6238  inline Pointer data ();
6239  inline ConstPointer data () const;
6240  inline Pointer data ( size_t i );
6241  inline ConstPointer data ( size_t i ) const;
6242  inline Iterator begin ( size_t i );
6243  inline ConstIterator begin ( size_t i ) const;
6244  inline ConstIterator cbegin( size_t i ) const;
6245  inline Iterator end ( size_t i );
6246  inline ConstIterator end ( size_t i ) const;
6247  inline ConstIterator cend ( size_t i ) const;
6249  //**********************************************************************************************
6250 
6251  //**Assignment operators************************************************************************
6254  inline DenseSubmatrix& operator=( const ElementType& rhs );
6255  inline DenseSubmatrix& operator=( const DenseSubmatrix& rhs );
6256 
6257  template< typename MT2, bool SO >
6258  inline DenseSubmatrix& operator=( const Matrix<MT2,SO>& rhs );
6259 
6260  template< typename MT2, bool SO >
6261  inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
6262  operator+=( const Matrix<MT2,SO>& rhs );
6263 
6264  template< typename MT2, bool SO >
6265  inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
6266  operator+=( const Matrix<MT2,SO>& rhs );
6267 
6268  template< typename MT2, bool SO >
6269  inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
6270  operator-=( const Matrix<MT2,SO>& rhs );
6271 
6272  template< typename MT2, bool SO >
6273  inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
6274  operator-=( const Matrix<MT2,SO>& rhs );
6275 
6276  template< typename MT2, bool SO >
6277  inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
6278 
6279  template< typename Other >
6280  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
6281  operator*=( Other rhs );
6282 
6283  template< typename Other >
6284  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
6285  operator/=( Other rhs );
6287  //**********************************************************************************************
6288 
6289  //**Utility functions***************************************************************************
6292  inline size_t row() const;
6293  inline size_t rows() const;
6294  inline size_t column() const;
6295  inline size_t columns() const;
6296  inline size_t spacing() const;
6297  inline size_t capacity() const;
6298  inline size_t capacity( size_t i ) const;
6299  inline size_t nonZeros() const;
6300  inline size_t nonZeros( size_t i ) const;
6301  inline void reset();
6302  inline void reset( size_t i );
6303  inline DenseSubmatrix& transpose();
6304  inline DenseSubmatrix& ctranspose();
6305  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
6307  //**********************************************************************************************
6308 
6309  private:
6310  //**********************************************************************************************
6312  template< typename MT2 >
6313  struct VectorizedAssign {
6314  enum { value = useOptimizedKernels &&
6315  vectorizable && MT2::vectorizable &&
6316  IsSame<ElementType,typename MT2::ElementType>::value };
6317  };
6318  //**********************************************************************************************
6319 
6320  //**********************************************************************************************
6322  template< typename MT2 >
6323  struct VectorizedAddAssign {
6324  enum { value = useOptimizedKernels &&
6325  vectorizable && MT2::vectorizable &&
6326  IsSame<ElementType,typename MT2::ElementType>::value &&
6327  IntrinsicTrait<ElementType>::addition };
6328  };
6329  //**********************************************************************************************
6330 
6331  //**********************************************************************************************
6333  template< typename MT2 >
6334  struct VectorizedSubAssign {
6335  enum { value = useOptimizedKernels &&
6336  vectorizable && MT2::vectorizable &&
6337  IsSame<ElementType,typename MT2::ElementType>::value &&
6338  IntrinsicTrait<ElementType>::subtraction };
6339  };
6340  //**********************************************************************************************
6341 
6342  public:
6343  //**Expression template evaluation functions****************************************************
6346  template< typename Other >
6347  inline bool canAlias( const Other* alias ) const;
6348 
6349  template< typename MT2, bool AF2, bool SO2 >
6350  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
6351 
6352  template< typename Other >
6353  inline bool isAliased( const Other* alias ) const;
6354 
6355  template< typename MT2, bool AF2, bool SO2 >
6356  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
6357 
6358  inline bool isAligned () const;
6359  inline bool canSMPAssign() const;
6360 
6361  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
6362  BLAZE_ALWAYS_INLINE IntrinsicType loada( size_t i, size_t j ) const;
6363  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
6364 
6365  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
6366  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const IntrinsicType& value );
6367  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
6368  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
6369 
6370  template< typename MT2 >
6371  inline typename DisableIf< VectorizedAssign<MT2> >::Type
6372  assign( const DenseMatrix<MT2,false>& rhs );
6373 
6374  template< typename MT2 >
6375  inline typename EnableIf< VectorizedAssign<MT2> >::Type
6376  assign( const DenseMatrix<MT2,false>& rhs );
6377 
6378  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
6379  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
6380  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
6381 
6382  template< typename MT2 >
6383  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
6384  addAssign( const DenseMatrix<MT2,false>& rhs );
6385 
6386  template< typename MT2 >
6387  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
6388  addAssign( const DenseMatrix<MT2,false>& rhs );
6389 
6390  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
6391  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
6392  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
6393 
6394  template< typename MT2 >
6395  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
6396  subAssign( const DenseMatrix<MT2,false>& rhs );
6397 
6398  template< typename MT2 >
6399  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
6400  subAssign( const DenseMatrix<MT2,false>& rhs );
6401 
6402  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
6403  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
6404  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
6406  //**********************************************************************************************
6407 
6408  private:
6409  //**Utility functions***************************************************************************
6412  inline bool hasOverlap() const;
6414  //**********************************************************************************************
6415 
6416  //**Member variables****************************************************************************
6419  Operand matrix_;
6420  const size_t row_;
6421  const size_t column_;
6422  const size_t m_;
6423  const size_t n_;
6424 
6425  //**********************************************************************************************
6426 
6427  //**Friend declarations*************************************************************************
6428  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
6429 
6430  template< bool AF1, typename MT2, bool AF2, bool SO2 >
6431  friend const DenseSubmatrix<MT2,AF1,SO2>
6432  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
6433 
6434  template< typename MT2, bool AF2, bool SO2 >
6435  friend bool isIntact( const DenseSubmatrix<MT2,AF2,SO2>& dm );
6436 
6437  template< typename MT2, bool AF2, bool SO2 >
6438  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
6439 
6440  template< typename MT2, bool AF2, bool SO2 >
6441  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
6442 
6443  template< typename MT2, bool AF2, bool SO2 >
6444  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
6445 
6446  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
6447  friend bool tryAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
6448  size_t row, size_t column );
6449 
6450  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
6451  friend bool tryAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
6452  size_t row, size_t column );
6453 
6454  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
6455  friend bool tryAddAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
6456  size_t row, size_t column );
6457 
6458  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
6459  friend bool tryAddAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
6460  size_t row, size_t column );
6461 
6462  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
6463  friend bool trySubAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
6464  size_t row, size_t column );
6465 
6466  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
6467  friend bool trySubAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
6468  size_t row, size_t column );
6469 
6470  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
6471  friend bool tryMultAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
6472  size_t row, size_t column );
6473 
6474  template< typename MT2, bool AF2, bool SO2 >
6475  friend typename DerestrictTrait< DenseSubmatrix<MT2,AF2,SO2> >::Type
6476  derestrict( DenseSubmatrix<MT2,AF2,SO2>& dm );
6477  //**********************************************************************************************
6478 
6479  //**Compile time checks*************************************************************************
6487  //**********************************************************************************************
6488 };
6490 //*************************************************************************************************
6491 
6492 
6493 
6494 
6495 //=================================================================================================
6496 //
6497 // CONSTRUCTOR
6498 //
6499 //=================================================================================================
6500 
6501 //*************************************************************************************************
6515 template< typename MT > // Type of the dense matrix
6516 inline DenseSubmatrix<MT,aligned,false>::DenseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
6517  : matrix_( matrix ) // The dense matrix containing the submatrix
6518  , row_ ( rindex ) // The first row of the submatrix
6519  , column_( cindex ) // The first column of the submatrix
6520  , m_ ( m ) // The number of rows of the submatrix
6521  , n_ ( n ) // The number of columns of the submatrix
6522 {
6523  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
6524  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
6525  }
6526 
6527  if( ( vectorizable && matrix_.data() != NULL && !checkAlignment( data() ) ) ||
6528  ( m_ > 1UL && matrix_.spacing() % IT::size != 0UL ) ) {
6529  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix alignment" );
6530  }
6531 }
6533 //*************************************************************************************************
6534 
6535 
6536 
6537 
6538 //=================================================================================================
6539 //
6540 // DATA ACCESS FUNCTIONS
6541 //
6542 //=================================================================================================
6543 
6544 //*************************************************************************************************
6555 template< typename MT > // Type of the dense matrix
6557  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j )
6558 {
6559  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6560  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6561 
6562  return matrix_(row_+i,column_+j);
6563 }
6565 //*************************************************************************************************
6566 
6567 
6568 //*************************************************************************************************
6579 template< typename MT > // Type of the dense matrix
6581  DenseSubmatrix<MT,aligned,false>::operator()( size_t i, size_t j ) const
6582 {
6583  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6584  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6585 
6586  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
6587 }
6589 //*************************************************************************************************
6590 
6591 
6592 //*************************************************************************************************
6604 template< typename MT > // Type of the dense matrix
6606  DenseSubmatrix<MT,aligned,false>::at( size_t i, size_t j )
6607 {
6608  if( i >= rows() ) {
6609  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6610  }
6611  if( j >= columns() ) {
6612  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6613  }
6614  return (*this)(i,j);
6615 }
6617 //*************************************************************************************************
6618 
6619 
6620 //*************************************************************************************************
6632 template< typename MT > // Type of the dense matrix
6634  DenseSubmatrix<MT,aligned,false>::at( size_t i, size_t j ) const
6635 {
6636  if( i >= rows() ) {
6637  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6638  }
6639  if( j >= columns() ) {
6640  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6641  }
6642  return (*this)(i,j);
6643 }
6645 //*************************************************************************************************
6646 
6647 
6648 //*************************************************************************************************
6658 template< typename MT > // Type of the dense matrix
6659 inline typename DenseSubmatrix<MT,aligned,false>::Pointer
6661 {
6662  return matrix_.data() + row_*spacing() + column_;
6663 }
6665 //*************************************************************************************************
6666 
6667 
6668 //*************************************************************************************************
6678 template< typename MT > // Type of the dense matrix
6679 inline typename DenseSubmatrix<MT,aligned,false>::ConstPointer
6681 {
6682  return matrix_.data() + row_*spacing() + column_;
6683 }
6685 //*************************************************************************************************
6686 
6687 
6688 //*************************************************************************************************
6697 template< typename MT > // Type of the dense matrix
6698 inline typename DenseSubmatrix<MT,aligned,false>::Pointer
6700 {
6701  return matrix_.data() + (row_+i)*spacing() + column_;
6702 }
6704 //*************************************************************************************************
6705 
6706 
6707 //*************************************************************************************************
6716 template< typename MT > // Type of the dense matrix
6717 inline typename DenseSubmatrix<MT,aligned,false>::ConstPointer
6718  DenseSubmatrix<MT,aligned,false>::data( size_t i ) const
6719 {
6720  return matrix_.data() + (row_+i)*spacing() + column_;
6721 }
6723 //*************************************************************************************************
6724 
6725 
6726 //*************************************************************************************************
6738 template< typename MT > // Type of the dense matrix
6741 {
6742  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
6743  return ( matrix_.begin( row_ + i ) + column_ );
6744 }
6746 //*************************************************************************************************
6747 
6748 
6749 //*************************************************************************************************
6761 template< typename MT > // Type of the dense matrix
6763  DenseSubmatrix<MT,aligned,false>::begin( size_t i ) const
6764 {
6765  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
6766  return ( matrix_.cbegin( row_ + i ) + column_ );
6767 }
6769 //*************************************************************************************************
6770 
6771 
6772 //*************************************************************************************************
6784 template< typename MT > // Type of the dense matrix
6787 {
6788  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
6789  return ( matrix_.cbegin( row_ + i ) + column_ );
6790 }
6792 //*************************************************************************************************
6793 
6794 
6795 //*************************************************************************************************
6807 template< typename MT > // Type of the dense matrix
6810 {
6811  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
6812  return ( matrix_.begin( row_ + i ) + column_ + n_ );
6813 }
6815 //*************************************************************************************************
6816 
6817 
6818 //*************************************************************************************************
6830 template< typename MT > // Type of the dense matrix
6832  DenseSubmatrix<MT,aligned,false>::end( size_t i ) const
6833 {
6834  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
6835  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
6836 }
6838 //*************************************************************************************************
6839 
6840 
6841 //*************************************************************************************************
6853 template< typename MT > // Type of the dense matrix
6855  DenseSubmatrix<MT,aligned,false>::cend( size_t i ) const
6856 {
6857  BLAZE_USER_ASSERT( i < rows(), "Invalid dense submatrix row access index" );
6858  return ( matrix_.cbegin( row_ + i ) + column_ + n_ );
6859 }
6861 //*************************************************************************************************
6862 
6863 
6864 
6865 
6866 //=================================================================================================
6867 //
6868 // ASSIGNMENT OPERATORS
6869 //
6870 //=================================================================================================
6871 
6872 //*************************************************************************************************
6883 template< typename MT > // Type of the dense matrix
6884 inline DenseSubmatrix<MT,aligned,false>&
6885  DenseSubmatrix<MT,aligned,false>::operator=( const ElementType& rhs )
6886 {
6887  const size_t iend( row_ + m_ );
6888 
6889  for( size_t i=row_; i<iend; ++i )
6890  {
6891  const size_t jbegin( ( IsUpper<MT>::value )
6892  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
6893  ?( max( i+1UL, column_ ) )
6894  :( max( i, column_ ) ) )
6895  :( column_ ) );
6896  const size_t jend ( ( IsLower<MT>::value )
6897  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
6898  ?( min( i, column_+n_ ) )
6899  :( min( i+1UL, column_+n_ ) ) )
6900  :( column_+n_ ) );
6901 
6902  for( size_t j=jbegin; j<jend; ++j )
6903  matrix_(i,j) = rhs;
6904  }
6905 
6906  return *this;
6907 }
6909 //*************************************************************************************************
6910 
6911 
6912 //*************************************************************************************************
6927 template< typename MT > // Type of the dense matrix
6928 inline DenseSubmatrix<MT,aligned,false>&
6929  DenseSubmatrix<MT,aligned,false>::operator=( const DenseSubmatrix& rhs )
6930 {
6933 
6934  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
6935  return *this;
6936 
6937  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
6938  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
6939  }
6940 
6941  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
6942  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
6943  }
6944 
6945  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
6946 
6947  if( rhs.canAlias( &matrix_ ) ) {
6948  const ResultType tmp( rhs );
6949  smpAssign( left, tmp );
6950  }
6951  else {
6952  smpAssign( left, rhs );
6953  }
6954 
6955  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
6956 
6957  return *this;
6958 }
6960 //*************************************************************************************************
6961 
6962 
6963 //*************************************************************************************************
6978 template< typename MT > // Type of the dense matrix
6979 template< typename MT2 // Type of the right-hand side matrix
6980  , bool SO > // Storage order of the right-hand side matrix
6981 inline DenseSubmatrix<MT,aligned,false>&
6982  DenseSubmatrix<MT,aligned,false>::operator=( const Matrix<MT2,SO>& rhs )
6983 {
6985 
6986  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
6987  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
6988  }
6989 
6990  typedef typename If< IsRestricted<MT>, typename MT2::CompositeType, const MT2& >::Type Right;
6991  Right right( ~rhs );
6992 
6993  if( !tryAssign( matrix_, right, row_, column_ ) ) {
6994  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
6995  }
6996 
6997  if( IsSparseMatrix<MT2>::value )
6998  reset();
6999 
7000  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7001 
7002  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
7003  const typename MT2::ResultType tmp( right );
7004  smpAssign( left, tmp );
7005  }
7006  else {
7007  smpAssign( left, right );
7008  }
7009 
7010  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
7011 
7012  return *this;
7013 }
7015 //*************************************************************************************************
7016 
7017 
7018 //*************************************************************************************************
7032 template< typename MT > // Type of the dense matrix
7033 template< typename MT2 // Type of the right-hand side matrix
7034  , bool SO > // Storage order of the right-hand side matrix
7035 inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
7036  , DenseSubmatrix<MT,aligned,false>& >::Type
7037  DenseSubmatrix<MT,aligned,false>::operator+=( const Matrix<MT2,SO>& rhs )
7038 {
7042 
7043  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
7044 
7047 
7048  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
7049  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
7050  }
7051 
7052  if( !tryAddAssign( matrix_, ~rhs, row_, column_ ) ) {
7053  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
7054  }
7055 
7056  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7057 
7058  if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
7059  (~rhs).canAlias( &matrix_ ) ) {
7060  const AddType tmp( *this + (~rhs) );
7061  smpAssign( left, tmp );
7062  }
7063  else {
7064  smpAddAssign( left, ~rhs );
7065  }
7066 
7067  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
7068 
7069  return *this;
7070 }
7072 //*************************************************************************************************
7073 
7074 
7075 //*************************************************************************************************
7089 template< typename MT > // Type of the dense matrix
7090 template< typename MT2 // Type of the right-hand side matrix
7091  , bool SO > // Storage order of the right-hand side matrix
7092 inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
7093  , DenseSubmatrix<MT,aligned,false>& >::Type
7094  DenseSubmatrix<MT,aligned,false>::operator+=( const Matrix<MT2,SO>& rhs )
7095 {
7099 
7100  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
7101 
7104 
7105  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
7106  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
7107  }
7108 
7109  const AddType tmp( *this + (~rhs) );
7110 
7111  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
7112  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
7113  }
7114 
7115  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7116 
7117  smpAssign( left, tmp );
7118 
7119  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
7120 
7121  return *this;
7122 }
7124 //*************************************************************************************************
7125 
7126 
7127 //*************************************************************************************************
7141 template< typename MT > // Type of the dense matrix
7142 template< typename MT2 // Type of the right-hand side matrix
7143  , bool SO > // Storage order of the right-hand side matrix
7144 inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
7145  , DenseSubmatrix<MT,aligned,false>& >::Type
7146  DenseSubmatrix<MT,aligned,false>::operator-=( const Matrix<MT2,SO>& rhs )
7147 {
7151 
7152  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
7153 
7156 
7157  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
7158  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
7159  }
7160 
7161  if( !trySubAssign( matrix_, ~rhs, row_, column_ ) ) {
7162  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
7163  }
7164 
7165  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7166 
7167  if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
7168  (~rhs).canAlias( &matrix_ ) ) {
7169  const SubType tmp( *this - (~rhs ) );
7170  smpAssign( left, tmp );
7171  }
7172  else {
7173  smpSubAssign( left, ~rhs );
7174  }
7175 
7176  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
7177 
7178  return *this;
7179 }
7181 //*************************************************************************************************
7182 
7183 
7184 //*************************************************************************************************
7198 template< typename MT > // Type of the dense matrix
7199 template< typename MT2 // Type of the right-hand side matrix
7200  , bool SO > // Storage order of the right-hand side matrix
7201 inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
7202  , DenseSubmatrix<MT,aligned,false>& >::Type
7203  DenseSubmatrix<MT,aligned,false>::operator-=( const Matrix<MT2,SO>& rhs )
7204 {
7208 
7209  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
7210 
7213 
7214  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
7215  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
7216  }
7217 
7218  const SubType tmp( *this - (~rhs) );
7219 
7220  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
7221  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
7222  }
7223 
7224  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7225 
7226  smpAssign( left, tmp );
7227 
7228  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
7229 
7230  return *this;
7231 }
7233 //*************************************************************************************************
7234 
7235 
7236 //*************************************************************************************************
7250 template< typename MT > // Type of the dense matrix
7251 template< typename MT2 // Type of the right-hand side matrix
7252  , bool SO > // Storage order of the right-hand side matrix
7253 inline DenseSubmatrix<MT,aligned,false>&
7254  DenseSubmatrix<MT,aligned,false>::operator*=( const Matrix<MT2,SO>& rhs )
7255 {
7259 
7260  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
7261 
7264 
7265  if( columns() != (~rhs).rows() ) {
7266  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
7267  }
7268 
7269  const MultType tmp( *this * (~rhs) );
7270 
7271  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
7272  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
7273  }
7274 
7275  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7276 
7277  smpAssign( left, tmp );
7278 
7279  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
7280 
7281  return *this;
7282 }
7284 //*************************************************************************************************
7285 
7286 
7287 //*************************************************************************************************
7298 template< typename MT > // Type of the dense matrix
7299 template< typename Other > // Data type of the right-hand side scalar
7300 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
7301  DenseSubmatrix<MT,aligned,false>::operator*=( Other rhs )
7302 {
7304 
7305  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7306  smpAssign( left, (*this) * rhs );
7307 
7308  return *this;
7309 }
7311 //*************************************************************************************************
7312 
7313 
7314 //*************************************************************************************************
7327 template< typename MT > // Type of the dense matrix
7328 template< typename Other > // Data type of the right-hand side scalar
7329 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,false> >::Type&
7330  DenseSubmatrix<MT,aligned,false>::operator/=( Other rhs )
7331 {
7333 
7334  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
7335 
7336  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7337  smpAssign( left, (*this) / rhs );
7338 
7339  return *this;
7340 }
7342 //*************************************************************************************************
7343 
7344 
7345 
7346 
7347 //=================================================================================================
7348 //
7349 // UTILITY FUNCTIONS
7350 //
7351 //=================================================================================================
7352 
7353 //*************************************************************************************************
7359 template< typename MT > // Type of the dense matrix
7360 inline size_t DenseSubmatrix<MT,aligned,false>::row() const
7361 {
7362  return row_;
7363 }
7365 //*************************************************************************************************
7366 
7367 
7368 //*************************************************************************************************
7374 template< typename MT > // Type of the dense matrix
7375 inline size_t DenseSubmatrix<MT,aligned,false>::rows() const
7376 {
7377  return m_;
7378 }
7380 //*************************************************************************************************
7381 
7382 
7383 //*************************************************************************************************
7389 template< typename MT > // Type of the dense matrix
7390 inline size_t DenseSubmatrix<MT,aligned,false>::column() const
7391 {
7392  return column_;
7393 }
7395 //*************************************************************************************************
7396 
7397 
7398 //*************************************************************************************************
7404 template< typename MT > // Type of the dense matrix
7405 inline size_t DenseSubmatrix<MT,aligned,false>::columns() const
7406 {
7407  return n_;
7408 }
7410 //*************************************************************************************************
7411 
7412 
7413 //*************************************************************************************************
7424 template< typename MT > // Type of the dense matrix
7425 inline size_t DenseSubmatrix<MT,aligned,false>::spacing() const
7426 {
7427  return matrix_.spacing();
7428 }
7430 //*************************************************************************************************
7431 
7432 
7433 //*************************************************************************************************
7439 template< typename MT > // Type of the dense matrix
7440 inline size_t DenseSubmatrix<MT,aligned,false>::capacity() const
7441 {
7442  return rows() * columns();
7443 }
7445 //*************************************************************************************************
7446 
7447 
7448 //*************************************************************************************************
7460 template< typename MT > // Type of the dense matrix
7461 inline size_t DenseSubmatrix<MT,aligned,false>::capacity( size_t i ) const
7462 {
7463  UNUSED_PARAMETER( i );
7464 
7465  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
7466 
7467  return columns();
7468 }
7470 //*************************************************************************************************
7471 
7472 
7473 //*************************************************************************************************
7479 template< typename MT > // Type of the dense matrix
7480 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros() const
7481 {
7482  const size_t iend( row_ + m_ );
7483  const size_t jend( column_ + n_ );
7484  size_t nonzeros( 0UL );
7485 
7486  for( size_t i=row_; i<iend; ++i )
7487  for( size_t j=column_; j<jend; ++j )
7488  if( !isDefault( matrix_(i,j) ) )
7489  ++nonzeros;
7490 
7491  return nonzeros;
7492 }
7494 //*************************************************************************************************
7495 
7496 
7497 //*************************************************************************************************
7509 template< typename MT > // Type of the dense matrix
7510 inline size_t DenseSubmatrix<MT,aligned,false>::nonZeros( size_t i ) const
7511 {
7512  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
7513 
7514  const size_t jend( column_ + n_ );
7515  size_t nonzeros( 0UL );
7516 
7517  for( size_t j=column_; j<jend; ++j )
7518  if( !isDefault( matrix_(row_+i,j) ) )
7519  ++nonzeros;
7520 
7521  return nonzeros;
7522 }
7524 //*************************************************************************************************
7525 
7526 
7527 //*************************************************************************************************
7533 template< typename MT > // Type of the dense matrix
7535 {
7536  using blaze::clear;
7537 
7538  for( size_t i=row_; i<row_+m_; ++i )
7539  {
7540  const size_t jbegin( ( IsUpper<MT>::value )
7541  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
7542  ?( max( i+1UL, column_ ) )
7543  :( max( i, column_ ) ) )
7544  :( column_ ) );
7545  const size_t jend ( ( IsLower<MT>::value )
7546  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
7547  ?( min( i, column_+n_ ) )
7548  :( min( i+1UL, column_+n_ ) ) )
7549  :( column_+n_ ) );
7550 
7551  for( size_t j=jbegin; j<jend; ++j )
7552  clear( matrix_(i,j) );
7553  }
7554 }
7556 //*************************************************************************************************
7557 
7558 
7559 //*************************************************************************************************
7571 template< typename MT > // Type of the dense matrix
7572 inline void DenseSubmatrix<MT,aligned,false>::reset( size_t i )
7573 {
7574  using blaze::clear;
7575 
7576  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
7577 
7578  const size_t jbegin( ( IsUpper<MT>::value )
7579  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
7580  ?( max( i+1UL, column_ ) )
7581  :( max( i, column_ ) ) )
7582  :( column_ ) );
7583  const size_t jend ( ( IsLower<MT>::value )
7584  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
7585  ?( min( i, column_+n_ ) )
7586  :( min( i+1UL, column_+n_ ) ) )
7587  :( column_+n_ ) );
7588 
7589  for( size_t j=jbegin; j<jend; ++j )
7590  clear( matrix_(row_+i,j) );
7591 }
7593 //*************************************************************************************************
7594 
7595 
7596 //*************************************************************************************************
7614 template< typename MT > // Type of the dense matrix
7615 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::transpose()
7616 {
7617  if( m_ != n_ ) {
7618  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
7619  }
7620 
7621  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
7622  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
7623  }
7624 
7625  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7626  const ResultType tmp( trans( *this ) );
7627  smpAssign( left, tmp );
7628 
7629  return *this;
7630 }
7632 //*************************************************************************************************
7633 
7634 
7635 //*************************************************************************************************
7653 template< typename MT > // Type of the dense matrix
7654 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::ctranspose()
7655 {
7656  if( m_ != n_ ) {
7657  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
7658  }
7659 
7660  if( !tryAssign( matrix_, ctrans( *this ), row_, column_ ) ) {
7661  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
7662  }
7663 
7664  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
7665  const ResultType tmp( ctrans( *this ) );
7666  smpAssign( left, tmp );
7667 
7668  return *this;
7669 }
7671 //*************************************************************************************************
7672 
7673 
7674 //*************************************************************************************************
7685 template< typename MT > // Type of the dense matrix
7686 template< typename Other > // Data type of the scalar value
7687 inline DenseSubmatrix<MT,aligned,false>& DenseSubmatrix<MT,aligned,false>::scale( const Other& scalar )
7688 {
7690 
7691  const size_t iend( row_ + m_ );
7692 
7693  for( size_t i=row_; i<iend; ++i )
7694  {
7695  const size_t jbegin( ( IsUpper<MT>::value )
7696  ?( ( IsStrictlyUpper<MT>::value )
7697  ?( max( i+1UL, column_ ) )
7698  :( max( i, column_ ) ) )
7699  :( column_ ) );
7700  const size_t jend ( ( IsLower<MT>::value )
7701  ?( ( IsStrictlyLower<MT>::value )
7702  ?( min( i, column_+n_ ) )
7703  :( min( i+1UL, column_+n_ ) ) )
7704  :( column_+n_ ) );
7705 
7706  for( size_t j=jbegin; j<jend; ++j )
7707  matrix_(i,j) *= scalar;
7708  }
7709 
7710  return *this;
7711 }
7713 //*************************************************************************************************
7714 
7715 
7716 //*************************************************************************************************
7726 template< typename MT > // Type of the dense matrix
7728 {
7729  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
7730 
7731  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
7732  return false;
7733  else return true;
7734 }
7736 //*************************************************************************************************
7737 
7738 
7739 
7740 
7741 //=================================================================================================
7742 //
7743 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
7744 //
7745 //=================================================================================================
7746 
7747 //*************************************************************************************************
7758 template< typename MT > // Type of the dense matrix
7759 template< typename Other > // Data type of the foreign expression
7760 inline bool DenseSubmatrix<MT,aligned,false>::canAlias( const Other* alias ) const
7761 {
7762  return matrix_.isAliased( alias );
7763 }
7765 //*************************************************************************************************
7766 
7767 
7768 //*************************************************************************************************
7779 template< typename MT > // Type of the dense matrix
7780 template< typename MT2 // Data type of the foreign dense submatrix
7781  , bool AF2 // Alignment flag of the foreign dense submatrix
7782  , bool SO2 > // Storage order of the foreign dense submatrix
7783 inline bool DenseSubmatrix<MT,aligned,false>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
7784 {
7785  return ( matrix_.isAliased( &alias->matrix_ ) &&
7786  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
7787  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
7788 }
7790 //*************************************************************************************************
7791 
7792 
7793 //*************************************************************************************************
7804 template< typename MT > // Type of the dense matrix
7805 template< typename Other > // Data type of the foreign expression
7806 inline bool DenseSubmatrix<MT,aligned,false>::isAliased( const Other* alias ) const
7807 {
7808  return matrix_.isAliased( alias );
7809 }
7811 //*************************************************************************************************
7812 
7813 
7814 //*************************************************************************************************
7825 template< typename MT > // Type of the dense matrix
7826 template< typename MT2 // Data type of the foreign dense submatrix
7827  , bool AF2 // Alignment flag of the foreign dense submatrix
7828  , bool SO2 > // Storage order of the foreign dense submatrix
7829 inline bool DenseSubmatrix<MT,aligned,false>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
7830 {
7831  return ( matrix_.isAliased( &alias->matrix_ ) &&
7832  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
7833  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
7834 }
7836 //*************************************************************************************************
7837 
7838 
7839 //*************************************************************************************************
7849 template< typename MT > // Type of the dense matrix
7851 {
7852  return true;
7853 }
7855 //*************************************************************************************************
7856 
7857 
7858 //*************************************************************************************************
7869 template< typename MT > // Type of the dense matrix
7871 {
7872  return ( rows() > SMP_DMATASSIGN_THRESHOLD );
7873 }
7875 //*************************************************************************************************
7876 
7877 
7878 //*************************************************************************************************
7894 template< typename MT > // Type of the dense matrix
7895 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
7896  DenseSubmatrix<MT,aligned,false>::load( size_t i, size_t j ) const
7897 {
7898  return loada( i, j );
7899 }
7901 //*************************************************************************************************
7902 
7903 
7904 //*************************************************************************************************
7921 template< typename MT > // Type of the dense matrix
7922 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
7923  DenseSubmatrix<MT,aligned,false>::loada( size_t i, size_t j ) const
7924 {
7926 
7927  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
7928  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
7929  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
7930  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
7931 
7932  return matrix_.loada( row_+i, column_+j );
7933 }
7935 //*************************************************************************************************
7936 
7937 
7938 //*************************************************************************************************
7955 template< typename MT > // Type of the dense matrix
7956 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,false>::IntrinsicType
7957  DenseSubmatrix<MT,aligned,false>::loadu( size_t i, size_t j ) const
7958 {
7960 
7961  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
7962  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
7963  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
7964  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
7965 
7966  return matrix_.loadu( row_+i, column_+j );
7967 }
7969 //*************************************************************************************************
7970 
7971 
7972 //*************************************************************************************************
7989 template< typename MT > // Type of the dense matrix
7991  DenseSubmatrix<MT,aligned,false>::store( size_t i, size_t j, const IntrinsicType& value )
7992 {
7993  return storea( i, j, value );
7994 }
7996 //*************************************************************************************************
7997 
7998 
7999 //*************************************************************************************************
8016 template< typename MT > // Type of the dense matrix
8018  DenseSubmatrix<MT,aligned,false>::storea( size_t i, size_t j, const IntrinsicType& value )
8019 {
8021 
8022  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
8023  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
8024  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
8025  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
8026 
8027  return matrix_.storea( row_+i, column_+j, value );
8028 }
8030 //*************************************************************************************************
8031 
8032 
8033 //*************************************************************************************************
8050 template< typename MT > // Type of the dense matrix
8052  DenseSubmatrix<MT,aligned,false>::storeu( size_t i, size_t j, const IntrinsicType& value )
8053 {
8055 
8056  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
8057  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
8058  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
8059  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
8060 
8061  matrix_.storeu( row_+i, column_+j, value );
8062 }
8064 //*************************************************************************************************
8065 
8066 
8067 //*************************************************************************************************
8085 template< typename MT > // Type of the dense matrix
8087  DenseSubmatrix<MT,aligned,false>::stream( size_t i, size_t j, const IntrinsicType& value )
8088 {
8090 
8091  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
8092  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
8093  BLAZE_INTERNAL_ASSERT( j + IT::size <= columns(), "Invalid column access index" );
8094  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
8095 
8096  matrix_.stream( row_+i, column_+j, value );
8097 }
8099 //*************************************************************************************************
8100 
8101 
8102 //*************************************************************************************************
8114 template< typename MT > // Type of the dense matrix
8115 template< typename MT2 > // Type of the right-hand side dense matrix
8116 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
8117  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
8118 {
8119  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8120  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8121 
8122  const size_t jpos( n_ & size_t(-2) );
8123  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
8124 
8125  for( size_t i=0UL; i<m_; ++i ) {
8126  for( size_t j=0UL; j<jpos; j+=2UL ) {
8127  matrix_(row_+i,column_+j ) = (~rhs)(i,j );
8128  matrix_(row_+i,column_+j+1UL) = (~rhs)(i,j+1UL);
8129  }
8130  if( jpos < n_ ) {
8131  matrix_(row_+i,column_+jpos) = (~rhs)(i,jpos);
8132  }
8133  }
8134 }
8136 //*************************************************************************************************
8137 
8138 
8139 //*************************************************************************************************
8151 template< typename MT > // Type of the dense matrix
8152 template< typename MT2 > // Type of the right-hand side dense matrix
8153 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
8154  DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,false>& rhs )
8155 {
8157 
8158  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8159  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8160 
8161  const size_t jpos( n_ & size_t(-IT::size) );
8162  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size) ) ) == jpos, "Invalid end calculation" );
8163 
8164  if( useStreaming &&
8165  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
8166  !(~rhs).isAliased( &matrix_ ) )
8167  {
8168  for( size_t i=0UL; i<m_; ++i )
8169  {
8170  size_t j( 0UL );
8171 
8172  for( ; j<jpos; j+=IT::size ) {
8173  stream( i, j, (~rhs).load(i,j) );
8174  }
8175  for( ; j<n_; ++j ) {
8176  matrix_(row_+i,column_+j) = (~rhs)(i,j);
8177  }
8178  }
8179  }
8180  else
8181  {
8182  for( size_t i=0UL; i<m_; ++i )
8183  {
8184  size_t j( 0UL );
8185  typename MT2::ConstIterator it( (~rhs).begin(i) );
8186 
8187  for( ; (j+IT::size*3UL) < jpos; j+=IT::size*4UL ) {
8188  store( i, j , it.load() ); it += IT::size;
8189  store( i, j+IT::size , it.load() ); it += IT::size;
8190  store( i, j+IT::size*2UL, it.load() ); it += IT::size;
8191  store( i, j+IT::size*3UL, it.load() ); it += IT::size;
8192  }
8193  for( ; j<jpos; j+=IT::size, it+=IT::size ) {
8194  store( i, j, it.load() );
8195  }
8196  for( ; j<n_; ++j, ++it ) {
8197  matrix_(row_+i,column_+j) = *it;
8198  }
8199  }
8200  }
8201 }
8203 //*************************************************************************************************
8204 
8205 
8206 //*************************************************************************************************
8218 template< typename MT > // Type of the dense matrix
8219 template< typename MT2 > // Type of the right-hand side dense matrix
8220 inline void DenseSubmatrix<MT,aligned,false>::assign( const DenseMatrix<MT2,true>& rhs )
8221 {
8223 
8224  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8225  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8226 
8227  const size_t block( BLOCK_SIZE );
8228 
8229  for( size_t ii=0UL; ii<m_; ii+=block ) {
8230  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
8231  for( size_t jj=0UL; jj<n_; jj+=block ) {
8232  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
8233  for( size_t i=ii; i<iend; ++i ) {
8234  for( size_t j=jj; j<jend; ++j ) {
8235  matrix_(row_+i,column_+j) = (~rhs)(i,j);
8236  }
8237  }
8238  }
8239  }
8240 }
8242 //*************************************************************************************************
8243 
8244 
8245 //*************************************************************************************************
8257 template< typename MT > // Type of the dense matrix
8258 template< typename MT2 > // Type of the right-hand side sparse matrix
8259 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,false>& rhs )
8260 {
8261  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8262  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8263 
8264  for( size_t i=0UL; i<m_; ++i )
8265  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
8266  matrix_(row_+i,column_+element->index()) = element->value();
8267 }
8269 //*************************************************************************************************
8270 
8271 
8272 //*************************************************************************************************
8284 template< typename MT > // Type of the dense matrix
8285 template< typename MT2 > // Type of the right-hand side sparse matrix
8286 inline void DenseSubmatrix<MT,aligned,false>::assign( const SparseMatrix<MT2,true>& rhs )
8287 {
8289 
8290  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8291  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8292 
8293  for( size_t j=0UL; j<n_; ++j )
8294  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
8295  matrix_(row_+element->index(),column_+j) = element->value();
8296 }
8298 //*************************************************************************************************
8299 
8300 
8301 //*************************************************************************************************
8313 template< typename MT > // Type of the dense matrix
8314 template< typename MT2 > // Type of the right-hand side dense matrix
8315 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
8316  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
8317 {
8318  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8319  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8320 
8321  const size_t jpos( n_ & size_t(-2) );
8322  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
8323 
8324  for( size_t i=0UL; i<m_; ++i ) {
8325  for( size_t j=0UL; j<jpos; j+=2UL ) {
8326  matrix_(row_+i,column_+j ) += (~rhs)(i,j );
8327  matrix_(row_+i,column_+j+1UL) += (~rhs)(i,j+1UL);
8328  }
8329  if( jpos < n_ ) {
8330  matrix_(row_+i,column_+jpos) += (~rhs)(i,jpos);
8331  }
8332  }
8333 }
8335 //*************************************************************************************************
8336 
8337 
8338 //*************************************************************************************************
8350 template< typename MT > // Type of the dense matrix
8351 template< typename MT2 > // Type of the right-hand side dense matrix
8352 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
8353  DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,false>& rhs )
8354 {
8356 
8357  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8358  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8359 
8360  for( size_t i=0UL; i<m_; ++i )
8361  {
8362  const size_t jbegin( ( IsUpper<MT2>::value )
8363  ?( ( IsStrictlyUpper<MT2>::value ? i+1UL : i ) & size_t(-IT::size) )
8364  :( 0UL ) );
8365  const size_t jend ( ( IsLower<MT2>::value )
8366  ?( IsStrictlyLower<MT2>::value ? i : i+1UL )
8367  :( n_ ) );
8368  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
8369 
8370  const size_t jpos( jend & size_t(-IT::size) );
8371  BLAZE_INTERNAL_ASSERT( ( jend - ( jend % (IT::size) ) ) == jpos, "Invalid end calculation" );
8372 
8373  size_t j( jbegin );
8374  typename MT2::ConstIterator it( (~rhs).begin(i) );
8375 
8376  for( ; (j+IT::size*3UL) < jpos; j+=IT::size*4UL ) {
8377  store( i, j , load(i,j ) + it.load() ); it += IT::size;
8378  store( i, j+IT::size , load(i,j+IT::size ) + it.load() ); it += IT::size;
8379  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) + it.load() ); it += IT::size;
8380  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) + it.load() ); it += IT::size;
8381  }
8382  for( ; j<jpos; j+=IT::size, it+=IT::size ) {
8383  store( i, j, load(i,j) + it.load() );
8384  }
8385  for( ; j<jend; ++j, ++it ) {
8386  matrix_(row_+i,column_+j) += *it;
8387  }
8388  }
8389 }
8391 //*************************************************************************************************
8392 
8393 
8394 //*************************************************************************************************
8406 template< typename MT > // Type of the dense matrix
8407 template< typename MT2 > // Type of the right-hand side dense matrix
8408 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const DenseMatrix<MT2,true>& rhs )
8409 {
8411 
8412  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8413  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8414 
8415  const size_t block( BLOCK_SIZE );
8416 
8417  for( size_t ii=0UL; ii<m_; ii+=block ) {
8418  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
8419  for( size_t jj=0UL; jj<n_; jj+=block ) {
8420  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
8421  for( size_t i=ii; i<iend; ++i ) {
8422  for( size_t j=jj; j<jend; ++j ) {
8423  matrix_(row_+i,column_+j) += (~rhs)(i,j);
8424  }
8425  }
8426  }
8427  }
8428 }
8430 //*************************************************************************************************
8431 
8432 
8433 //*************************************************************************************************
8445 template< typename MT > // Type of the dense matrix
8446 template< typename MT2 > // Type of the right-hand side sparse matrix
8447 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,false>& rhs )
8448 {
8449  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8450  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8451 
8452  for( size_t i=0UL; i<m_; ++i )
8453  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
8454  matrix_(row_+i,column_+element->index()) += element->value();
8455 }
8457 //*************************************************************************************************
8458 
8459 
8460 //*************************************************************************************************
8472 template< typename MT > // Type of the dense matrix
8473 template< typename MT2 > // Type of the right-hand side sparse matrix
8474 inline void DenseSubmatrix<MT,aligned,false>::addAssign( const SparseMatrix<MT2,true>& rhs )
8475 {
8477 
8478  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8479  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8480 
8481  for( size_t j=0UL; j<n_; ++j )
8482  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
8483  matrix_(row_+element->index(),column_+j) += element->value();
8484 }
8486 //*************************************************************************************************
8487 
8488 
8489 //*************************************************************************************************
8501 template< typename MT > // Type of the dense matrix
8502 template< typename MT2 > // Type of the right-hand side dense matrix
8503 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
8504  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
8505 {
8506  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8507  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8508 
8509  const size_t jpos( n_ & size_t(-2) );
8510  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
8511 
8512  for( size_t i=0UL; i<m_; ++i ) {
8513  for( size_t j=0UL; j<jpos; j+=2UL ) {
8514  matrix_(row_+i,column_+j ) -= (~rhs)(i,j );
8515  matrix_(row_+i,column_+j+1UL) -= (~rhs)(i,j+1UL);
8516  }
8517  if( jpos < n_ ) {
8518  matrix_(row_+i,column_+jpos) -= (~rhs)(i,jpos);
8519  }
8520  }
8521 }
8523 //*************************************************************************************************
8524 
8525 
8526 //*************************************************************************************************
8538 template< typename MT > // Type of the dense matrix
8539 template< typename MT2 > // Type of the right-hand side dense matrix
8540 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,false>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
8541  DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,false>& rhs )
8542 {
8544 
8545  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8546  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8547 
8548  for( size_t i=0UL; i<m_; ++i )
8549  {
8550  const size_t jbegin( ( IsUpper<MT2>::value )
8551  ?( ( IsStrictlyUpper<MT2>::value ? i+1UL : i ) & size_t(-IT::size) )
8552  :( 0UL ) );
8553  const size_t jend ( ( IsLower<MT2>::value )
8554  ?( IsStrictlyLower<MT2>::value ? i : i+1UL )
8555  :( n_ ) );
8556  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
8557 
8558  const size_t jpos( jend & size_t(-IT::size) );
8559  BLAZE_INTERNAL_ASSERT( ( jend - ( jend % (IT::size) ) ) == jpos, "Invalid end calculation" );
8560 
8561  size_t j( jbegin );
8562  typename MT2::ConstIterator it( (~rhs).begin(i) );
8563 
8564  for( ; (j+IT::size*3UL) < jpos; j+=IT::size*4UL ) {
8565  store( i, j , load(i,j ) - it.load() ); it += IT::size;
8566  store( i, j+IT::size , load(i,j+IT::size ) - it.load() ); it += IT::size;
8567  store( i, j+IT::size*2UL, load(i,j+IT::size*2UL) - it.load() ); it += IT::size;
8568  store( i, j+IT::size*3UL, load(i,j+IT::size*3UL) - it.load() ); it += IT::size;
8569  }
8570  for( ; j<jpos; j+=IT::size, it+=IT::size ) {
8571  store( i, j, load(i,j) - it.load() );
8572  }
8573  for( ; j<jend; ++j, ++it ) {
8574  matrix_(row_+i,column_+j) -= *it;
8575  }
8576  }
8577 }
8579 //*************************************************************************************************
8580 
8581 
8582 //*************************************************************************************************
8594 template< typename MT > // Type of the dense matrix
8595 template< typename MT2 > // Type of the right-hand side dense matrix
8596 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const DenseMatrix<MT2,true>& rhs )
8597 {
8599 
8600  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8601  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8602 
8603  const size_t block( BLOCK_SIZE );
8604 
8605  for( size_t ii=0UL; ii<m_; ii+=block ) {
8606  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
8607  for( size_t jj=0UL; jj<n_; jj+=block ) {
8608  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
8609  for( size_t i=ii; i<iend; ++i ) {
8610  for( size_t j=jj; j<jend; ++j ) {
8611  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
8612  }
8613  }
8614  }
8615  }
8616 }
8618 //*************************************************************************************************
8619 
8620 
8621 //*************************************************************************************************
8633 template< typename MT > // Type of the dense matrix
8634 template< typename MT2 > // Type of the right-hand side sparse matrix
8635 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,false>& rhs )
8636 {
8637  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8638  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8639 
8640  for( size_t i=0UL; i<m_; ++i )
8641  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
8642  matrix_(row_+i,column_+element->index()) -= element->value();
8643 }
8645 //*************************************************************************************************
8646 
8647 
8648 //*************************************************************************************************
8660 template< typename MT > // Type of the dense matrix
8661 template< typename MT2 > // Type of the right-hand side sparse matrix
8662 inline void DenseSubmatrix<MT,aligned,false>::subAssign( const SparseMatrix<MT2,true>& rhs )
8663 {
8665 
8666  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
8667  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
8668 
8669  for( size_t j=0UL; j<n_; ++j )
8670  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
8671  matrix_(row_+element->index(),column_+j) -= element->value();
8672 }
8674 //*************************************************************************************************
8675 
8676 
8677 
8678 
8679 
8680 
8681 
8682 
8683 //=================================================================================================
8684 //
8685 // CLASS TEMPLATE SPECIALIZATION FOR ALIGNED COLUMN-MAJOR SUBMATRICES
8686 //
8687 //=================================================================================================
8688 
8689 //*************************************************************************************************
8697 template< typename MT > // Type of the dense matrix
8698 class DenseSubmatrix<MT,aligned,true> : public DenseMatrix< DenseSubmatrix<MT,aligned,true>, true >
8699  , private Submatrix
8700 {
8701  private:
8702  //**Type definitions****************************************************************************
8704  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
8705 
8707  typedef IntrinsicTrait<typename MT::ElementType> IT;
8708  //**********************************************************************************************
8709 
8710  public:
8711  //**Type definitions****************************************************************************
8712  typedef DenseSubmatrix<MT,aligned,true> This;
8713  typedef typename SubmatrixTrait<MT>::Type ResultType;
8714  typedef typename ResultType::OppositeType OppositeType;
8715  typedef typename ResultType::TransposeType TransposeType;
8716  typedef typename MT::ElementType ElementType;
8717  typedef typename IT::Type IntrinsicType;
8718  typedef typename MT::ReturnType ReturnType;
8719  typedef const DenseSubmatrix& CompositeType;
8720 
8722  typedef typename MT::ConstReference ConstReference;
8723 
8725  typedef typename If< IsConst<MT>, ConstReference, typename MT::Reference >::Type Reference;
8726 
8728  typedef const ElementType* ConstPointer;
8729 
8731  typedef typename If< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >
8732  , ConstPointer, ElementType* >::Type Pointer;
8733 
8735  typedef typename MT::ConstIterator ConstIterator;
8736 
8738  typedef typename If< IsConst<MT>, ConstIterator, typename MT::Iterator >::Type Iterator;
8739  //**********************************************************************************************
8740 
8741  //**Compilation flags***************************************************************************
8743  enum { vectorizable = MT::vectorizable };
8744 
8746  enum { smpAssignable = MT::smpAssignable };
8747  //**********************************************************************************************
8748 
8749  //**Constructors********************************************************************************
8752  explicit inline DenseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n );
8753  // No explicitly declared copy constructor.
8755  //**********************************************************************************************
8756 
8757  //**Destructor**********************************************************************************
8758  // No explicitly declared destructor.
8759  //**********************************************************************************************
8760 
8761  //**Data access functions***********************************************************************
8764  inline Reference operator()( size_t i, size_t j );
8765  inline ConstReference operator()( size_t i, size_t j ) const;
8766  inline Reference at( size_t i, size_t j );
8767  inline ConstReference at( size_t i, size_t j ) const;
8768  inline Pointer data ();
8769  inline ConstPointer data () const;
8770  inline Pointer data ( size_t j );
8771  inline ConstPointer data ( size_t j ) const;
8772  inline Iterator begin ( size_t j );
8773  inline ConstIterator begin ( size_t j ) const;
8774  inline ConstIterator cbegin( size_t j ) const;
8775  inline Iterator end ( size_t j );
8776  inline ConstIterator end ( size_t j ) const;
8777  inline ConstIterator cend ( size_t j ) const;
8779  //**********************************************************************************************
8780 
8781  //**Assignment operators************************************************************************
8784  inline DenseSubmatrix& operator=( const ElementType& rhs );
8785  inline DenseSubmatrix& operator=( const DenseSubmatrix& rhs );
8786 
8787  template< typename MT2, bool SO >
8788  inline DenseSubmatrix& operator=( const Matrix<MT2,SO>& rhs );
8789 
8790  template< typename MT2, bool SO >
8791  inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
8792  operator+=( const Matrix<MT2,SO>& rhs );
8793 
8794  template< typename MT2, bool SO >
8795  inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
8796  operator+=( const Matrix<MT2,SO>& rhs );
8797 
8798  template< typename MT2, bool SO >
8799  inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
8800  operator-=( const Matrix<MT2,SO>& rhs );
8801 
8802  template< typename MT2, bool SO >
8803  inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, DenseSubmatrix& >::Type
8804  operator-=( const Matrix<MT2,SO>& rhs );
8805 
8806  template< typename MT2, bool SO >
8807  inline DenseSubmatrix& operator*=( const Matrix<MT2,SO>& rhs );
8808 
8809  template< typename Other >
8810  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
8811  operator*=( Other rhs );
8812 
8813  template< typename Other >
8814  inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix >::Type&
8815  operator/=( Other rhs );
8817  //**********************************************************************************************
8818 
8819  //**Utility functions***************************************************************************
8822  inline size_t row() const;
8823  inline size_t rows() const;
8824  inline size_t column() const;
8825  inline size_t columns() const;
8826  inline size_t spacing() const;
8827  inline size_t capacity() const;
8828  inline size_t capacity( size_t i ) const;
8829  inline size_t nonZeros() const;
8830  inline size_t nonZeros( size_t i ) const;
8831  inline void reset();
8832  inline void reset( size_t i );
8833  inline DenseSubmatrix& transpose();
8834  inline DenseSubmatrix& ctranspose();
8835  template< typename Other > inline DenseSubmatrix& scale( const Other& scalar );
8837  //**********************************************************************************************
8838 
8839  private:
8840  //**********************************************************************************************
8842  template< typename MT2 >
8843  struct VectorizedAssign {
8844  enum { value = useOptimizedKernels &&
8845  vectorizable && MT2::vectorizable &&
8846  IsSame<ElementType,typename MT2::ElementType>::value };
8847  };
8848  //**********************************************************************************************
8849 
8850  //**********************************************************************************************
8852  template< typename MT2 >
8853  struct VectorizedAddAssign {
8854  enum { value = useOptimizedKernels &&
8855  vectorizable && MT2::vectorizable &&
8856  IsSame<ElementType,typename MT2::ElementType>::value &&
8857  IntrinsicTrait<ElementType>::addition };
8858  };
8859  //**********************************************************************************************
8860 
8861  //**********************************************************************************************
8863  template< typename MT2 >
8864  struct VectorizedSubAssign {
8865  enum { value = useOptimizedKernels &&
8866  vectorizable && MT2::vectorizable &&
8867  IsSame<ElementType,typename MT2::ElementType>::value &&
8868  IntrinsicTrait<ElementType>::subtraction };
8869  };
8870  //**********************************************************************************************
8871 
8872  public:
8873  //**Expression template evaluation functions****************************************************
8876  template< typename Other >
8877  inline bool canAlias( const Other* alias ) const;
8878 
8879  template< typename MT2, bool AF2, bool SO2 >
8880  inline bool canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
8881 
8882  template< typename Other >
8883  inline bool isAliased( const Other* alias ) const;
8884 
8885  template< typename MT2, bool AF2, bool SO2 >
8886  inline bool isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const;
8887 
8888  inline bool isAligned () const;
8889  inline bool canSMPAssign() const;
8890 
8891  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
8892  BLAZE_ALWAYS_INLINE IntrinsicType loada( size_t i, size_t j ) const;
8893  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
8894 
8895  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
8896  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const IntrinsicType& value );
8897  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
8898  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
8899 
8900  template< typename MT2 >
8901  inline typename DisableIf< VectorizedAssign<MT2> >::Type
8902  assign( const DenseMatrix<MT2,true>& rhs );
8903 
8904  template< typename MT2 >
8905  inline typename EnableIf< VectorizedAssign<MT2> >::Type
8906  assign( const DenseMatrix<MT2,true>& rhs );
8907 
8908  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
8909  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
8910  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
8911 
8912  template< typename MT2 >
8913  inline typename DisableIf< VectorizedAddAssign<MT2> >::Type
8914  addAssign( const DenseMatrix<MT2,true>& rhs );
8915 
8916  template< typename MT2 >
8917  inline typename EnableIf< VectorizedAddAssign<MT2> >::Type
8918  addAssign( const DenseMatrix<MT2,true>& rhs );
8919 
8920  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
8921  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
8922  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
8923 
8924  template< typename MT2 >
8925  inline typename DisableIf< VectorizedSubAssign<MT2> >::Type
8926  subAssign( const DenseMatrix<MT2,true>& rhs );
8927 
8928  template< typename MT2 >
8929  inline typename EnableIf< VectorizedSubAssign<MT2> >::Type
8930  subAssign( const DenseMatrix<MT2,true>& rhs );
8931 
8932  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
8933  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
8934  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
8936  //**********************************************************************************************
8937 
8938  private:
8939  //**Utility functions***************************************************************************
8942  inline bool hasOverlap() const;
8944  //**********************************************************************************************
8945 
8946  //**Member variables****************************************************************************
8949  Operand matrix_;
8950  const size_t row_;
8951  const size_t column_;
8952  const size_t m_;
8953  const size_t n_;
8954 
8955  //**********************************************************************************************
8956 
8957  //**Friend declarations*************************************************************************
8958  template< typename MT2, bool AF2, bool SO2 > friend class DenseSubmatrix;
8959 
8960  template< bool AF1, typename MT2, bool AF2, bool SO2 >
8961  friend const DenseSubmatrix<MT2,AF1,SO2>
8962  submatrix( const DenseSubmatrix<MT2,AF2,SO2>& dm, size_t row, size_t column, size_t m, size_t n );
8963 
8964  template< typename MT2, bool AF2, bool SO2 >
8965  friend bool isIntact( const DenseSubmatrix<MT2,AF2,SO2>& dm );
8966 
8967  template< typename MT2, bool AF2, bool SO2 >
8968  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseMatrix<MT2,SO2>& b );
8969 
8970  template< typename MT2, bool AF2, bool SO2 >
8971  friend bool isSame( const DenseMatrix<MT2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
8972 
8973  template< typename MT2, bool AF2, bool SO2 >
8974  friend bool isSame( const DenseSubmatrix<MT2,AF2,SO2>& a, const DenseSubmatrix<MT2,AF2,SO2>& b );
8975 
8976  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
8977  friend bool tryAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
8978  size_t row, size_t column );
8979 
8980  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
8981  friend bool tryAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
8982  size_t row, size_t column );
8983 
8984  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
8985  friend bool tryAddAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
8986  size_t row, size_t column );
8987 
8988  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
8989  friend bool tryAddAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
8990  size_t row, size_t column );
8991 
8992  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
8993  friend bool trySubAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
8994  size_t row, size_t column );
8995 
8996  template< typename MT2, bool AF2, bool SO2, typename MT3, bool SO3 >
8997  friend bool trySubAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Matrix<MT3,SO3>& rhs,
8998  size_t row, size_t column );
8999 
9000  template< typename MT2, bool AF2, bool SO2, typename VT, bool TF >
9001  friend bool tryMultAssign( const DenseSubmatrix<MT2,AF2,SO2>& lhs, const Vector<VT,TF>& rhs,
9002  size_t row, size_t column );
9003 
9004  template< typename MT2, bool AF2, bool SO2 >
9005  friend typename DerestrictTrait< DenseSubmatrix<MT2,AF2,SO2> >::Type
9006  derestrict( DenseSubmatrix<MT2,AF2,SO2>& dm );
9007  //**********************************************************************************************
9008 
9009  //**Compile time checks*************************************************************************
9017  //**********************************************************************************************
9018 };
9020 //*************************************************************************************************
9021 
9022 
9023 
9024 
9025 //=================================================================================================
9026 //
9027 // CONSTRUCTOR
9028 //
9029 //=================================================================================================
9030 
9031 //*************************************************************************************************
9045 template< typename MT > // Type of the dense matrix
9046 inline DenseSubmatrix<MT,aligned,true>::DenseSubmatrix( Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n )
9047  : matrix_( matrix ) // The dense matrix containing the submatrix
9048  , row_ ( rindex ) // The first row of the submatrix
9049  , column_( cindex ) // The first column of the submatrix
9050  , m_ ( m ) // The number of rows of the submatrix
9051  , n_ ( n ) // The number of columns of the submatrix
9052 {
9053  if( ( row_ + m_ > matrix_.rows() ) || ( column_ + n_ > matrix_.columns() ) ) {
9054  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
9055  }
9056 
9057  if( ( vectorizable && matrix_.data() != NULL && !checkAlignment( data() ) ) ||
9058  ( n_ > 1UL && matrix_.spacing() % IT::size != 0UL ) ) {
9059  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix alignment" );
9060  }
9061 }
9063 //*************************************************************************************************
9064 
9065 
9066 
9067 
9068 //=================================================================================================
9069 //
9070 // DATA ACCESS FUNCTIONS
9071 //
9072 //=================================================================================================
9073 
9074 //*************************************************************************************************
9085 template< typename MT > // Type of the dense matrix
9087  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j )
9088 {
9089  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
9090  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
9091 
9092  return matrix_(row_+i,column_+j);
9093 }
9095 //*************************************************************************************************
9096 
9097 
9098 //*************************************************************************************************
9109 template< typename MT > // Type of the dense matrix
9111  DenseSubmatrix<MT,aligned,true>::operator()( size_t i, size_t j ) const
9112 {
9113  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
9114  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
9115 
9116  return const_cast<const MT&>( matrix_ )(row_+i,column_+j);
9117 }
9119 //*************************************************************************************************
9120 
9121 
9122 //*************************************************************************************************
9134 template< typename MT > // Type of the dense matrix
9136  DenseSubmatrix<MT,aligned,true>::at( size_t i, size_t j )
9137 {
9138  if( i >= rows() ) {
9139  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
9140  }
9141  if( j >= columns() ) {
9142  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
9143  }
9144  return (*this)(i,j);
9145 }
9147 //*************************************************************************************************
9148 
9149 
9150 //*************************************************************************************************
9162 template< typename MT > // Type of the dense matrix
9164  DenseSubmatrix<MT,aligned,true>::at( size_t i, size_t j ) const
9165 {
9166  if( i >= rows() ) {
9167  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
9168  }
9169  if( j >= columns() ) {
9170  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
9171  }
9172  return (*this)(i,j);
9173 }
9175 //*************************************************************************************************
9176 
9177 
9178 //*************************************************************************************************
9188 template< typename MT > // Type of the dense matrix
9189 inline typename DenseSubmatrix<MT,aligned,true>::Pointer
9191 {
9192  return matrix_.data() + row_ + column_*spacing();
9193 }
9195 //*************************************************************************************************
9196 
9197 
9198 //*************************************************************************************************
9208 template< typename MT > // Type of the dense matrix
9209 inline typename DenseSubmatrix<MT,aligned,true>::ConstPointer
9211 {
9212  return matrix_.data() + row_ + column_*spacing();
9213 }
9215 //*************************************************************************************************
9216 
9217 
9218 //*************************************************************************************************
9227 template< typename MT > // Type of the dense matrix
9228 inline typename DenseSubmatrix<MT,aligned,true>::Pointer
9230 {
9231  return matrix_.data() + row_ + (column_+j)*spacing();
9232 }
9234 //*************************************************************************************************
9235 
9236 
9237 //*************************************************************************************************
9246 template< typename MT > // Type of the dense matrix
9247 inline typename DenseSubmatrix<MT,aligned,true>::ConstPointer
9248  DenseSubmatrix<MT,aligned,true>::data( size_t j ) const
9249 {
9250  return matrix_.data() + row_ + (column_+j)*spacing();
9251 }
9253 //*************************************************************************************************
9254 
9255 
9256 //*************************************************************************************************
9263 template< typename MT > // Type of the dense matrix
9266 {
9267  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
9268  return ( matrix_.begin( column_ + j ) + row_ );
9269 }
9271 //*************************************************************************************************
9272 
9273 
9274 //*************************************************************************************************
9281 template< typename MT > // Type of the dense matrix
9283  DenseSubmatrix<MT,aligned,true>::begin( size_t j ) const
9284 {
9285  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
9286  return ( matrix_.cbegin( column_ + j ) + row_ );
9287 }
9289 //*************************************************************************************************
9290 
9291 
9292 //*************************************************************************************************
9299 template< typename MT > // Type of the dense matrix
9301  DenseSubmatrix<MT,aligned,true>::cbegin( size_t j ) const
9302 {
9303  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
9304  return ( matrix_.cbegin( column_ + j ) + row_ );
9305 }
9307 //*************************************************************************************************
9308 
9309 
9310 //*************************************************************************************************
9317 template< typename MT > // Type of the dense matrix
9320 {
9321  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
9322  return ( matrix_.begin( column_ + j ) + row_ + m_ );
9323 }
9325 //*************************************************************************************************
9326 
9327 
9328 //*************************************************************************************************
9335 template< typename MT > // Type of the dense matrix
9337  DenseSubmatrix<MT,aligned,true>::end( size_t j ) const
9338 {
9339  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
9340  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
9341 }
9343 //*************************************************************************************************
9344 
9345 
9346 //*************************************************************************************************
9353 template< typename MT > // Type of the dense matrix
9355  DenseSubmatrix<MT,aligned,true>::cend( size_t j ) const
9356 {
9357  BLAZE_USER_ASSERT( j < columns(), "Invalid dense submatrix column access index" );
9358  return ( matrix_.cbegin( column_ + j ) + row_ + m_ );
9359 }
9361 //*************************************************************************************************
9362 
9363 
9364 
9365 
9366 //=================================================================================================
9367 //
9368 // ASSIGNMENT OPERATORS
9369 //
9370 //=================================================================================================
9371 
9372 //*************************************************************************************************
9383 template< typename MT > // Type of the dense matrix
9384 inline DenseSubmatrix<MT,aligned,true>&
9385  DenseSubmatrix<MT,aligned,true>::operator=( const ElementType& rhs )
9386 {
9387  const size_t jend( column_ + n_ );
9388 
9389  for( size_t j=column_; j<jend; ++j )
9390  {
9391  const size_t ibegin( ( IsLower<MT>::value )
9392  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
9393  ?( max( j+1UL, row_ ) )
9394  :( max( j, row_ ) ) )
9395  :( row_ ) );
9396  const size_t iend ( ( IsUpper<MT>::value )
9397  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
9398  ?( min( j, row_+m_ ) )
9399  :( min( j+1UL, row_+m_ ) ) )
9400  :( row_+m_ ) );
9401 
9402  for( size_t i=ibegin; i<iend; ++i )
9403  matrix_(i,j) = rhs;
9404  }
9405 
9406  return *this;
9407 }
9409 //*************************************************************************************************
9410 
9411 
9412 //*************************************************************************************************
9427 template< typename MT > // Type of the dense matrix
9428 inline DenseSubmatrix<MT,aligned,true>&
9429  DenseSubmatrix<MT,aligned,true>::operator=( const DenseSubmatrix& rhs )
9430 {
9433 
9434  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ && column_ == rhs.column_ ) )
9435  return *this;
9436 
9437  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
9438  BLAZE_THROW_INVALID_ARGUMENT( "Submatrix sizes do not match" );
9439  }
9440 
9441  if( !tryAssign( matrix_, rhs, row_, column_ ) ) {
9442  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
9443  }
9444 
9445  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
9446 
9447  if( rhs.canAlias( &matrix_ ) ) {
9448  const ResultType tmp( rhs );
9449  smpAssign( left, tmp );
9450  }
9451  else {
9452  smpAssign( left, rhs );
9453  }
9454 
9455  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
9456 
9457  return *this;
9458 }
9460 //*************************************************************************************************
9461 
9462 
9463 //*************************************************************************************************
9477 template< typename MT > // Type of the dense matrix
9478 template< typename MT2 // Type of the right-hand side matrix
9479  , bool SO > // Storage order of the right-hand side matrix
9480 inline DenseSubmatrix<MT,aligned,true>&
9481  DenseSubmatrix<MT,aligned,true>::operator=( const Matrix<MT2,SO>& rhs )
9482 {
9484 
9485  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
9486  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
9487  }
9488 
9489  typedef typename If< IsRestricted<MT>, typename MT2::CompositeType, const MT2& >::Type Right;
9490  Right right( ~rhs );
9491 
9492  if( !tryAssign( matrix_, right, row_, column_ ) ) {
9493  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
9494  }
9495 
9496  if( IsSparseMatrix<MT2>::value )
9497  reset();
9498 
9499  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
9500 
9501  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
9502  const typename MT2::ResultType tmp( right );
9503  smpAssign( left, tmp );
9504  }
9505  else {
9506  smpAssign( left, right );
9507  }
9508 
9509  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
9510 
9511  return *this;
9512 }
9514 //*************************************************************************************************
9515 
9516 
9517 //*************************************************************************************************
9531 template< typename MT > // Type of the dense matrix
9532 template< typename MT2 // Type of the right-hand side matrix
9533  , bool SO > // Storage order of the right-hand side matrix
9534 inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
9535  , DenseSubmatrix<MT,aligned,true>& >::Type
9536  DenseSubmatrix<MT,aligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
9537 {
9541 
9542  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
9543 
9546 
9547  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
9548  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
9549  }
9550 
9551  if( !tryAddAssign( matrix_, ~rhs, row_, column_ ) ) {
9552  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
9553  }
9554 
9555  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
9556 
9557  if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
9558  (~rhs).canAlias( &matrix_ ) ) {
9559  const AddType tmp( *this + (~rhs) );
9560  smpAssign( left, tmp );
9561  }
9562  else {
9563  smpAddAssign( left, ~rhs );
9564  }
9565 
9566  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
9567 
9568  return *this;
9569 }
9571 //*************************************************************************************************
9572 
9573 
9574 //*************************************************************************************************
9588 template< typename MT > // Type of the dense matrix
9589 template< typename MT2 // Type of the right-hand side matrix
9590  , bool SO > // Storage order of the right-hand side matrix
9591 inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
9592  , DenseSubmatrix<MT,aligned,true>& >::Type
9593  DenseSubmatrix<MT,aligned,true>::operator+=( const Matrix<MT2,SO>& rhs )
9594 {
9598 
9599  typedef typename AddTrait<ResultType,typename MT2::ResultType>::Type AddType;
9600 
9603 
9604  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
9605  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
9606  }
9607 
9608  const AddType tmp( *this + (~rhs) );
9609 
9610  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
9611  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
9612  }
9613 
9614  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
9615 
9616  smpAssign( left, tmp );
9617 
9618  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
9619 
9620  return *this;
9621 }
9623 //*************************************************************************************************
9624 
9625 
9626 //*************************************************************************************************
9640 template< typename MT > // Type of the dense matrix
9641 template< typename MT2 // Type of the right-hand side matrix
9642  , bool SO > // Storage order of the right-hand side matrix
9643 inline typename DisableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
9644  , DenseSubmatrix<MT,aligned,true>& >::Type
9645  DenseSubmatrix<MT,aligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
9646 {
9650 
9651  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
9652 
9655 
9656  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
9657  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
9658  }
9659 
9660  if( !trySubAssign( matrix_, ~rhs, row_, column_ ) ) {
9661  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
9662  }
9663 
9664  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
9665 
9666  if( ( ( IsSymmetric<MT>::value || IsHermitian<MT>::value ) && hasOverlap() ) ||
9667  (~rhs).canAlias( &matrix_ ) ) {
9668  const SubType tmp( *this - (~rhs ) );
9669  smpAssign( left, tmp );
9670  }
9671  else {
9672  smpSubAssign( left, ~rhs );
9673  }
9674 
9675  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
9676 
9677  return *this;
9678 }
9680 //*************************************************************************************************
9681 
9682 
9683 //*************************************************************************************************
9697 template< typename MT > // Type of the dense matrix
9698 template< typename MT2 // Type of the right-hand side matrix
9699  , bool SO > // Storage order of the right-hand side matrix
9700 inline typename EnableIf< And< IsRestricted<MT>, RequiresEvaluation<MT2> >
9701  , DenseSubmatrix<MT,aligned,true>& >::Type
9702  DenseSubmatrix<MT,aligned,true>::operator-=( const Matrix<MT2,SO>& rhs )
9703 {
9707 
9708  typedef typename SubTrait<ResultType,typename MT2::ResultType>::Type SubType;
9709 
9712 
9713  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
9714  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
9715  }
9716 
9717  const SubType tmp( *this - (~rhs) );
9718 
9719  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
9720  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
9721  }
9722 
9723  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
9724 
9725  smpAssign( left, tmp );
9726 
9727  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
9728 
9729  return *this;
9730 }
9732 //*************************************************************************************************
9733 
9734 
9735 //*************************************************************************************************
9749 template< typename MT > // Type of the dense matrix
9750 template< typename MT2 // Type of the right-hand side matrix
9751  , bool SO > // Storage order of the right-hand side matrix
9752 inline DenseSubmatrix<MT,aligned,true>&
9753  DenseSubmatrix<MT,aligned,true>::operator*=( const Matrix<MT2,SO>& rhs )
9754 {
9758 
9759  typedef typename MultTrait<ResultType,typename MT2::ResultType>::Type MultType;
9760 
9763 
9764  if( columns() != (~rhs).rows() ) {
9765  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
9766  }
9767 
9768  const MultType tmp( *this * (~rhs) );
9769 
9770  if( !tryAssign( matrix_, tmp, row_, column_ ) ) {
9771  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
9772  }
9773 
9774  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
9775 
9776  smpAssign( left, tmp );
9777 
9778  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
9779 
9780  return *this;
9781 }
9783 //*************************************************************************************************
9784 
9785 
9786 //*************************************************************************************************
9797 template< typename MT > // Type of the dense matrix
9798 template< typename Other > // Data type of the right-hand side scalar
9799 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
9800  DenseSubmatrix<MT,aligned,true>::operator*=( Other rhs )
9801 {
9803 
9804  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
9805  smpAssign( left, (*this) * rhs );
9806 
9807  return *this;
9808 }
9810 //*************************************************************************************************
9811 
9812 
9813 //*************************************************************************************************
9826 template< typename MT > // Type of the dense matrix
9827 template< typename Other > // Data type of the right-hand side scalar
9828 inline typename EnableIf< IsNumeric<Other>, DenseSubmatrix<MT,aligned,true> >::Type&
9829  DenseSubmatrix<MT,aligned,true>::operator/=( Other rhs )
9830 {
9832 
9833  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
9834 
9835  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
9836  smpAssign( left, (*this) / rhs );
9837 
9838  return *this;
9839 }
9841 //*************************************************************************************************
9842 
9843 
9844 
9845 
9846 //=================================================================================================
9847 //
9848 // UTILITY FUNCTIONS
9849 //
9850 //=================================================================================================
9851 
9852 //*************************************************************************************************
9858 template< typename MT > // Type of the dense matrix
9859 inline size_t DenseSubmatrix<MT,aligned,true>::row() const
9860 {
9861  return row_;
9862 }
9864 //*************************************************************************************************
9865 
9866 
9867 //*************************************************************************************************
9873 template< typename MT > // Type of the dense matrix
9874 inline size_t DenseSubmatrix<MT,aligned,true>::rows() const
9875 {
9876  return m_;
9877 }
9879 //*************************************************************************************************
9880 
9881 
9882 //*************************************************************************************************
9888 template< typename MT > // Type of the dense matrix
9889 inline size_t DenseSubmatrix<MT,aligned,true>::column() const
9890 {
9891  return column_;
9892 }
9894 //*************************************************************************************************
9895 
9896 
9897 //*************************************************************************************************
9903 template< typename MT > // Type of the dense matrix
9904 inline size_t DenseSubmatrix<MT,aligned,true>::columns() const
9905 {
9906  return n_;
9907 }
9909 //*************************************************************************************************
9910 
9911 
9912 //*************************************************************************************************
9921 template< typename MT > // Type of the dense matrix
9922 inline size_t DenseSubmatrix<MT,aligned,true>::spacing() const
9923 {
9924  return matrix_.spacing();
9925 }
9927 //*************************************************************************************************
9928 
9929 
9930 //*************************************************************************************************
9936 template< typename MT > // Type of the dense matrix
9937 inline size_t DenseSubmatrix<MT,aligned,true>::capacity() const
9938 {
9939  return rows() * columns();
9940 }
9942 //*************************************************************************************************
9943 
9944 
9945 //*************************************************************************************************
9952 template< typename MT > // Type of the dense matrix
9953 inline size_t DenseSubmatrix<MT,aligned,true>::capacity( size_t j ) const
9954 {
9955  UNUSED_PARAMETER( j );
9956 
9957  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
9958 
9959  return rows();
9960 }
9962 //*************************************************************************************************
9963 
9964 
9965 //*************************************************************************************************
9971 template< typename MT > // Type of the dense matrix
9972 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros() const
9973 {
9974  const size_t iend( row_ + m_ );
9975  const size_t jend( column_ + n_ );
9976  size_t nonzeros( 0UL );
9977 
9978  for( size_t j=column_; j<jend; ++j )
9979  for( size_t i=row_; i<iend; ++i )
9980  if( !isDefault( matrix_(i,j) ) )
9981  ++nonzeros;
9982 
9983  return nonzeros;
9984 }
9986 //*************************************************************************************************
9987 
9988 
9989 //*************************************************************************************************
9996 template< typename MT > // Type of the dense matrix
9997 inline size_t DenseSubmatrix<MT,aligned,true>::nonZeros( size_t j ) const
9998 {
9999  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
10000 
10001  const size_t iend( row_ + m_ );
10002  size_t nonzeros( 0UL );
10003 
10004  for( size_t i=row_; i<iend; ++i )
10005  if( !isDefault( matrix_(i,column_+j) ) )
10006  ++nonzeros;
10007 
10008  return nonzeros;
10009 }
10011 //*************************************************************************************************
10012 
10013 
10014 //*************************************************************************************************
10020 template< typename MT > // Type of the dense matrix
10022 {
10023  using blaze::clear;
10024 
10025  for( size_t j=column_; j<column_+n_; ++j )
10026  {
10027  const size_t ibegin( ( IsLower<MT>::value )
10028  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
10029  ?( max( j+1UL, row_ ) )
10030  :( max( j, row_ ) ) )
10031  :( row_ ) );
10032  const size_t iend ( ( IsUpper<MT>::value )
10033  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
10034  ?( min( j, row_+m_ ) )
10035  :( min( j+1UL, row_+m_ ) ) )
10036  :( row_+m_ ) );
10037 
10038  for( size_t i=ibegin; i<iend; ++i )
10039  clear( matrix_(i,j) );
10040  }
10041 }
10043 //*************************************************************************************************
10044 
10045 
10046 //*************************************************************************************************
10053 template< typename MT > // Type of the dense matrix
10054 inline void DenseSubmatrix<MT,aligned,true>::reset( size_t j )
10055 {
10056  using blaze::clear;
10057 
10058  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
10059 
10060  const size_t ibegin( ( IsLower<MT>::value )
10061  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
10062  ?( max( j+1UL, row_ ) )
10063  :( max( j, row_ ) ) )
10064  :( row_ ) );
10065  const size_t iend ( ( IsUpper<MT>::value )
10066  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
10067  ?( min( j, row_+m_ ) )
10068  :( min( j+1UL, row_+m_ ) ) )
10069  :( row_+m_ ) );
10070 
10071  for( size_t i=ibegin; i<iend; ++i )
10072  clear( matrix_(i,column_+j) );
10073 }
10075 //*************************************************************************************************
10076 
10077 
10078 //*************************************************************************************************
10096 template< typename MT > // Type of the dense matrix
10097 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::transpose()
10098 {
10099  if( m_ != n_ ) {
10100  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
10101  }
10102 
10103  if( !tryAssign( matrix_, trans( *this ), row_, column_ ) ) {
10104  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
10105  }
10106 
10107  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
10108  const ResultType tmp( trans( *this ) );
10109  smpAssign( left, tmp );
10110 
10111  return *this;
10112 }
10114 //*************************************************************************************************
10115 
10116 
10117 //*************************************************************************************************
10135 template< typename MT > // Type of the dense matrix
10136 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::ctranspose()
10137 {
10138  if( m_ != n_ ) {
10139  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic submatrix" );
10140  }
10141 
10142  if( !tryAssign( matrix_, ctrans( *this ), row_, column_ ) ) {
10143  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
10144  }
10145 
10146  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
10147  const ResultType tmp( ctrans( *this ) );
10148  smpAssign( left, tmp );
10149 
10150  return *this;
10151 }
10153 //*************************************************************************************************
10154 
10155 
10156 //*************************************************************************************************
10167 template< typename MT > // Type of the dense matrix
10168 template< typename Other > // Data type of the scalar value
10169 inline DenseSubmatrix<MT,aligned,true>& DenseSubmatrix<MT,aligned,true>::scale( const Other& scalar )
10170 {
10172 
10173  const size_t jend( column_ + n_ );
10174 
10175  for( size_t j=column_; j<jend; ++j )
10176  {
10177  const size_t ibegin( ( IsLower<MT>::value )
10178  ?( ( IsStrictlyLower<MT>::value )
10179  ?( max( j+1UL, row_ ) )
10180  :( max( j, row_ ) ) )
10181  :( row_ ) );
10182  const size_t iend ( ( IsUpper<MT>::value )
10183  ?( ( IsStrictlyUpper<MT>::value )
10184  ?( min( j, row_+m_ ) )
10185  :( min( j+1UL, row_+m_ ) ) )
10186  :( row_+m_ ) );
10187 
10188  for( size_t i=ibegin; i<iend; ++i )
10189  matrix_(i,j) *= scalar;
10190  }
10191 
10192  return *this;
10193 }
10195 //*************************************************************************************************
10196 
10197 
10198 //*************************************************************************************************
10208 template< typename MT > // Type of the dense matrix
10210 {
10211  BLAZE_INTERNAL_ASSERT( IsSymmetric<MT>::value || IsHermitian<MT>::value, "Invalid matrix detected" );
10212 
10213  if( ( row_ + m_ <= column_ ) || ( column_ + n_ <= row_ ) )
10214  return false;
10215  else return true;
10216 }
10218 //*************************************************************************************************
10219 
10220 
10221 
10222 
10223 //=================================================================================================
10224 //
10225 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
10226 //
10227 //=================================================================================================
10228 
10229 //*************************************************************************************************
10240 template< typename MT > // Type of the dense matrix
10241 template< typename Other > // Data type of the foreign expression
10242 inline bool DenseSubmatrix<MT,aligned,true>::canAlias( const Other* alias ) const
10243 {
10244  return matrix_.isAliased( alias );
10245 }
10247 //*************************************************************************************************
10248 
10249 
10250 //*************************************************************************************************
10261 template< typename MT > // Type of the dense matrix
10262 template< typename MT2 // Data type of the foreign dense submatrix
10263  , bool AF2 // Alignment flag of the foreign dense submatrix
10264  , bool SO2 > // Storage order of the foreign dense submatrix
10265 inline bool DenseSubmatrix<MT,aligned,true>::canAlias( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
10266 {
10267  return ( matrix_.isAliased( &alias->matrix_ ) &&
10268  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
10269  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
10270 }
10272 //*************************************************************************************************
10273 
10274 
10275 //*************************************************************************************************
10286 template< typename MT > // Type of the dense matrix
10287 template< typename Other > // Data type of the foreign expression
10288 inline bool DenseSubmatrix<MT,aligned,true>::isAliased( const Other* alias ) const
10289 {
10290  return matrix_.isAliased( alias );
10291 }
10293 //*************************************************************************************************
10294 
10295 
10296 //*************************************************************************************************
10307 template< typename MT > // Type of the dense matrix
10308 template< typename MT2 // Data type of the foreign dense submatrix
10309  , bool AF2 // Alignment flag of the foreign dense submatrix
10310  , bool SO2 > // Storage order of the foreign dense submatrix
10311 inline bool DenseSubmatrix<MT,aligned,true>::isAliased( const DenseSubmatrix<MT2,AF2,SO2>* alias ) const
10312 {
10313  return ( matrix_.isAliased( &alias->matrix_ ) &&
10314  ( row_ + m_ > alias->row_ ) && ( row_ < alias->row_ + alias->m_ ) &&
10315  ( column_ + n_ > alias->column_ ) && ( column_ < alias->column_ + alias->n_ ) );
10316 }
10318 //*************************************************************************************************
10319 
10320 
10321 //*************************************************************************************************
10331 template< typename MT > // Type of the dense matrix
10333 {
10334  return true;
10335 }
10337 //*************************************************************************************************
10338 
10339 
10340 //*************************************************************************************************
10351 template< typename MT > // Type of the dense matrix
10353 {
10354  return ( columns() > SMP_DMATASSIGN_THRESHOLD );
10355 }
10357 //*************************************************************************************************
10358 
10359 
10360 //*************************************************************************************************
10375 template< typename MT > // Type of the dense matrix
10376 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
10377  DenseSubmatrix<MT,aligned,true>::load( size_t i, size_t j ) const
10378 {
10379  return loada( i, j );
10380 }
10382 //*************************************************************************************************
10383 
10384 
10385 //*************************************************************************************************
10401 template< typename MT > // Type of the dense matrix
10402 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
10403  DenseSubmatrix<MT,aligned,true>::loada( size_t i, size_t j ) const
10404 {
10406 
10407  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
10408  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
10409  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
10410  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
10411 
10412  return matrix_.loada( row_+i, column_+j );
10413 }
10415 //*************************************************************************************************
10416 
10417 
10418 //*************************************************************************************************
10434 template< typename MT > // Type of the dense matrix
10435 BLAZE_ALWAYS_INLINE typename DenseSubmatrix<MT,aligned,true>::IntrinsicType
10436  DenseSubmatrix<MT,aligned,true>::loadu( size_t i, size_t j ) const
10437 {
10439 
10440  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
10441  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
10442  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
10443  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
10444 
10445  return matrix_.loadu( row_+i, column_+j );
10446 }
10448 //*************************************************************************************************
10449 
10450 
10451 //*************************************************************************************************
10467 template< typename MT > // Type of the dense matrix
10469  DenseSubmatrix<MT,aligned,true>::store( size_t i, size_t j, const IntrinsicType& value )
10470 {
10471  storea( i, j, value );
10472 }
10474 //*************************************************************************************************
10475 
10476 
10477 //*************************************************************************************************
10493 template< typename MT > // Type of the dense matrix
10495  DenseSubmatrix<MT,aligned,true>::storea( size_t i, size_t j, const IntrinsicType& value )
10496 {
10498 
10499  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
10500  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
10501  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
10502  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
10503 
10504  matrix_.storea( row_+i, column_+j, value );
10505 }
10507 //*************************************************************************************************
10508 
10509 
10510 //*************************************************************************************************
10527 template< typename MT > // Type of the dense matrix
10529  DenseSubmatrix<MT,aligned,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
10530 {
10532 
10533  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
10534  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
10535  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
10536  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
10537 
10538  matrix_.storeu( row_+i, column_+j, value );
10539 }
10541 //*************************************************************************************************
10542 
10543 
10544 //*************************************************************************************************
10561 template< typename MT > // Type of the dense matrix
10563  DenseSubmatrix<MT,aligned,true>::stream( size_t i, size_t j, const IntrinsicType& value )
10564 {
10566 
10567  BLAZE_INTERNAL_ASSERT( i < rows(), "Invalid row access index" );
10568  BLAZE_INTERNAL_ASSERT( i + IT::size <= rows(), "Invalid row access index" );
10569  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
10570  BLAZE_INTERNAL_ASSERT( j < columns(), "Invalid column access index" );
10571 
10572  matrix_.stream( row_+i, column_+j, value );
10573 }
10575 //*************************************************************************************************
10576 
10577 
10578 //*************************************************************************************************
10590 template< typename MT > // Type of the dense matrix
10591 template< typename MT2 > // Type of the right-hand side dense matrix
10592 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
10593  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
10594 {
10595  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10596  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10597 
10598  const size_t ipos( m_ & size_t(-2) );
10599  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
10600 
10601  for( size_t j=0UL; j<n_; ++j ) {
10602  for( size_t i=0UL; i<ipos; i+=2UL ) {
10603  matrix_(row_+i ,column_+j) = (~rhs)(i ,j);
10604  matrix_(row_+i+1UL,column_+j) = (~rhs)(i+1UL,j);
10605  }
10606  if( ipos < m_ ) {
10607  matrix_(row_+ipos,column_+j) = (~rhs)(ipos,j);
10608  }
10609  }
10610 }
10612 //*************************************************************************************************
10613 
10614 
10615 //*************************************************************************************************
10627 template< typename MT > // Type of the dense matrix
10628 template< typename MT2 > // Type of the right-hand side dense matrix
10629 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAssign<MT2> >::Type
10630  DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,true>& rhs )
10631 {
10633 
10634  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10635  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10636 
10637  const size_t ipos( m_ & size_t(-IT::size) );
10638  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size) ) ) == ipos, "Invalid end calculation" );
10639 
10640  if( useStreaming &&
10641  m_*n_ > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
10642  !(~rhs).isAliased( &matrix_ ) )
10643  {
10644  for( size_t j=0UL; j<n_; ++j )
10645  {
10646  size_t i( 0UL );
10647 
10648  for( ; i<ipos; i+=IT::size ) {
10649  stream( i, j, (~rhs).load(i,j) );
10650  }
10651  for( ; i<m_; ++i ) {
10652  matrix_(row_+i,column_+j) = (~rhs)(i,j);
10653  }
10654  }
10655  }
10656  else
10657  {
10658  for( size_t j=0UL; j<n_; ++j )
10659  {
10660  size_t i( 0UL );
10661  typename MT2::ConstIterator it( (~rhs).begin(j) );
10662 
10663  for( ; (i+IT::size*3UL) < ipos; i+=IT::size*4UL ) {
10664  store( i , j, it.load() ); it += IT::size;
10665  store( i+IT::size , j, it.load() ); it += IT::size;
10666  store( i+IT::size*2UL, j, it.load() ); it += IT::size;
10667  store( i+IT::size*3UL, j, it.load() ); it += IT::size;
10668  }
10669  for( ; i<ipos; i+=IT::size, it+=IT::size ) {
10670  store( i, j, it.load() );
10671  }
10672  for( ; i<m_; ++i, ++it ) {
10673  matrix_(row_+i,column_+j) = (~rhs)(i,j);
10674  }
10675  }
10676  }
10677 }
10679 //*************************************************************************************************
10680 
10681 
10682 //*************************************************************************************************
10694 template< typename MT > // Type of the dense matrix
10695 template< typename MT2 > // Type of the right-hand side dense matrix
10696 inline void DenseSubmatrix<MT,aligned,true>::assign( const DenseMatrix<MT2,false>& rhs )
10697 {
10699 
10700  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10701  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10702 
10703  const size_t block( BLOCK_SIZE );
10704 
10705  for( size_t jj=0UL; jj<n_; jj+=block ) {
10706  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
10707  for( size_t ii=0UL; ii<m_; ii+=block ) {
10708  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
10709  for( size_t j=jj; j<jend; ++j ) {
10710  for( size_t i=ii; i<iend; ++i ) {
10711  matrix_(row_+i,column_+j) = (~rhs)(i,j);
10712  }
10713  }
10714  }
10715  }
10716 }
10718 //*************************************************************************************************
10719 
10720 
10721 //*************************************************************************************************
10733 template< typename MT > // Type of the dense matrix
10734 template< typename MT2 > // Type of the right-hand side sparse matrix
10735 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,true>& rhs )
10736 {
10737  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10738  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10739 
10740  for( size_t j=0UL; j<n_; ++j )
10741  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
10742  matrix_(row_+element->index(),column_+j) = element->value();
10743 }
10745 //*************************************************************************************************
10746 
10747 
10748 //*************************************************************************************************
10760 template< typename MT > // Type of the dense matrix
10761 template< typename MT2 > // Type of the right-hand side sparse matrix
10762 inline void DenseSubmatrix<MT,aligned,true>::assign( const SparseMatrix<MT2,false>& rhs )
10763 {
10765 
10766  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10767  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10768 
10769  for( size_t i=0UL; i<m_; ++i )
10770  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
10771  matrix_(row_+i,column_+element->index()) = element->value();
10772 }
10774 //*************************************************************************************************
10775 
10776 
10777 //*************************************************************************************************
10789 template< typename MT > // Type of the dense matrix
10790 template< typename MT2 > // Type of the right-hand side dense matrix
10791 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
10792  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
10793 {
10794  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10795  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10796 
10797  const size_t ipos( m_ & size_t(-2) );
10798  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
10799 
10800  for( size_t j=0UL; j<n_; ++j ) {
10801  for( size_t i=0UL; i<ipos; i+=2UL ) {
10802  matrix_(row_+i ,column_+j) += (~rhs)(i ,j);
10803  matrix_(row_+i+1UL,column_+j) += (~rhs)(i+1UL,j);
10804  }
10805  if( ipos < m_ ) {
10806  matrix_(row_+ipos,column_+j) += (~rhs)(ipos,j);
10807  }
10808  }
10809 }
10811 //*************************************************************************************************
10812 
10813 
10814 //*************************************************************************************************
10826 template< typename MT > // Type of the dense matrix
10827 template< typename MT2 > // Type of the right-hand side dense matrix
10828 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >::Type
10829  DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,true>& rhs )
10830 {
10832 
10833  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10834  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10835 
10836  for( size_t j=0UL; j<n_; ++j )
10837  {
10838  const size_t ibegin( ( IsLower<MT>::value )
10839  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
10840  :( 0UL ) );
10841  const size_t iend ( ( IsUpper<MT>::value )
10842  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
10843  :( m_ ) );
10844  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
10845 
10846  const size_t ipos( iend & size_t(-IT::size) );
10847  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (IT::size) ) ) == ipos, "Invalid end calculation" );
10848 
10849  size_t i( ibegin );
10850  typename MT2::ConstIterator it( (~rhs).begin(j) );
10851 
10852  for( ; (i+IT::size*3UL) < ipos; i+=IT::size*4UL ) {
10853  store( i , j, load(i ,j) + it.load() ); it += IT::size;
10854  store( i+IT::size , j, load(i+IT::size ,j) + it.load() ); it += IT::size;
10855  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) + it.load() ); it += IT::size;
10856  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) + it.load() ); it += IT::size;
10857  }
10858  for( ; i<ipos; i+=IT::size, it+=IT::size ) {
10859  store( i, j, load(i,j) + it.load() );
10860  }
10861  for( ; i<iend; ++i, ++it ) {
10862  matrix_(row_+i,column_+j) += *it;
10863  }
10864  }
10865 }
10867 //*************************************************************************************************
10868 
10869 
10870 //*************************************************************************************************
10882 template< typename MT > // Type of the dense matrix
10883 template< typename MT2 > // Type of the right-hand side dense matrix
10884 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const DenseMatrix<MT2,false>& rhs )
10885 {
10887 
10888  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10889  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10890 
10891  const size_t block( BLOCK_SIZE );
10892 
10893  for( size_t jj=0UL; jj<n_; jj+=block ) {
10894  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
10895  for( size_t ii=0UL; ii<m_; ii+=block ) {
10896  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
10897  for( size_t j=jj; j<jend; ++j ) {
10898  for( size_t i=ii; i<iend; ++i ) {
10899  matrix_(row_+i,column_+j) += (~rhs)(i,j);
10900  }
10901  }
10902  }
10903  }
10904 }
10906 //*************************************************************************************************
10907 
10908 
10909 //*************************************************************************************************
10921 template< typename MT > // Type of the dense matrix
10922 template< typename MT2 > // Type of the right-hand side sparse matrix
10923 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,true>& rhs )
10924 {
10925  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10926  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10927 
10928  for( size_t j=0UL; j<n_; ++j )
10929  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
10930  matrix_(row_+element->index(),column_+j) += element->value();
10931 }
10933 //*************************************************************************************************
10934 
10935 
10936 //*************************************************************************************************
10948 template< typename MT > // Type of the dense matrix
10949 template< typename MT2 > // Type of the right-hand side sparse matrix
10950 inline void DenseSubmatrix<MT,aligned,true>::addAssign( const SparseMatrix<MT2,false>& rhs )
10951 {
10953 
10954  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10955  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10956 
10957  for( size_t i=0UL; i<m_; ++i )
10958  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
10959  matrix_(row_+i,column_+element->index()) += element->value();
10960 }
10962 //*************************************************************************************************
10963 
10964 
10965 //*************************************************************************************************
10977 template< typename MT > // Type of the dense matrix
10978 template< typename MT2 > // Type of the right-hand side dense matrix
10979 inline typename DisableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
10980  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
10981 {
10982  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
10983  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
10984 
10985  const size_t ipos( m_ & size_t(-2) );
10986  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
10987 
10988  for( size_t j=0UL; j<n_; ++j ) {
10989  for( size_t i=0UL; i<ipos; i+=2UL ) {
10990  matrix_(row_+i ,column_+j) -= (~rhs)(i ,j);
10991  matrix_(row_+i+1UL,column_+j) -= (~rhs)(i+1UL,j);
10992  }
10993  if( ipos < m_ ) {
10994  matrix_(row_+ipos,column_+j) -= (~rhs)(ipos,j);
10995  }
10996  }
10997 }
10999 //*************************************************************************************************
11000 
11001 
11002 //*************************************************************************************************
11014 template< typename MT > // Type of the dense matrix
11015 template< typename MT2 > // Type of the right-hand side dense matrix
11016 inline typename EnableIf< typename DenseSubmatrix<MT,aligned,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >::Type
11017  DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,true>& rhs )
11018 {
11020 
11021  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
11022  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
11023 
11024  for( size_t j=0UL; j<n_; ++j )
11025  {
11026  const size_t ibegin( ( IsLower<MT>::value )
11027  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
11028  :( 0UL ) );
11029  const size_t iend ( ( IsUpper<MT>::value )
11030  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
11031  :( m_ ) );
11032  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
11033 
11034  const size_t ipos( iend & size_t(-IT::size) );
11035  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (IT::size) ) ) == ipos, "Invalid end calculation" );
11036 
11037  size_t i( ibegin );
11038  typename MT2::ConstIterator it( (~rhs).begin(j) );
11039 
11040  for( ; (i+IT::size*3UL) < ipos; i+=IT::size*4UL ) {
11041  store( i , j, load(i ,j) - it.load() ); it += IT::size;
11042  store( i+IT::size , j, load(i+IT::size ,j) - it.load() ); it += IT::size;
11043  store( i+IT::size*2UL, j, load(i+IT::size*2UL,j) - it.load() ); it += IT::size;
11044  store( i+IT::size*3UL, j, load(i+IT::size*3UL,j) - it.load() ); it += IT::size;
11045  }
11046  for( ; i<ipos; i+=IT::size, it+=IT::size ) {
11047  store( i, j, load(i,j) - it.load() );
11048  }
11049  for( ; i<iend; ++i, ++it ) {
11050  matrix_(row_+i,column_+j) -= *it;
11051  }
11052  }
11053 }
11055 //*************************************************************************************************
11056 
11057 
11058 //*************************************************************************************************
11070 template< typename MT > // Type of the dense matrix
11071 template< typename MT2 > // Type of the right-hand side dense matrix
11072 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const DenseMatrix<MT2,false>& rhs )
11073 {
11075 
11076  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
11077  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
11078 
11079  const size_t block( BLOCK_SIZE );
11080 
11081  for( size_t jj=0UL; jj<n_; jj+=block ) {
11082  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
11083  for( size_t ii=0UL; ii<m_; ii+=block ) {
11084  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
11085  for( size_t j=jj; j<jend; ++j ) {
11086  for( size_t i=ii; i<iend; ++i ) {
11087  matrix_(row_+i,column_+j) -= (~rhs)(i,j);
11088  }
11089  }
11090  }
11091  }
11092 }
11094 //*************************************************************************************************
11095 
11096 
11097 //*************************************************************************************************
11109 template< typename MT > // Type of the dense matrix
11110 template< typename MT2 > // Type of the right-hand side sparse matrix
11111 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,true>& rhs )
11112 {
11113  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
11114  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
11115 
11116  for( size_t j=0UL; j<n_; ++j )
11117  for( typename MT2::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
11118  matrix_(row_+element->index(),column_+j) -= element->value();
11119 }
11121 //*************************************************************************************************
11122 
11123 
11124 //*************************************************************************************************
11136 template< typename MT > // Type of the dense matrix
11137 template< typename MT2 > // Type of the right-hand side sparse matrix
11138 inline void DenseSubmatrix<MT,aligned,true>::subAssign( const SparseMatrix<MT2,false>& rhs )
11139 {
11141 
11142  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
11143  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
11144 
11145  for( size_t i=0UL; i<m_; ++i )
11146  for( typename MT2::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
11147  matrix_(row_+i,column_+element->index()) -= element->value();
11148 }
11150 //*************************************************************************************************
11151 
11152 
11153 
11154 
11155 
11156 
11157 
11158 
11159 //=================================================================================================
11160 //
11161 // DENSESUBMATRIX OPERATORS
11162 //
11163 //=================================================================================================
11164 
11165 //*************************************************************************************************
11168 template< typename MT, bool AF, bool SO >
11169 inline void reset( DenseSubmatrix<MT,AF,SO>& dm );
11170 
11171 template< typename MT, bool AF, bool SO >
11172 inline void reset( DenseSubmatrix<MT,AF,SO>& dm, size_t i );
11173 
11174 template< typename MT, bool AF, bool SO >
11175 inline void clear( DenseSubmatrix<MT,AF,SO>& dm );
11176 
11177 template< typename MT, bool AF, bool SO >
11178 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm );
11179 
11180 template< typename MT, bool AF, bool SO >
11181 inline bool isIntact( const DenseSubmatrix<MT,AF,SO>& dm );
11182 
11183 template< typename MT, bool AF, bool SO >
11184 inline bool isSymmetric( const DenseSubmatrix<MT,AF,SO>& dm );
11185 
11186 template< typename MT, bool AF, bool SO >
11187 inline bool isHermitian( const DenseSubmatrix<MT,AF,SO>& dm );
11188 
11189 template< typename MT, bool AF, bool SO >
11190 inline bool isLower( const DenseSubmatrix<MT,AF,SO>& dm );
11191 
11192 template< typename MT, bool AF, bool SO >
11193 inline bool isUniLower( const DenseSubmatrix<MT,AF,SO>& dm );
11194 
11195 template< typename MT, bool AF, bool SO >
11196 inline bool isStrictlyLower( const DenseSubmatrix<MT,AF,SO>& dm );
11197 
11198 template< typename MT, bool AF, bool SO >
11199 inline bool isUpper( const DenseSubmatrix<MT,AF,SO>& dm );
11200 
11201 template< typename MT, bool AF, bool SO >
11202 inline bool isUniUpper( const DenseSubmatrix<MT,AF,SO>& dm );
11203 
11204 template< typename MT, bool AF, bool SO >
11205 inline bool isStrictlyUpper( const DenseSubmatrix<MT,AF,SO>& dm );
11206 
11207 template< typename MT, bool AF, bool SO >
11208 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseMatrix<MT,SO>& b );
11209 
11210 template< typename MT, bool AF, bool SO >
11211 inline bool isSame( const DenseMatrix<MT,SO>& a, const DenseSubmatrix<MT,AF,SO>& b );
11212 
11213 template< typename MT, bool AF, bool SO >
11214 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseSubmatrix<MT,AF,SO>& b );
11216 //*************************************************************************************************
11217 
11218 
11219 //*************************************************************************************************
11226 template< typename MT // Type of the dense matrix
11227  , bool AF // Alignment flag
11228  , bool SO > // Storage order
11230 {
11231  dm.reset();
11232 }
11233 //*************************************************************************************************
11234 
11235 
11236 //*************************************************************************************************
11249 template< typename MT // Type of the dense matrix
11250  , bool AF // Alignment flag
11251  , bool SO > // Storage order
11252 inline void reset( DenseSubmatrix<MT,AF,SO>& dm, size_t i )
11253 {
11254  dm.reset( i );
11255 }
11256 //*************************************************************************************************
11257 
11258 
11259 //*************************************************************************************************
11268 template< typename MT // Type of the dense matrix
11269  , bool AF // Alignment flag
11270  , bool SO > // Storage order
11272 {
11273  dm.reset();
11274 }
11275 //*************************************************************************************************
11276 
11277 
11278 //*************************************************************************************************
11296 template< typename MT // Type of the dense matrix
11297  , bool AF // Alignment flag
11298  , bool SO > // Storage order
11299 inline bool isDefault( const DenseSubmatrix<MT,AF,SO>& dm )
11300 {
11301  using blaze::isDefault;
11302 
11303  if( SO == rowMajor ) {
11304  for( size_t i=0UL; i<(~dm).rows(); ++i )
11305  for( size_t j=0UL; j<(~dm).columns(); ++j )
11306  if( !isDefault( (~dm)(i,j) ) )
11307  return false;
11308  }
11309  else {
11310  for( size_t j=0UL; j<(~dm).columns(); ++j )
11311  for( size_t i=0UL; i<(~dm).rows(); ++i )
11312  if( !isDefault( (~dm)(i,j) ) )
11313  return false;
11314  }
11315 
11316  return true;
11317 }
11318 //*************************************************************************************************
11319 
11320 
11321 //*************************************************************************************************
11339 template< typename MT // Type of the dense matrix
11340  , bool AF // Alignment flag
11341  , bool SO > // Storage order
11342 inline bool isIntact( const DenseSubmatrix<MT,AF,SO>& dm )
11343 {
11344  return ( dm.row_ + dm.m_ <= dm.matrix_.rows() &&
11345  dm.column_ + dm.n_ <= dm.matrix_.columns() &&
11346  isIntact( dm.matrix_ ) );
11347 }
11348 //*************************************************************************************************
11349 
11350 
11351 //*************************************************************************************************
11373 template< typename MT // Type of the dense matrix
11374  , bool AF // Alignment flag
11375  , bool SO > // Storage order
11376 inline bool isSymmetric( const DenseSubmatrix<MT,AF,SO>& dm )
11377 {
11378  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
11379 
11380  if( IsSymmetric<MT>::value && dm.row() == dm.column() && dm.rows() == dm.columns() )
11381  return true;
11382  else return isSymmetric( static_cast<const BaseType&>( dm ) );
11383 }
11384 //*************************************************************************************************
11385 
11386 
11387 //*************************************************************************************************
11409 template< typename MT // Type of the dense matrix
11410  , bool AF // Alignment flag
11411  , bool SO > // Storage order
11412 inline bool isHermitian( const DenseSubmatrix<MT,AF,SO>& dm )
11413 {
11414  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
11415 
11416  if( IsHermitian<MT>::value && dm.row() == dm.column() && dm.rows() == dm.columns() )
11417  return true;
11418  else return isHermitian( static_cast<const BaseType&>( dm ) );
11419 }
11420 //*************************************************************************************************
11421 
11422 
11423 //*************************************************************************************************
11455 template< typename MT // Type of the dense matrix
11456  , bool AF // Alignment flag
11457  , bool SO > // Storage order
11458 inline bool isLower( const DenseSubmatrix<MT,AF,SO>& dm )
11459 {
11460  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
11461 
11462  if( IsLower<MT>::value && dm.row() == dm.column() && dm.rows() == dm.columns() )
11463  return true;
11464  else return isLower( static_cast<const BaseType&>( dm ) );
11465 }
11466 //*************************************************************************************************
11467 
11468 
11469 //*************************************************************************************************
11500 template< typename MT // Type of the dense matrix
11501  , bool AF // Alignment flag
11502  , bool SO > // Storage order
11503 inline bool isUniLower( const DenseSubmatrix<MT,AF,SO>& dm )
11504 {
11505  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
11506 
11507  if( IsUniLower<MT>::value && dm.row() == dm.column() && dm.rows() == dm.columns() )
11508  return true;
11509  else return isUniLower( static_cast<const BaseType&>( dm ) );
11510 }
11511 //*************************************************************************************************
11512 
11513 
11514 //*************************************************************************************************
11545 template< typename MT // Type of the dense matrix
11546  , bool AF // Alignment flag
11547  , bool SO > // Storage order
11549 {
11550  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
11551 
11552  if( IsStrictlyLower<MT>::value && dm.row() == dm.column() && dm.rows() == dm.columns() )
11553  return true;
11554  else return isStrictlyLower( static_cast<const BaseType&>( dm ) );
11555 }
11556 //*************************************************************************************************
11557 
11558 
11559 //*************************************************************************************************
11591 template< typename MT // Type of the dense matrix
11592  , bool AF // Alignment flag
11593  , bool SO > // Storage order
11594 inline bool isUpper( const DenseSubmatrix<MT,AF,SO>& dm )
11595 {
11596  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
11597 
11598  if( IsUpper<MT>::value && dm.row() == dm.column() && dm.rows() == dm.columns() )
11599  return true;
11600  else return isUpper( static_cast<const BaseType&>( dm ) );
11601 }
11602 //*************************************************************************************************
11603 
11604 
11605 //*************************************************************************************************
11636 template< typename MT // Type of the dense matrix
11637  , bool AF // Alignment flag
11638  , bool SO > // Storage order
11639 inline bool isUniUpper( const DenseSubmatrix<MT,AF,SO>& dm )
11640 {
11641  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
11642 
11643  if( IsUniUpper<MT>::value && dm.row() == dm.column() && dm.rows() == dm.columns() )
11644  return true;
11645  else return isUniUpper( static_cast<const BaseType&>( dm ) );
11646 }
11647 //*************************************************************************************************
11648 
11649 
11650 //*************************************************************************************************
11681 template< typename MT // Type of the dense matrix
11682  , bool AF // Alignment flag
11683  , bool SO > // Storage order
11685 {
11686  typedef DenseMatrix< DenseSubmatrix<MT,AF,SO>, SO > BaseType;
11687 
11688  if( IsStrictlyUpper<MT>::value && dm.row() == dm.column() && dm.rows() == dm.columns() )
11689  return true;
11690  else return isStrictlyUpper( static_cast<const BaseType&>( dm ) );
11691 }
11692 //*************************************************************************************************
11693 
11694 
11695 //*************************************************************************************************
11707 template< typename MT // Type of the dense matrix
11708  , bool AF // Alignment flag
11709  , bool SO > // Storage order
11710 inline bool isSame( const DenseSubmatrix<MT,AF,SO>& a, const DenseMatrix<MT,SO>& b )
11711 {
11712  return ( isSame( a.matrix_, ~b ) && ( a.rows() == (~b).rows() ) && ( a.columns() == (~b).columns() ) );
11713 }
11714 //*************************************************************************************************
11715 
11716 
11717 //*************************************************************************************************
11729 template< typename MT // Type of the dense matrix
11730  , bool AF // Alignment flag
11731  , bool SO > // Storage order
11732 inline bool isSame( const DenseMatrix<MT,SO>& a, const DenseSubmatrix<MT,AF,SO>& b )
11733 {
11734  return ( isSame( ~a, b.matrix_ ) && ( (~a).rows() == b.rows() ) && ( (~a).columns() == b.columns() ) );
11735 }
11736 //*************************************************************************************************
11737 
11738 
11739 //*************************************************************************************************
11751 template< typename MT // Type of the dense matrix
11752  , bool AF // Alignment flag
11753  , bool SO > // Storage order
11755 {
11756  return ( isSame( a.matrix_, b.matrix_ ) &&
11757  ( a.row_ == b.row_ ) && ( a.column_ == b.column_ ) &&
11758  ( a.m_ == b.m_ ) && ( a.n_ == b.n_ ) );
11759 }
11760 //*************************************************************************************************
11761 
11762 
11763 //*************************************************************************************************
11796 template< InversionFlag IF // Inversion algorithm
11797  , typename MT // Type of the dense matrix
11798  , bool AF // Alignment flag
11799  , bool SO > // Storage order
11800 inline typename DisableIf< HasMutableDataAccess<MT> >::Type
11801  invert( DenseSubmatrix<MT,AF,SO>& dm )
11802 {
11803  typedef typename DenseSubmatrix<MT,AF,SO>::ResultType RT;
11804 
11807 
11808  RT tmp( dm );
11809  invert<IF>( tmp );
11810  dm = tmp;
11811 }
11813 //*************************************************************************************************
11814 
11815 
11816 //*************************************************************************************************
11832 template< typename MT // Type of the dense matrix
11833  , bool AF // Alignment flag
11834  , bool SO // Storage order
11835  , typename VT // Type of the right-hand side vector
11836  , bool TF > // Transpose flag of the right-hand side vector
11837 inline bool tryAssign( const DenseSubmatrix<MT,AF,SO>& lhs, const Vector<VT,TF>& rhs,
11838  size_t row, size_t column )
11839 {
11840  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
11841  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
11842  BLAZE_INTERNAL_ASSERT( TF || ( (~rhs).size() <= lhs.rows() - row ), "Invalid number of rows" );
11843  BLAZE_INTERNAL_ASSERT( !TF || ( (~rhs).size() <= lhs.columns() - column ), "Invalid number of columns" );
11844 
11845  return tryAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
11846 }
11848 //*************************************************************************************************
11849 
11850 
11851 //*************************************************************************************************
11867 template< typename MT1 // Type of the dense matrix
11868  , bool AF // Alignment flag
11869  , bool SO1 // Storage order
11870  , typename MT2 // Type of the right-hand side matrix
11871  , bool SO2 > // Storage order of the right-hand side matrix
11872 inline bool tryAssign( const DenseSubmatrix<MT1,AF,SO1>& lhs, const Matrix<MT2,SO2>& rhs,
11873  size_t row, size_t column )
11874 {
11875  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
11876  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
11877  BLAZE_INTERNAL_ASSERT( (~rhs).rows() <= lhs.rows() - row, "Invalid number of rows" );
11878  BLAZE_INTERNAL_ASSERT( (~rhs).columns() <= lhs.columns() - column, "Invalid number of columns" );
11879 
11880  return tryAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
11881 }
11883 //*************************************************************************************************
11884 
11885 
11886 //*************************************************************************************************
11902 template< typename MT // Type of the dense matrix
11903  , bool AF // Alignment flag
11904  , bool SO // Storage order
11905  , typename VT // Type of the right-hand side vector
11906  , bool TF > // Transpose flag of the right-hand side vector
11907 inline bool tryAddAssign( const DenseSubmatrix<MT,AF,SO>& lhs, const Vector<VT,TF>& rhs,
11908  size_t row, size_t column )
11909 {
11910  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
11911  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
11912  BLAZE_INTERNAL_ASSERT( TF || ( (~rhs).size() <= lhs.rows() - row ), "Invalid number of rows" );
11913  BLAZE_INTERNAL_ASSERT( !TF || ( (~rhs).size() <= lhs.columns() - column ), "Invalid number of columns" );
11914 
11915  return tryAddAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
11916 }
11918 //*************************************************************************************************
11919 
11920 
11921 //*************************************************************************************************
11937 template< typename MT1 // Type of the dense matrix
11938  , bool AF // Alignment flag
11939  , bool SO1 // Storage order
11940  , typename MT2 // Type of the right-hand side matrix
11941  , bool SO2 > // Storage order of the right-hand side matrix
11942 inline bool tryAddAssign( const DenseSubmatrix<MT1,AF,SO1>& lhs, const Matrix<MT2,SO2>& rhs,
11943  size_t row, size_t column )
11944 {
11945  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
11946  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
11947  BLAZE_INTERNAL_ASSERT( (~rhs).rows() <= lhs.rows() - row, "Invalid number of rows" );
11948  BLAZE_INTERNAL_ASSERT( (~rhs).columns() <= lhs.columns() - column, "Invalid number of columns" );
11949 
11950  return tryAddAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
11951 }
11953 //*************************************************************************************************
11954 
11955 
11956 //*************************************************************************************************
11972 template< typename MT // Type of the dense matrix
11973  , bool AF // Alignment flag
11974  , bool SO // Storage order
11975  , typename VT // Type of the right-hand side vector
11976  , bool TF > // Transpose flag of the right-hand side vector
11977 inline bool trySubAssign( const DenseSubmatrix<MT,AF,SO>& lhs, const Vector<VT,TF>& rhs,
11978  size_t row, size_t column )
11979 {
11980  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
11981  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
11982  BLAZE_INTERNAL_ASSERT( TF || ( (~rhs).size() <= lhs.rows() - row ), "Invalid number of rows" );
11983  BLAZE_INTERNAL_ASSERT( !TF || ( (~rhs).size() <= lhs.columns() - column ), "Invalid number of columns" );
11984 
11985  return trySubAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
11986 }
11988 //*************************************************************************************************
11989 
11990 
11991 //*************************************************************************************************
12007 template< typename MT1 // Type of the dense matrix
12008  , bool AF // Alignment flag
12009  , bool SO1 // Storage order
12010  , typename MT2 // Type of the right-hand side matrix
12011  , bool SO2 > // Storage order of the right-hand side matrix
12012 inline bool trySubAssign( const DenseSubmatrix<MT1,AF,SO1>& lhs, const Matrix<MT2,SO2>& rhs,
12013  size_t row, size_t column )
12014 {
12015  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
12016  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
12017  BLAZE_INTERNAL_ASSERT( (~rhs).rows() <= lhs.rows() - row, "Invalid number of rows" );
12018  BLAZE_INTERNAL_ASSERT( (~rhs).columns() <= lhs.columns() - column, "Invalid number of columns" );
12019 
12020  return trySubAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
12021 }
12023 //*************************************************************************************************
12024 
12025 
12026 //*************************************************************************************************
12043 template< typename MT // Type of the dense matrix
12044  , bool AF // Alignment flag
12045  , bool SO // Storage order
12046  , typename VT // Type of the right-hand side vector
12047  , bool TF > // Transpose flag of the right-hand side vector
12048 inline bool tryMultAssign( const DenseSubmatrix<MT,AF,SO>& lhs, const Vector<VT,TF>& rhs,
12049  size_t row, size_t column )
12050 {
12051  BLAZE_INTERNAL_ASSERT( row <= lhs.rows(), "Invalid row access index" );
12052  BLAZE_INTERNAL_ASSERT( column <= lhs.columns(), "Invalid column access index" );
12053  BLAZE_INTERNAL_ASSERT( TF || ( (~rhs).size() <= lhs.rows() - row ), "Invalid number of rows" );
12054  BLAZE_INTERNAL_ASSERT( !TF || ( (~rhs).size() <= lhs.columns() - column ), "Invalid number of columns" );
12055 
12056  return tryMultAssign( lhs.matrix_, ~rhs, lhs.row_ + row, lhs.column_ + column );
12057 }
12059 //*************************************************************************************************
12060 
12061 
12062 //*************************************************************************************************
12077 template< typename MT // Type of the dense matrix
12078  , bool AF // Alignment flag
12079  , bool SO > // Storage order
12080 inline typename DerestrictTrait< DenseSubmatrix<MT,AF,SO> >::Type
12081  derestrict( DenseSubmatrix<MT,AF,SO>& dm )
12082 {
12083  typedef typename DerestrictTrait< DenseSubmatrix<MT,AF,SO> >::Type ReturnType;
12084  return ReturnType( derestrict( dm.matrix_ ), dm.row_, dm.column_, dm.m_, dm.n_ );
12085 }
12087 //*************************************************************************************************
12088 
12089 
12090 
12091 
12092 //=================================================================================================
12093 //
12094 // GLOBAL RESTRUCTURING OPERATORS
12095 //
12096 //=================================================================================================
12097 
12098 //*************************************************************************************************
12113 template< bool AF1 // Required alignment flag
12114  , typename MT // Type of the sparse submatrix
12115  , bool AF2 // Present alignment flag
12116  , bool SO > // Storage order
12117 inline const DenseSubmatrix<MT,AF1,SO>
12118  submatrix( const DenseSubmatrix<MT,AF2,SO>& dm, size_t row, size_t column, size_t m, size_t n )
12119 {
12121 
12122  if( ( row + m > dm.rows() ) || ( column + n > dm.columns() ) ) {
12123  BLAZE_THROW_INVALID_ARGUMENT( "Invalid submatrix specification" );
12124  }
12125 
12126  return DenseSubmatrix<MT,AF1,SO>( dm.matrix_, dm.row_ + row, dm.column_ + column, m, n );
12127 }
12129 //*************************************************************************************************
12130 
12131 
12132 
12133 
12134 //=================================================================================================
12135 //
12136 // ISRESTRICTED SPECIALIZATIONS
12137 //
12138 //=================================================================================================
12139 
12140 //*************************************************************************************************
12142 template< typename MT, bool AF, bool SO >
12143 struct IsRestricted< DenseSubmatrix<MT,AF,SO> > : public IsTrue< IsRestricted<MT>::value >
12144 {};
12146 //*************************************************************************************************
12147 
12148 
12149 
12150 
12151 //=================================================================================================
12152 //
12153 // DERESTRICTTRAIT SPECIALIZATIONS
12154 //
12155 //=================================================================================================
12156 
12157 //*************************************************************************************************
12159 template< typename MT, bool AF, bool SO >
12160 struct DerestrictTrait< DenseSubmatrix<MT,AF,SO> >
12161 {
12162  typedef DenseSubmatrix< typename RemoveReference< typename DerestrictTrait<MT>::Type >::Type, AF > Type;
12163 };
12165 //*************************************************************************************************
12166 
12167 
12168 
12169 
12170 //=================================================================================================
12171 //
12172 // HASCONSTDATAACCESS SPECIALIZATIONS
12173 //
12174 //=================================================================================================
12175 
12176 //*************************************************************************************************
12178 template< typename MT, bool AF, bool SO >
12179 struct HasConstDataAccess< DenseSubmatrix<MT,AF,SO> >
12180  : public IsTrue< HasConstDataAccess<MT>::value >
12181 {};
12183 //*************************************************************************************************
12184 
12185 
12186 
12187 
12188 //=================================================================================================
12189 //
12190 // HASMUTABLEDATAACCESS SPECIALIZATIONS
12191 //
12192 //=================================================================================================
12193 
12194 //*************************************************************************************************
12196 template< typename MT, bool AF, bool SO >
12197 struct HasMutableDataAccess< DenseSubmatrix<MT,AF,SO> >
12198  : public IsTrue< HasMutableDataAccess<MT>::value >
12199 {};
12201 //*************************************************************************************************
12202 
12203 
12204 
12205 
12206 //=================================================================================================
12207 //
12208 // ISALIGNED SPECIALIZATIONS
12209 //
12210 //=================================================================================================
12211 
12212 //*************************************************************************************************
12214 template< typename MT, bool SO >
12215 struct IsAligned< DenseSubmatrix<MT,aligned,SO> > : public IsTrue<true>
12216 {};
12218 //*************************************************************************************************
12219 
12220 
12221 
12222 
12223 //=================================================================================================
12224 //
12225 // ADDTRAIT SPECIALIZATIONS
12226 //
12227 //=================================================================================================
12228 
12229 //*************************************************************************************************
12231 template< typename MT, bool AF, bool SO, typename T >
12232 struct AddTrait< DenseSubmatrix<MT,AF,SO>, T >
12233 {
12234  typedef typename AddTrait< typename SubmatrixTrait<MT>::Type, T >::Type Type;
12235 };
12236 
12237 template< typename T, typename MT, bool AF, bool TF >
12238 struct AddTrait< T, DenseSubmatrix<MT,AF,TF> >
12239 {
12240  typedef typename AddTrait< T, typename SubmatrixTrait<MT>::Type >::Type Type;
12241 };
12243 //*************************************************************************************************
12244 
12245 
12246 
12247 
12248 //=================================================================================================
12249 //
12250 // SUBTRAIT SPECIALIZATIONS
12251 //
12252 //=================================================================================================
12253 
12254 //*************************************************************************************************
12256 template< typename MT, bool AF, bool SO, typename T >
12257 struct SubTrait< DenseSubmatrix<MT,AF,SO>, T >
12258 {
12259  typedef typename SubTrait< typename SubmatrixTrait<MT>::Type, T >::Type Type;
12260 };
12261 
12262 template< typename T, typename MT, bool AF, bool TF >
12263 struct SubTrait< T, DenseSubmatrix<MT,AF,TF> >
12264 {
12265  typedef typename SubTrait< T, typename SubmatrixTrait<MT>::Type >::Type Type;
12266 };
12268 //*************************************************************************************************
12269 
12270 
12271 
12272 
12273 //=================================================================================================
12274 //
12275 // MULTTRAIT SPECIALIZATIONS
12276 //
12277 //=================================================================================================
12278 
12279 //*************************************************************************************************
12281 template< typename MT, bool AF, bool SO, typename T >
12282 struct MultTrait< DenseSubmatrix<MT,AF,SO>, T >
12283 {
12284  typedef typename MultTrait< typename SubmatrixTrait<MT>::Type, T >::Type Type;
12285 };
12286 
12287 template< typename T, typename MT, bool AF, bool TF >
12288 struct MultTrait< T, DenseSubmatrix<MT,AF,TF> >
12289 {
12290  typedef typename MultTrait< T, typename SubmatrixTrait<MT>::Type >::Type Type;
12291 };
12293 //*************************************************************************************************
12294 
12295 
12296 
12297 
12298 //=================================================================================================
12299 //
12300 // DIVTRAIT SPECIALIZATIONS
12301 //
12302 //=================================================================================================
12303 
12304 //*************************************************************************************************
12306 template< typename MT, bool AF, bool SO, typename T >
12307 struct DivTrait< DenseSubmatrix<MT,AF,SO>, T >
12308 {
12309  typedef typename DivTrait< typename SubmatrixTrait<MT>::Type, T >::Type Type;
12310 };
12311 
12312 template< typename T, typename MT, bool AF, bool TF >
12313 struct DivTrait< T, DenseSubmatrix<MT,AF,TF> >
12314 {
12315  typedef typename DivTrait< T, typename SubmatrixTrait<MT>::Type >::Type Type;
12316 };
12318 //*************************************************************************************************
12319 
12320 
12321 
12322 
12323 //=================================================================================================
12324 //
12325 // SUBMATRIXTRAIT SPECIALIZATIONS
12326 //
12327 //=================================================================================================
12328 
12329 //*************************************************************************************************
12331 template< typename MT, bool AF, bool SO >
12332 struct SubmatrixTrait< DenseSubmatrix<MT,AF,SO> >
12333 {
12335 };
12337 //*************************************************************************************************
12338 
12339 
12340 
12341 
12342 //=================================================================================================
12343 //
12344 // SUBMATRIXEXPRTRAIT SPECIALIZATIONS
12345 //
12346 //=================================================================================================
12347 
12348 //*************************************************************************************************
12350 template< typename MT, bool AF1, bool SO, bool AF2 >
12351 struct SubmatrixExprTrait< DenseSubmatrix<MT,AF1,SO>, AF2 >
12352 {
12353  typedef DenseSubmatrix<MT,AF2,SO> Type;
12354 };
12356 //*************************************************************************************************
12357 
12358 
12359 //*************************************************************************************************
12361 template< typename MT, bool AF1, bool SO, bool AF2 >
12362 struct SubmatrixExprTrait< const DenseSubmatrix<MT,AF1,SO>, AF2 >
12363 {
12364  typedef DenseSubmatrix<MT,AF2,SO> Type;
12365 };
12367 //*************************************************************************************************
12368 
12369 
12370 //*************************************************************************************************
12372 template< typename MT, bool AF1, bool SO, bool AF2 >
12373 struct SubmatrixExprTrait< volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
12374 {
12375  typedef DenseSubmatrix<MT,AF2,SO> Type;
12376 };
12378 //*************************************************************************************************
12379 
12380 
12381 //*************************************************************************************************
12383 template< typename MT, bool AF1, bool SO, bool AF2 >
12384 struct SubmatrixExprTrait< const volatile DenseSubmatrix<MT,AF1,SO>, AF2 >
12385 {
12386  typedef DenseSubmatrix<MT,AF2,SO> Type;
12387 };
12389 //*************************************************************************************************
12390 
12391 
12392 
12393 
12394 //=================================================================================================
12395 //
12396 // ROWTRAIT SPECIALIZATIONS
12397 //
12398 //=================================================================================================
12399 
12400 //*************************************************************************************************
12402 template< typename MT, bool AF, bool SO >
12403 struct RowTrait< DenseSubmatrix<MT,AF,SO> >
12404 {
12405  typedef typename RowTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
12406 };
12408 //*************************************************************************************************
12409 
12410 
12411 
12412 
12413 //=================================================================================================
12414 //
12415 // COLUMNTRAIT SPECIALIZATIONS
12416 //
12417 //=================================================================================================
12418 
12419 //*************************************************************************************************
12421 template< typename MT, bool AF, bool SO >
12422 struct ColumnTrait< DenseSubmatrix<MT,AF,SO> >
12423 {
12424  typedef typename ColumnTrait< typename DenseSubmatrix<MT,AF,SO>::ResultType >::Type Type;
12425 };
12427 //*************************************************************************************************
12428 
12429 } // namespace blaze
12430 
12431 #endif
Constraint on the data type.
void storea(size_t i, size_t j, const IntrinsicType &value)
Aligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2669
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
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:2736
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:1729
DenseSubmatrix & transpose()
In-place transpose of the submatrix.
Definition: DenseSubmatrix.h:2262
IteratorCategory iterator_category
The iterator category.
Definition: DenseSubmatrix.h:541
ReferenceType reference
Reference return type.
Definition: DenseSubmatrix.h:544
const size_t column_
The first column of the submatrix.
Definition: DenseSubmatrix.h:1070
Header file for kernel specific block sizes.
Header file for mathematical functions.
bool canAlias(const Other *alias) const
Returns whether the submatrix can alias with the given address alias.
Definition: DenseSubmatrix.h:2407
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the 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.
#define BLAZE_CONSTRAINT_MUST_HAVE_MUTABLE_DATA_ACCESS(T)
Constraint on the data type.In case the given data type T does not provide low-level data access to m...
Definition: MutableDataAccess.h:79
Header file for basic type definitions.
If< IsConst< MT >, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant submatrix value.
Definition: DenseSubmatrix.h:507
std::iterator_traits< IteratorType >::difference_type DifferenceType
Difference between two iterators.
Definition: DenseSubmatrix.h:538
DifferenceType difference_type
Difference between two iterators.
Definition: DenseSubmatrix.h:545
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:252
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:250
bool isStrictlyLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly lower triangular matrix.
Definition: DenseMatrix.h:1201
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
Header file for the IsSparseMatrix type trait.
bool isStrictlyUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a strictly upper triangular matrix.
Definition: DenseMatrix.h:1434
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:207
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:1214
bool operator<=(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:755
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:647
const bool aligned
Alignment flag for aligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:85
Header file for the IsSame and IsStrictlySame type traits.
Header file for the dense matrix inversion flags.
bool isSymmetric(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is symmetric.
Definition: DenseMatrix.h:697
bool hasOverlap() const
Checking whether there exists an overlap in the context of a symmetric matrix.
Definition: DenseSubmatrix.h:2374
bool isAligned() const
Returns whether the submatrix is properly aligned in memory.
Definition: DenseSubmatrix.h:2497
Iterator end(size_t i)
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1460
bool isAliased(const Other *alias) const
Returns whether the submatrix is aliased with the given address alias.
Definition: DenseSubmatrix.h:2453
const bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
Header file for the IsColumnMajorMatrix type trait.
DenseSubmatrix & ctranspose()
In-place conjugate transpose of the submatrix.
Definition: DenseSubmatrix.h:2301
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
ConstIterator cend(size_t i) const
Returns an iterator just past the last non-zero element of row/column i.
Definition: DenseSubmatrix.h:1506
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2749
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2588
ReferenceType operator*() const
Direct access to the element at the current iterator position.
Definition: DenseSubmatrix.h:652
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
const size_t n_
The number of columns of the submatrix.
Definition: DenseSubmatrix.h:1072
const size_t row_
The first row of the submatrix.
Definition: DenseSubmatrix.h:1069
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:107
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:257
const ElementType * ConstPointer
Pointer to a constant submatrix value.
Definition: DenseSubmatrix.h:510
SubmatrixIterator(const SubmatrixIterator< IteratorType2 > &it)
Conversion constructor from different SubmatrixIterator instances.
Definition: DenseSubmatrix.h:575
void reset()
Reset to the default initial values.
Definition: DenseSubmatrix.h:2181
MT::ElementType ElementType
Type of the submatrix elements.
Definition: DenseSubmatrix.h:498
size_t columns() const
Returns the number of columns of the dense submatrix.
Definition: DenseSubmatrix.h:2052
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
Constraints on the storage order of matrix types.
#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.
System settings for performance optimizations.
bool isAligned() const
Access to the iterator's memory alignment flag.
Definition: DenseSubmatrix.h:833
Pointer data()
Low-level data access to the submatrix elements.
Definition: DenseSubmatrix.h:1316
ConstIterator cbegin(size_t i) const
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1438
size_t rows() const
Returns the number of rows of the dense submatrix.
Definition: DenseSubmatrix.h:2022
Header file for the IsUniLower type trait.
SubmatrixIterator()
Default constructor of the SubmatrixIterator class.
Definition: DenseSubmatrix.h:551
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:1044
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:117
friend const SubmatrixIterator operator+(size_t inc, const SubmatrixIterator &it)
Addition between an integral value and a SubmatrixIterator.
Definition: DenseSubmatrix.h:801
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
Constraint on the data type.
DenseSubmatrix & operator=(const ElementType &rhs)
Homogenous assignment to all submatrix elements.
Definition: DenseSubmatrix.h:1535
SubmatrixTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: DenseSubmatrix.h:495
Iterator begin(size_t i)
Returns an iterator to the first non-zero element of row/column i.
Definition: DenseSubmatrix.h:1392
Constraint on the data type.
Header file for the matrix storage order types.
Constraint on the data type.
void invert(const HermitianProxy< MT > &proxy)
In-place inversion of the represented element.
Definition: HermitianProxy.h:767
Compile time check to query the requirement to evaluate an expression.Via this type trait it is possi...
Definition: RequiresEvaluation.h:90
SubmatrixIterator(IteratorType iterator, bool isMemoryAligned)
Constructor of the SubmatrixIterator class.
Definition: DenseSubmatrix.h:563
ValueType value_type
Type of the underlying elements.
Definition: DenseSubmatrix.h:542
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:85
bool operator<(const SubmatrixIterator &rhs) const
Less-than comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:733
std::iterator_traits< IteratorType >::reference ReferenceType
Reference return type.
Definition: DenseSubmatrix.h:535
IntrinsicType loadu(size_t i, size_t j) const
Unaligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2607
Header file for the DisableIf class template.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type loadu(const T *address)
Loads a vector of 2-byte integral values.
Definition: Loadu.h:74
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
Header file for nested template disabiguation.
Header file for the If class template.
IntrinsicType load() const
Load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:667
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: ColumnMajorMatrix.h:79
SubmatrixIterator< typename MT::ConstIterator > ConstIterator
Iterator over constant elements.
Definition: DenseSubmatrix.h:848
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type storeu(T *address, const simd_int16_t &value)
Unaligned store of a vector of 2-byte integral values.
Definition: Storeu.h:75
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:116
SubmatrixIterator & operator+=(size_t inc)
Addition assignment operator.
Definition: DenseSubmatrix.h:587
Header file for the Or class template.
bool operator==(const SubmatrixIterator &rhs) const
Equality comparison between two SubmatrixIterator objects.
Definition: DenseSubmatrix.h:711
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1682
Header file for the DenseMatrix base class.
Header file for the Not class template.
const DenseSubmatrix & CompositeType
Data type for composite expression templates.
Definition: DenseSubmatrix.h:501
const CTransExprTrait< MT >::Type ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatConjExpr.h:974
size_t row() const
Returns the index of the first row of the submatrix in the underlying dense matrix.
Definition: DenseSubmatrix.h:2007
IntrinsicTrait< typename MT::ElementType > IT
Intrinsic trait for the matrix element type.
Definition: DenseSubmatrix.h:489
Header file for the IsLower type trait.
IntrinsicType load(size_t i, size_t j) const
Load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2543
Header file for the IsAligned type trait.
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:722
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1277
const SubmatrixIterator operator++(int)
Post-increment operator.
Definition: DenseSubmatrix.h:621
Compile time check for symmetric matrices.This type trait tests whether or not the given template par...
Definition: IsSymmetric.h:85
If< IsConst< MT >, ConstIterator, SubmatrixIterator< typename MT::Iterator > >::Type Iterator
Iterator over non-constant elements.
Definition: DenseSubmatrix.h:851
SubmatrixIterator & operator-=(size_t dec)
Subtraction assignment operator.
Definition: DenseSubmatrix.h:599
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:187
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:497
bool isUniLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower unitriangular matrix.
Definition: DenseMatrix.h:1121
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2586
const bool unaligned
Alignment flag for unaligned vectors and matrices.Via this flag it is possible to specify subvectors...
Definition: AlignmentFlag.h:64
Constraint on the data type.
std::iterator_traits< IteratorType >::value_type ValueType
Type of the underlying elements.
Definition: DenseSubmatrix.h:529
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2590
Constraint on the data type.
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:527
If< Or< IsConst< MT >, Not< HasMutableDataAccess< MT > > >, ConstPointer, ElementType * >::Type Pointer
Pointer to a non-constant submatrix value.
Definition: DenseSubmatrix.h:514
Header file for the IsPadded type trait.
InversionFlag
Inversion flag.The InversionFlag type enumeration represents the different types of matrix inversion ...
Definition: InversionFlag.h:76
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:1068
Header file for the DerestrictTrait class template.
Constraint on the data type.
IteratorType iterator_
Iterator to the current submatrix element.
Definition: DenseSubmatrix.h:840
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:494
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:841
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:107
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type loada(const T *address)
Loads a vector of 2-byte integral values.
Definition: Loada.h:77
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: RowMajorMatrix.h:79
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2587
Header file for the IsConst type trait.
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:1232
IntrinsicType loadu() const
Unaligned load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:700
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:138
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:777
Base template for the MultTrait class.
Definition: MultTrait.h:138
IntrinsicType loada() const
Aligned load of an intrinsic element of the dense submatrix.
Definition: DenseSubmatrix.h:685
Header file for the addition trait.
Header file for the division trait.
SubmatrixIterator & operator++()
Pre-increment operator.
Definition: DenseSubmatrix.h:610
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: DenseSubmatrix.h:500
DenseSubmatrix(Operand matrix, size_t rindex, size_t cindex, size_t m, size_t n)
The constructor for DenseSubmatrix.
Definition: DenseSubmatrix.h:1176
Header file for the submatrix trait.
If< IsExpression< MT >, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: DenseSubmatrix.h:486
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:521
const bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
const bool isAligned_
Memory alignment flag.
Definition: DenseSubmatrix.h:1073
Header file for the cache size of the target architecture.
std::iterator_traits< IteratorType >::iterator_category IteratorCategory
The iterator category.
Definition: DenseSubmatrix.h:526
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:744
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:116
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2591
Header file for the column trait.
Header file for the isDefault shim.
Compile time check for Hermitian matrices.This type trait tests whether or not the given template par...
Definition: IsHermitian.h:85
ResultType::OppositeType OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DenseSubmatrix.h:496
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:94
Constraint on the data type.
PointerType pointer
Pointer return type.
Definition: DenseSubmatrix.h:543
Constraint on the data type.
size_t capacity() const
Returns the maximum capacity of the dense submatrix.
Definition: DenseSubmatrix.h:2087
Constraints on the storage order of matrix types.
IntrinsicType loada(size_t i, size_t j) const
Aligned load of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2573
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:642
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
void storeu(size_t i, size_t j, const IntrinsicType &value)
Unaligned store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2702
Header file for all intrinsic functionality.
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
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:2127
IteratorType base() const
Access to the current position of the submatrix iterator.
Definition: DenseSubmatrix.h:823
IT::Type IntrinsicType
Intrinsic type of the submatrix elements.
Definition: DenseSubmatrix.h:499
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2750
MT::ConstReference ConstReference
Reference to a constant submatrix value.
Definition: DenseSubmatrix.h:504
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:146
size_t column() const
Returns the index of the first column of the submatrix in the underlying dense matrix.
Definition: DenseSubmatrix.h:2037
Base class for N-dimensional vectors.The Vector class is a base class for all arbitrarily sized (N-di...
Definition: Forward.h:164
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:944
const bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:258
bool isHermitian(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is Hermitian.
Definition: DenseMatrix.h:767
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
Header file for the alignment check function.
std::iterator_traits< IteratorType >::pointer PointerType
Pointer return type.
Definition: DenseSubmatrix.h:532
#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:2583
Header file for the IsTrue value trait.
View on a specific submatrix of a dense matrix.The DenseSubmatrix template represents a view on a spe...
Definition: DenseSubmatrix.h:480
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type stream(T *address, const simd_int16_t &value)
Aligned, non-temporal store of a vector of 2-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:324
Reference at(size_t i, size_t j)
Checked access to the submatrix elements.
Definition: DenseSubmatrix.h:1263
bool canSMPAssign() const
Returns whether the submatrix can be used in SMP assignments.
Definition: DenseSubmatrix.h:2517
Compile time type check.This class tests whether the given template parameter T is a reference type (...
Definition: IsReference.h:94
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:237
size_t spacing() const
Returns the spacing between the beginning of two rows/columns.
Definition: DenseSubmatrix.h:2072
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
bool isUniUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper unitriangular matrix.
Definition: DenseMatrix.h:1354
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2589
Base template for the SubTrait class.
Definition: SubTrait.h:138
Header file for the Submatrix base class.
const size_t m_
The number of rows of the submatrix.
Definition: DenseSubmatrix.h:1071
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exceptionThis macro encapsulates the default way of Blaz...
Definition: Exception.h:283
Header file for the IsUpper type trait.
Header file for exception macros.
void store(size_t i, size_t j, const IntrinsicType &value)
Store of an intrinsic element of the submatrix.
Definition: DenseSubmatrix.h:2640
friend const SubmatrixIterator operator-(const SubmatrixIterator &it, size_t dec)
Subtraction between a SubmatrixIterator and an integral value.
Definition: DenseSubmatrix.h:813
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
Header file for the IsHermitian type trait.
Header file for the IsRestricted type trait.
System settings for the inline keywords.
Size type of the Blaze library.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
SubmatrixIterator & operator--()
Pre-decrement operator.
Definition: DenseSubmatrix.h:631
#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:766
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type storea(T *address, const simd_int16_t &value)
Aligned store of a vector of 2-byte integral values.
Definition: Storea.h:78
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:789
Constraint on the data type.
Header file for the FunctionTrace class.
Header file for a safe C++ NULL pointer implementation.