DynamicMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_DENSE_DYNAMICMATRIX_H_
36 #define _BLAZE_MATH_DENSE_DYNAMICMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <utility>
45 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
53 #include <blaze/math/Forward.h>
54 #include <blaze/math/Functions.h>
56 #include <blaze/math/shims/Clear.h>
59 #include <blaze/math/SIMD.h>
87 #include <blaze/system/Blocking.h>
88 #include <blaze/system/CacheSize.h>
89 #include <blaze/system/Inline.h>
91 #include <blaze/system/Restrict.h>
94 #include <blaze/util/Algorithm.h>
96 #include <blaze/util/Assert.h>
102 #include <blaze/util/DisableIf.h>
103 #include <blaze/util/EnableIf.h>
105 #include <blaze/util/Memory.h>
106 #include <blaze/util/Template.h>
107 #include <blaze/util/TrueType.h>
108 #include <blaze/util/Types.h>
112 #include <blaze/util/Unused.h>
113 
114 
115 namespace blaze {
116 
117 //=================================================================================================
118 //
119 // CLASS DEFINITION
120 //
121 //=================================================================================================
122 
123 //*************************************************************************************************
202 template< typename Type // Data type of the matrix
203  , bool SO = defaultStorageOrder > // Storage order
204 class DynamicMatrix : public DenseMatrix< DynamicMatrix<Type,SO>, SO >
205 {
206  public:
207  //**Type definitions****************************************************************************
210  typedef This ResultType;
213  typedef Type ElementType;
215  typedef const Type& ReturnType;
216  typedef const This& CompositeType;
217 
218  typedef Type& Reference;
219  typedef const Type& ConstReference;
220  typedef Type* Pointer;
221  typedef const Type* ConstPointer;
222 
225  //**********************************************************************************************
226 
227  //**Rebind struct definition********************************************************************
230  template< typename NewType > // Data type of the other matrix
231  struct Rebind {
233  };
234  //**********************************************************************************************
235 
236  //**Resize struct definition********************************************************************
239  template< size_t NewM // Number of rows of the other matrix
240  , size_t NewN > // Number of columns of the other matrix
241  struct Resize {
243  };
244  //**********************************************************************************************
245 
246  //**Compilation flags***************************************************************************
248 
252  enum : bool { simdEnabled = IsVectorizable<Type>::value };
253 
255 
258  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
259  //**********************************************************************************************
260 
261  //**Constructors********************************************************************************
264  explicit inline DynamicMatrix() noexcept;
265  explicit inline DynamicMatrix( size_t m, size_t n );
266  explicit inline DynamicMatrix( size_t m, size_t n, const Type& init );
267  explicit inline DynamicMatrix( initializer_list< initializer_list<Type> > list );
268 
269  template< typename Other >
270  explicit inline DynamicMatrix( size_t m, size_t n, const Other* array );
271 
272  template< typename Other, size_t M, size_t N >
273  explicit inline DynamicMatrix( const Other (&array)[M][N] );
274 
275  inline DynamicMatrix( const DynamicMatrix& m );
276  inline DynamicMatrix( DynamicMatrix&& m ) noexcept;
277  template< typename MT, bool SO2 > inline DynamicMatrix( const Matrix<MT,SO2>& m );
279  //**********************************************************************************************
280 
281  //**Destructor**********************************************************************************
284  inline ~DynamicMatrix();
286  //**********************************************************************************************
287 
288  //**Data access functions***********************************************************************
291  inline Reference operator()( size_t i, size_t j ) noexcept;
292  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
293  inline Reference at( size_t i, size_t j );
294  inline ConstReference at( size_t i, size_t j ) const;
295  inline Pointer data () noexcept;
296  inline ConstPointer data () const noexcept;
297  inline Pointer data ( size_t i ) noexcept;
298  inline ConstPointer data ( size_t i ) const noexcept;
299  inline Iterator begin ( size_t i ) noexcept;
300  inline ConstIterator begin ( size_t i ) const noexcept;
301  inline ConstIterator cbegin( size_t i ) const noexcept;
302  inline Iterator end ( size_t i ) noexcept;
303  inline ConstIterator end ( size_t i ) const noexcept;
304  inline ConstIterator cend ( size_t i ) const noexcept;
306  //**********************************************************************************************
307 
308  //**Assignment operators************************************************************************
311  inline DynamicMatrix& operator=( const Type& rhs );
312  inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list );
313 
314  template< typename Other, size_t M, size_t N >
315  inline DynamicMatrix& operator=( const Other (&array)[M][N] );
316 
317  inline DynamicMatrix& operator=( const DynamicMatrix& rhs );
318  inline DynamicMatrix& operator=( DynamicMatrix&& rhs ) noexcept;
319 
320  template< typename MT, bool SO2 > inline DynamicMatrix& operator= ( const Matrix<MT,SO2>& rhs );
321  template< typename MT, bool SO2 > inline DynamicMatrix& operator+=( const Matrix<MT,SO2>& rhs );
322  template< typename MT, bool SO2 > inline DynamicMatrix& operator-=( const Matrix<MT,SO2>& rhs );
323  template< typename MT, bool SO2 > inline DynamicMatrix& operator*=( const Matrix<MT,SO2>& rhs );
324 
325  template< typename Other >
326  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator*=( Other rhs );
327 
328  template< typename Other >
329  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator/=( Other rhs );
331  //**********************************************************************************************
332 
333  //**Utility functions***************************************************************************
336  inline size_t rows() const noexcept;
337  inline size_t columns() const noexcept;
338  inline size_t spacing() const noexcept;
339  inline size_t capacity() const noexcept;
340  inline size_t capacity( size_t i ) const noexcept;
341  inline size_t nonZeros() const;
342  inline size_t nonZeros( size_t i ) const;
343  inline void reset();
344  inline void reset( size_t i );
345  inline void clear();
346  void resize ( size_t m, size_t n, bool preserve=true );
347  inline void extend ( size_t m, size_t n, bool preserve=true );
348  inline void reserve( size_t elements );
349  inline void swap( DynamicMatrix& m ) noexcept;
351  //**********************************************************************************************
352 
353  //**Numeric functions***************************************************************************
356  inline DynamicMatrix& transpose();
357  inline DynamicMatrix& ctranspose();
358 
359  template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
361  //**********************************************************************************************
362 
363  private:
364  //**********************************************************************************************
366  template< typename MT >
368  struct VectorizedAssign {
369  enum : bool { value = useOptimizedKernels &&
370  simdEnabled && MT::simdEnabled &&
372  };
374  //**********************************************************************************************
375 
376  //**********************************************************************************************
378  template< typename MT >
380  struct VectorizedAddAssign {
381  enum : bool { value = useOptimizedKernels &&
382  simdEnabled && MT::simdEnabled &&
386  };
388  //**********************************************************************************************
389 
390  //**********************************************************************************************
392  template< typename MT >
394  struct VectorizedSubAssign {
395  enum : bool { value = useOptimizedKernels &&
396  simdEnabled && MT::simdEnabled &&
400  };
402  //**********************************************************************************************
403 
404  //**********************************************************************************************
406  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
407  //**********************************************************************************************
408 
409  public:
410  //**Debugging functions*************************************************************************
413  inline bool isIntact() const noexcept;
415  //**********************************************************************************************
416 
417  //**Expression template evaluation functions****************************************************
420  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
421  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
422 
423  inline bool isAligned () const noexcept;
424  inline bool canSMPAssign() const noexcept;
425 
426  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
427  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
428  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
429 
430  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
431  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
432  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
433  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
434 
435  template< typename MT >
436  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
437 
438  template< typename MT >
439  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
440 
441  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
442  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
443  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
444 
445  template< typename MT >
446  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
447 
448  template< typename MT >
449  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
450 
451  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
452  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
453  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
454 
455  template< typename MT >
456  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
457 
458  template< typename MT >
459  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
460 
461  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
462  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
463  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
465  //**********************************************************************************************
466 
467  private:
468  //**Utility functions***************************************************************************
471  inline size_t adjustColumns( size_t minColumns ) const noexcept;
473  //**********************************************************************************************
474 
475  //**Member variables****************************************************************************
478  size_t m_;
479  size_t n_;
480  size_t nn_;
481  size_t capacity_;
483 
493  //**********************************************************************************************
494 
495  //**Compile time checks*************************************************************************
502  //**********************************************************************************************
503 };
504 //*************************************************************************************************
505 
506 
507 
508 
509 //=================================================================================================
510 //
511 // CONSTRUCTORS
512 //
513 //=================================================================================================
514 
515 //*************************************************************************************************
518 template< typename Type // Data type of the matrix
519  , bool SO > // Storage order
521  : m_ ( 0UL ) // The current number of rows of the matrix
522  , n_ ( 0UL ) // The current number of columns of the matrix
523  , nn_ ( 0UL ) // The alignment adjusted number of columns
524  , capacity_( 0UL ) // The maximum capacity of the matrix
525  , v_ ( nullptr ) // The matrix elements
526 {}
527 //*************************************************************************************************
528 
529 
530 //*************************************************************************************************
539 template< typename Type // Data type of the matrix
540  , bool SO > // Storage order
541 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n )
542  : m_ ( m ) // The current number of rows of the matrix
543  , n_ ( n ) // The current number of columns of the matrix
544  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
545  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
546  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
547 {
549  for( size_t i=0UL; i<m_; ++i ) {
550  for( size_t j=n_; j<nn_; ++j ) {
551  v_[i*nn_+j] = Type();
552  }
553  }
554  }
555 
556  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
557 }
558 //*************************************************************************************************
559 
560 
561 //*************************************************************************************************
570 template< typename Type // Data type of the matrix
571  , bool SO > // Storage order
572 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, const Type& init )
573  : m_ ( m ) // The current number of rows of the matrix
574  , n_ ( n ) // The current number of columns of the matrix
575  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
576  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
577  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
578 {
579  for( size_t i=0UL; i<m; ++i ) {
580  for( size_t j=0UL; j<n_; ++j )
581  v_[i*nn_+j] = init;
582 
584  for( size_t j=n_; j<nn_; ++j )
585  v_[i*nn_+j] = Type();
586  }
587  }
588 
589  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
590 }
591 //*************************************************************************************************
592 
593 
594 //*************************************************************************************************
614 template< typename Type // Data type of the matrix
615  , bool SO > // Storage order
617  : m_ ( list.size() ) // The current number of rows of the matrix
618  , n_ ( determineColumns( list ) ) // The current number of columns of the matrix
619  , nn_ ( adjustColumns( n_ ) ) // The alignment adjusted number of columns
620  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
621  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
622 {
623  size_t i( 0UL );
624 
625  for( const auto& rowList : list ) {
626  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ), v_+(i+1UL)*nn_, Type() );
627  ++i;
628  }
629 
630  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
631 }
632 //*************************************************************************************************
633 
634 
635 //*************************************************************************************************
658 template< typename Type // Data type of the matrix
659  , bool SO > // Storage order
660 template< typename Other > // Data type of the initialization array
661 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, const Other* array )
662  : m_ ( m ) // The current number of rows of the matrix
663  , n_ ( n ) // The current number of columns of the matrix
664  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
665  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
666  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
667 {
668  for( size_t i=0UL; i<m; ++i ) {
669  for( size_t j=0UL; j<n; ++j )
670  v_[i*nn_+j] = array[i*n+j];
671 
673  for( size_t j=n; j<nn_; ++j )
674  v_[i*nn_+j] = Type();
675  }
676  }
677 
678  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
679 }
680 //*************************************************************************************************
681 
682 
683 //*************************************************************************************************
704 template< typename Type // Data type of the matrix
705  , bool SO > // Storage order
706 template< typename Other // Data type of the initialization array
707  , size_t M // Number of rows of the initialization array
708  , size_t N > // Number of columns of the initialization array
709 inline DynamicMatrix<Type,SO>::DynamicMatrix( const Other (&array)[M][N] )
710  : m_ ( M ) // The current number of rows of the matrix
711  , n_ ( N ) // The current number of columns of the matrix
712  , nn_ ( adjustColumns( N ) ) // The alignment adjusted number of columns
713  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
714  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
715 {
716  for( size_t i=0UL; i<M; ++i ) {
717  for( size_t j=0UL; j<N; ++j )
718  v_[i*nn_+j] = array[i][j];
719 
721  for( size_t j=N; j<nn_; ++j )
722  v_[i*nn_+j] = Type();
723  }
724  }
725 
726  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
727 }
728 //*************************************************************************************************
729 
730 
731 //*************************************************************************************************
739 template< typename Type // Data type of the matrix
740  , bool SO > // Storage order
742  : m_ ( m.m_ ) // The current number of rows of the matrix
743  , n_ ( m.n_ ) // The current number of columns of the matrix
744  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
745  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
746  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
747 {
748  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
749 
750  for( size_t i=0UL; i<capacity_; ++i )
751  v_[i] = m.v_[i];
752 
753  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
754 }
755 //*************************************************************************************************
756 
757 
758 //*************************************************************************************************
763 template< typename Type // Data type of the matrix
764  , bool SO > // Storage order
766  : m_ ( m.m_ ) // The current number of rows of the matrix
767  , n_ ( m.n_ ) // The current number of columns of the matrix
768  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
769  , capacity_( m.capacity_ ) // The maximum capacity of the matrix
770  , v_ ( m.v_ ) // The matrix elements
771 {
772  m.m_ = 0UL;
773  m.n_ = 0UL;
774  m.nn_ = 0UL;
775  m.capacity_ = 0UL;
776  m.v_ = nullptr;
777 }
778 //*************************************************************************************************
779 
780 
781 //*************************************************************************************************
786 template< typename Type // Data type of the matrix
787  , bool SO > // Storage order
788 template< typename MT // Type of the foreign matrix
789  , bool SO2 > // Storage order of the foreign matrix
791  : m_ ( (~m).rows() ) // The current number of rows of the matrix
792  , n_ ( (~m).columns() ) // The current number of columns of the matrix
793  , nn_ ( adjustColumns( n_ ) ) // The alignment adjusted number of columns
794  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
795  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
796 {
797  for( size_t i=0UL; i<m_; ++i ) {
798  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : n_ );
799  j<( IsVectorizable<Type>::value ? nn_ : n_ ); ++j ) {
800  v_[i*nn_+j] = Type();
801  }
802  }
803 
804  smpAssign( *this, ~m );
805 
806  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
807 }
808 //*************************************************************************************************
809 
810 
811 
812 
813 //=================================================================================================
814 //
815 // DESTRUCTOR
816 //
817 //=================================================================================================
818 
819 //*************************************************************************************************
822 template< typename Type // Data type of the matrix
823  , bool SO > // Storage order
825 {
826  deallocate( v_ );
827 }
828 //*************************************************************************************************
829 
830 
831 
832 
833 //=================================================================================================
834 //
835 // DATA ACCESS FUNCTIONS
836 //
837 //=================================================================================================
838 
839 //*************************************************************************************************
849 template< typename Type // Data type of the matrix
850  , bool SO > // Storage order
851 inline typename DynamicMatrix<Type,SO>::Reference
852  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) noexcept
853 {
854  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
855  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
856  return v_[i*nn_+j];
857 }
858 //*************************************************************************************************
859 
860 
861 //*************************************************************************************************
871 template< typename Type // Data type of the matrix
872  , bool SO > // Storage order
874  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) const noexcept
875 {
876  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
877  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
878  return v_[i*nn_+j];
879 }
880 //*************************************************************************************************
881 
882 
883 //*************************************************************************************************
894 template< typename Type // Data type of the matrix
895  , bool SO > // Storage order
896 inline typename DynamicMatrix<Type,SO>::Reference
897  DynamicMatrix<Type,SO>::at( size_t i, size_t j )
898 {
899  if( i >= m_ ) {
900  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
901  }
902  if( j >= n_ ) {
903  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
904  }
905  return (*this)(i,j);
906 }
907 //*************************************************************************************************
908 
909 
910 //*************************************************************************************************
921 template< typename Type // Data type of the matrix
922  , bool SO > // Storage order
924  DynamicMatrix<Type,SO>::at( size_t i, size_t j ) const
925 {
926  if( i >= m_ ) {
927  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
928  }
929  if( j >= n_ ) {
930  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
931  }
932  return (*this)(i,j);
933 }
934 //*************************************************************************************************
935 
936 
937 //*************************************************************************************************
949 template< typename Type // Data type of the matrix
950  , bool SO > // Storage order
951 inline typename DynamicMatrix<Type,SO>::Pointer
953 {
954  return v_;
955 }
956 //*************************************************************************************************
957 
958 
959 //*************************************************************************************************
971 template< typename Type // Data type of the matrix
972  , bool SO > // Storage order
975 {
976  return v_;
977 }
978 //*************************************************************************************************
979 
980 
981 //*************************************************************************************************
989 template< typename Type // Data type of the matrix
990  , bool SO > // Storage order
991 inline typename DynamicMatrix<Type,SO>::Pointer
992  DynamicMatrix<Type,SO>::data( size_t i ) noexcept
993 {
994  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
995  return v_ + i*nn_;
996 }
997 //*************************************************************************************************
998 
999 
1000 //*************************************************************************************************
1008 template< typename Type // Data type of the matrix
1009  , bool SO > // Storage order
1011  DynamicMatrix<Type,SO>::data( size_t i ) const noexcept
1012 {
1013  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1014  return v_ + i*nn_;
1015 }
1016 //*************************************************************************************************
1017 
1018 
1019 //*************************************************************************************************
1030 template< typename Type // Data type of the matrix
1031  , bool SO > // Storage order
1032 inline typename DynamicMatrix<Type,SO>::Iterator
1033  DynamicMatrix<Type,SO>::begin( size_t i ) noexcept
1034 {
1035  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1036  return Iterator( v_ + i*nn_ );
1037 }
1038 //*************************************************************************************************
1039 
1040 
1041 //*************************************************************************************************
1052 template< typename Type // Data type of the matrix
1053  , bool SO > // Storage order
1055  DynamicMatrix<Type,SO>::begin( size_t i ) const noexcept
1056 {
1057  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1058  return ConstIterator( v_ + i*nn_ );
1059 }
1060 //*************************************************************************************************
1061 
1062 
1063 //*************************************************************************************************
1074 template< typename Type // Data type of the matrix
1075  , bool SO > // Storage order
1077  DynamicMatrix<Type,SO>::cbegin( size_t i ) const noexcept
1078 {
1079  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1080  return ConstIterator( v_ + i*nn_ );
1081 }
1082 //*************************************************************************************************
1083 
1084 
1085 //*************************************************************************************************
1096 template< typename Type // Data type of the matrix
1097  , bool SO > // Storage order
1098 inline typename DynamicMatrix<Type,SO>::Iterator
1099  DynamicMatrix<Type,SO>::end( size_t i ) noexcept
1100 {
1101  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1102  return Iterator( v_ + i*nn_ + n_ );
1103 }
1104 //*************************************************************************************************
1105 
1106 
1107 //*************************************************************************************************
1118 template< typename Type // Data type of the matrix
1119  , bool SO > // Storage order
1121  DynamicMatrix<Type,SO>::end( size_t i ) const noexcept
1122 {
1123  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1124  return ConstIterator( v_ + i*nn_ + n_ );
1125 }
1126 //*************************************************************************************************
1127 
1128 
1129 //*************************************************************************************************
1140 template< typename Type // Data type of the matrix
1141  , bool SO > // Storage order
1143  DynamicMatrix<Type,SO>::cend( size_t i ) const noexcept
1144 {
1145  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1146  return ConstIterator( v_ + i*nn_ + n_ );
1147 }
1148 //*************************************************************************************************
1149 
1150 
1151 
1152 
1153 //=================================================================================================
1154 //
1155 // ASSIGNMENT OPERATORS
1156 //
1157 //=================================================================================================
1158 
1159 //*************************************************************************************************
1165 template< typename Type // Data type of the matrix
1166  , bool SO > // Storage order
1168 {
1169  for( size_t i=0UL; i<m_; ++i )
1170  for( size_t j=0UL; j<n_; ++j )
1171  v_[i*nn_+j] = rhs;
1172 
1173  return *this;
1174 }
1175 //*************************************************************************************************
1176 
1177 
1178 //*************************************************************************************************
1199 template< typename Type // Data type of the matrix
1200  , bool SO > // Storage order
1201 inline DynamicMatrix<Type,SO>&
1203 {
1204  resize( list.size(), determineColumns( list ), false );
1205 
1206  size_t i( 0UL );
1207 
1208  for( const auto& rowList : list ) {
1209  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ), v_+(i+1UL)*nn_, Type() );
1210  ++i;
1211  }
1212 
1213  return *this;
1214 }
1215 //*************************************************************************************************
1216 
1217 
1218 //*************************************************************************************************
1239 template< typename Type // Data type of the matrix
1240  , bool SO > // Storage order
1241 template< typename Other // Data type of the initialization array
1242  , size_t M // Number of rows of the initialization array
1243  , size_t N > // Number of columns of the initialization array
1244 inline DynamicMatrix<Type,SO>& DynamicMatrix<Type,SO>::operator=( const Other (&array)[M][N] )
1245 {
1246  resize( M, N, false );
1247 
1248  for( size_t i=0UL; i<M; ++i )
1249  for( size_t j=0UL; j<N; ++j )
1250  v_[i*nn_+j] = array[i][j];
1251 
1252  return *this;
1253 }
1254 //*************************************************************************************************
1255 
1256 
1257 //*************************************************************************************************
1266 template< typename Type // Data type of the matrix
1267  , bool SO > // Storage order
1269 {
1270  if( &rhs == this ) return *this;
1271 
1272  resize( rhs.m_, rhs.n_, false );
1273  smpAssign( *this, ~rhs );
1274 
1275  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1276 
1277  return *this;
1278 }
1279 //*************************************************************************************************
1280 
1281 
1282 //*************************************************************************************************
1288 template< typename Type // Data type of the matrix
1289  , bool SO > // Storage order
1291 {
1292  deallocate( v_ );
1293 
1294  m_ = rhs.m_;
1295  n_ = rhs.n_;
1296  nn_ = rhs.nn_;
1297  capacity_ = rhs.capacity_;
1298  v_ = rhs.v_;
1299 
1300  rhs.m_ = 0UL;
1301  rhs.n_ = 0UL;
1302  rhs.nn_ = 0UL;
1303  rhs.capacity_ = 0UL;
1304  rhs.v_ = nullptr;
1305 
1306  return *this;
1307 }
1308 //*************************************************************************************************
1309 
1310 
1311 //*************************************************************************************************
1320 template< typename Type // Data type of the matrix
1321  , bool SO > // Storage order
1322 template< typename MT // Type of the right-hand side matrix
1323  , bool SO2 > // Storage order of the right-hand side matrix
1325 {
1326  typedef TransExprTrait_<This> TT;
1327  typedef CTransExprTrait_<This> CT;
1328  typedef InvExprTrait_<This> IT;
1329 
1330  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1331  transpose();
1332  }
1333  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1334  ctranspose();
1335  }
1336  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1337  DynamicMatrix tmp( ~rhs );
1338  swap( tmp );
1339  }
1340  else {
1341  resize( (~rhs).rows(), (~rhs).columns(), false );
1343  reset();
1344  smpAssign( *this, ~rhs );
1345  }
1346 
1347  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1348 
1349  return *this;
1350 }
1351 //*************************************************************************************************
1352 
1353 
1354 //*************************************************************************************************
1364 template< typename Type // Data type of the matrix
1365  , bool SO > // Storage order
1366 template< typename MT // Type of the right-hand side matrix
1367  , bool SO2 > // Storage order of the right-hand side matrix
1369 {
1370  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1371  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1372  }
1373 
1374  if( (~rhs).canAlias( this ) ) {
1375  const ResultType_<MT> tmp( ~rhs );
1376  smpAddAssign( *this, tmp );
1377  }
1378  else {
1379  smpAddAssign( *this, ~rhs );
1380  }
1381 
1382  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1383 
1384  return *this;
1385 }
1386 //*************************************************************************************************
1387 
1388 
1389 //*************************************************************************************************
1399 template< typename Type // Data type of the matrix
1400  , bool SO > // Storage order
1401 template< typename MT // Type of the right-hand side matrix
1402  , bool SO2 > // Storage order of the right-hand side matrix
1404 {
1405  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1406  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1407  }
1408 
1409  if( (~rhs).canAlias( this ) ) {
1410  const ResultType_<MT> tmp( ~rhs );
1411  smpSubAssign( *this, tmp );
1412  }
1413  else {
1414  smpSubAssign( *this, ~rhs );
1415  }
1416 
1417  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1418 
1419  return *this;
1420 }
1421 //*************************************************************************************************
1422 
1423 
1424 //*************************************************************************************************
1434 template< typename Type // Data type of the matrix
1435  , bool SO > // Storage order
1436 template< typename MT // Type of the right-hand side matrix
1437  , bool SO2 > // Storage order of the right-hand side matrix
1439 {
1440  if( (~rhs).rows() != n_ ) {
1441  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1442  }
1443 
1444  DynamicMatrix tmp( *this * (~rhs) );
1445  swap( tmp );
1446 
1447  return *this;
1448 }
1449 //*************************************************************************************************
1450 
1451 
1452 //*************************************************************************************************
1459 template< typename Type // Data type of the matrix
1460  , bool SO > // Storage order
1461 template< typename Other > // Data type of the right-hand side scalar
1464 {
1465  smpAssign( *this, (*this) * rhs );
1466 
1467  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1468 
1469  return *this;
1470 }
1471 //*************************************************************************************************
1472 
1473 
1474 //*************************************************************************************************
1481 template< typename Type // Data type of the matrix
1482  , bool SO > // Storage order
1483 template< typename Other > // Data type of the right-hand side scalar
1484 inline EnableIf_<IsNumeric<Other>, DynamicMatrix<Type,SO> >&
1486 {
1487  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1488 
1489  smpAssign( *this, (*this) / rhs );
1490 
1491  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1492 
1493  return *this;
1494 }
1495 //*************************************************************************************************
1496 
1497 
1498 
1499 
1500 //=================================================================================================
1501 //
1502 // UTILITY FUNCTIONS
1503 //
1504 //=================================================================================================
1505 
1506 //*************************************************************************************************
1511 template< typename Type // Data type of the matrix
1512  , bool SO > // Storage order
1513 inline size_t DynamicMatrix<Type,SO>::rows() const noexcept
1514 {
1515  return m_;
1516 }
1517 //*************************************************************************************************
1518 
1519 
1520 //*************************************************************************************************
1525 template< typename Type // Data type of the matrix
1526  , bool SO > // Storage order
1527 inline size_t DynamicMatrix<Type,SO>::columns() const noexcept
1528 {
1529  return n_;
1530 }
1531 //*************************************************************************************************
1532 
1533 
1534 //*************************************************************************************************
1544 template< typename Type // Data type of the matrix
1545  , bool SO > // Storage order
1546 inline size_t DynamicMatrix<Type,SO>::spacing() const noexcept
1547 {
1548  return nn_;
1549 }
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1558 template< typename Type // Data type of the matrix
1559  , bool SO > // Storage order
1560 inline size_t DynamicMatrix<Type,SO>::capacity() const noexcept
1561 {
1562  return capacity_;
1563 }
1564 //*************************************************************************************************
1565 
1566 
1567 //*************************************************************************************************
1578 template< typename Type // Data type of the matrix
1579  , bool SO > // Storage order
1580 inline size_t DynamicMatrix<Type,SO>::capacity( size_t i ) const noexcept
1581 {
1582  UNUSED_PARAMETER( i );
1583  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1584  return nn_;
1585 }
1586 //*************************************************************************************************
1587 
1588 
1589 //*************************************************************************************************
1594 template< typename Type // Data type of the matrix
1595  , bool SO > // Storage order
1597 {
1598  size_t nonzeros( 0UL );
1599 
1600  for( size_t i=0UL; i<m_; ++i )
1601  for( size_t j=0UL; j<n_; ++j )
1602  if( !isDefault( v_[i*nn_+j] ) )
1603  ++nonzeros;
1604 
1605  return nonzeros;
1606 }
1607 //*************************************************************************************************
1608 
1609 
1610 //*************************************************************************************************
1621 template< typename Type // Data type of the matrix
1622  , bool SO > // Storage order
1623 inline size_t DynamicMatrix<Type,SO>::nonZeros( size_t i ) const
1624 {
1625  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1626 
1627  const size_t jend( i*nn_ + n_ );
1628  size_t nonzeros( 0UL );
1629 
1630  for( size_t j=i*nn_; j<jend; ++j )
1631  if( !isDefault( v_[j] ) )
1632  ++nonzeros;
1633 
1634  return nonzeros;
1635 }
1636 //*************************************************************************************************
1637 
1638 
1639 //*************************************************************************************************
1644 template< typename Type // Data type of the matrix
1645  , bool SO > // Storage order
1647 {
1648  using blaze::clear;
1649 
1650  for( size_t i=0UL; i<m_; ++i )
1651  for( size_t j=0UL; j<n_; ++j )
1652  clear( v_[i*nn_+j] );
1653 }
1654 //*************************************************************************************************
1655 
1656 
1657 //*************************************************************************************************
1668 template< typename Type // Data type of the matrix
1669  , bool SO > // Storage order
1670 inline void DynamicMatrix<Type,SO>::reset( size_t i )
1671 {
1672  using blaze::clear;
1673 
1674  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1675  for( size_t j=0UL; j<n_; ++j )
1676  clear( v_[i*nn_+j] );
1677 }
1678 //*************************************************************************************************
1679 
1680 
1681 //*************************************************************************************************
1688 template< typename Type // Data type of the matrix
1689  , bool SO > // Storage order
1691 {
1692  resize( 0UL, 0UL, false );
1693 }
1694 //*************************************************************************************************
1695 
1696 
1697 //*************************************************************************************************
1731 template< typename Type // Data type of the matrix
1732  , bool SO > // Storage order
1733 void DynamicMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1734 {
1735  using blaze::min;
1736 
1737  if( m == m_ && n == n_ ) return;
1738 
1739  const size_t nn( adjustColumns( n ) );
1740 
1741  if( preserve )
1742  {
1743  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1744  const size_t min_m( min( m, m_ ) );
1745  const size_t min_n( min( n, n_ ) );
1746 
1747  for( size_t i=0UL; i<min_m; ++i ) {
1748  transfer( v_+i*nn_, v_+i*nn_+min_n, v+i*nn );
1749  }
1750 
1751  std::swap( v_, v );
1752  deallocate( v );
1753  capacity_ = m*nn;
1754  }
1755  else if( m*nn > capacity_ ) {
1756  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1757  std::swap( v_, v );
1758  deallocate( v );
1759  capacity_ = m*nn;
1760  }
1761 
1763  for( size_t i=0UL; i<m; ++i )
1764  for( size_t j=n; j<nn; ++j )
1765  v_[i*nn+j] = Type();
1766  }
1767 
1768  m_ = m;
1769  n_ = n;
1770  nn_ = nn;
1771 }
1772 //*************************************************************************************************
1773 
1774 
1775 //*************************************************************************************************
1789 template< typename Type // Data type of the matrix
1790  , bool SO > // Storage order
1791 inline void DynamicMatrix<Type,SO>::extend( size_t m, size_t n, bool preserve )
1792 {
1793  resize( m_+m, n_+n, preserve );
1794 }
1795 //*************************************************************************************************
1796 
1797 
1798 //*************************************************************************************************
1807 template< typename Type // Data type of the matrix
1808  , bool SO > // Storage order
1809 inline void DynamicMatrix<Type,SO>::reserve( size_t elements )
1810 {
1811  if( elements > capacity_ )
1812  {
1813  // Allocating a new array
1814  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
1815 
1816  // Initializing the new array
1817  transfer( v_, v_+capacity_, tmp );
1818 
1820  for( size_t i=capacity_; i<elements; ++i )
1821  tmp[i] = Type();
1822  }
1823 
1824  // Replacing the old array
1825  std::swap( tmp, v_ );
1826  deallocate( tmp );
1827  capacity_ = elements;
1828  }
1829 }
1830 //*************************************************************************************************
1831 
1832 
1833 //*************************************************************************************************
1839 template< typename Type // Data type of the matrix
1840  , bool SO > // Storage order
1842 {
1843  std::swap( m_ , m.m_ );
1844  std::swap( n_ , m.n_ );
1845  std::swap( nn_, m.nn_ );
1846  std::swap( capacity_, m.capacity_ );
1847  std::swap( v_ , m.v_ );
1848 }
1849 //*************************************************************************************************
1850 
1851 
1852 //*************************************************************************************************
1858 template< typename Type // Data type of the matrix
1859  , bool SO > // Storage order
1860 inline size_t DynamicMatrix<Type,SO>::adjustColumns( size_t minColumns ) const noexcept
1861 {
1863  return nextMultiple<size_t>( minColumns, SIMDSIZE );
1864  else return minColumns;
1865 }
1866 //*************************************************************************************************
1867 
1868 
1869 
1870 
1871 //=================================================================================================
1872 //
1873 // NUMERIC FUNCTIONS
1874 //
1875 //=================================================================================================
1876 
1877 //*************************************************************************************************
1882 template< typename Type // Data type of the matrix
1883  , bool SO > // Storage order
1885 {
1886  using std::swap;
1887 
1888  constexpr size_t block( BLOCK_SIZE );
1889 
1890  if( m_ == n_ )
1891  {
1892  for( size_t ii=0UL; ii<m_; ii+=block ) {
1893  const size_t iend( min( ii+block, m_ ) );
1894  for( size_t jj=0UL; jj<=ii; jj+=block ) {
1895  for( size_t i=ii; i<iend; ++i ) {
1896  const size_t jend( min( jj+block, n_, i ) );
1897  for( size_t j=jj; j<jend; ++j ) {
1898  swap( v_[i*nn_+j], v_[j*nn_+i] );
1899  }
1900  }
1901  }
1902  }
1903  }
1904  else
1905  {
1906  DynamicMatrix tmp( trans(*this) );
1907  this->swap( tmp );
1908  }
1909 
1910  return *this;
1911 }
1912 //*************************************************************************************************
1913 
1914 
1915 //*************************************************************************************************
1920 template< typename Type // Data type of the matrix
1921  , bool SO > // Storage order
1923 {
1924  constexpr size_t block( BLOCK_SIZE );
1925 
1926  if( m_ == n_ )
1927  {
1928  for( size_t ii=0UL; ii<m_; ii+=block ) {
1929  const size_t iend( min( ii+block, m_ ) );
1930  for( size_t jj=0UL; jj<ii; jj+=block ) {
1931  const size_t jend( min( jj+block, n_ ) );
1932  for( size_t i=ii; i<iend; ++i ) {
1933  for( size_t j=jj; j<jend; ++j ) {
1934  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1935  }
1936  }
1937  }
1938  for( size_t i=ii; i<iend; ++i ) {
1939  for( size_t j=ii; j<i; ++j ) {
1940  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1941  }
1942  conjugate( v_[i*nn_+i] );
1943  }
1944  }
1945  }
1946  else
1947  {
1948  DynamicMatrix tmp( ctrans(*this) );
1949  swap( tmp );
1950  }
1951 
1952  return *this;
1953 }
1954 //*************************************************************************************************
1955 
1956 
1957 //*************************************************************************************************
1963 template< typename Type // Data type of the matrix
1964  , bool SO > // Storage order
1965 template< typename Other > // Data type of the scalar value
1967 {
1968  for( size_t i=0UL; i<m_; ++i )
1969  for( size_t j=0UL; j<n_; ++j )
1970  v_[i*nn_+j] *= scalar;
1971 
1972  return *this;
1973 }
1974 //*************************************************************************************************
1975 
1976 
1977 
1978 
1979 //=================================================================================================
1980 //
1981 // DEBUGGING FUNCTIONS
1982 //
1983 //=================================================================================================
1984 
1985 //*************************************************************************************************
1994 template< typename Type // Data type of the matrix
1995  , bool SO > // Storage order
1996 inline bool DynamicMatrix<Type,SO>::isIntact() const noexcept
1997 {
1998  if( m_ * n_ > capacity_ )
1999  return false;
2000 
2002  for( size_t i=0UL; i<m_; ++i ) {
2003  for( size_t j=n_; j<nn_; ++j ) {
2004  if( v_[i*nn_+j] != Type() )
2005  return false;
2006  }
2007  }
2008  }
2009 
2010  return true;
2011 }
2012 //*************************************************************************************************
2013 
2014 
2015 
2016 
2017 //=================================================================================================
2018 //
2019 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2020 //
2021 //=================================================================================================
2022 
2023 //*************************************************************************************************
2033 template< typename Type // Data type of the matrix
2034  , bool SO > // Storage order
2035 template< typename Other > // Data type of the foreign expression
2036 inline bool DynamicMatrix<Type,SO>::canAlias( const Other* alias ) const noexcept
2037 {
2038  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2039 }
2040 //*************************************************************************************************
2041 
2042 
2043 //*************************************************************************************************
2053 template< typename Type // Data type of the matrix
2054  , bool SO > // Storage order
2055 template< typename Other > // Data type of the foreign expression
2056 inline bool DynamicMatrix<Type,SO>::isAliased( const Other* alias ) const noexcept
2057 {
2058  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2059 }
2060 //*************************************************************************************************
2061 
2062 
2063 //*************************************************************************************************
2072 template< typename Type // Data type of the matrix
2073  , bool SO > // Storage order
2074 inline bool DynamicMatrix<Type,SO>::isAligned() const noexcept
2075 {
2076  return ( usePadding || columns() % SIMDSIZE == 0UL );
2077 }
2078 //*************************************************************************************************
2079 
2080 
2081 //*************************************************************************************************
2091 template< typename Type // Data type of the matrix
2092  , bool SO > // Storage order
2093 inline bool DynamicMatrix<Type,SO>::canSMPAssign() const noexcept
2094 {
2095  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2096 }
2097 //*************************************************************************************************
2098 
2099 
2100 //*************************************************************************************************
2115 template< typename Type // Data type of the matrix
2116  , bool SO > // Storage order
2118  DynamicMatrix<Type,SO>::load( size_t i, size_t j ) const noexcept
2119 {
2120  if( usePadding )
2121  return loada( i, j );
2122  else
2123  return loadu( i, j );
2124 }
2125 //*************************************************************************************************
2126 
2127 
2128 //*************************************************************************************************
2143 template< typename Type // Data type of the matrix
2144  , bool SO > // Storage order
2146  DynamicMatrix<Type,SO>::loada( size_t i, size_t j ) const noexcept
2147 {
2148  using blaze::loada;
2149 
2151 
2152  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2153  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2154  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2155  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2156  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2157 
2158  return loada( v_+i*nn_+j );
2159 }
2160 //*************************************************************************************************
2161 
2162 
2163 //*************************************************************************************************
2178 template< typename Type // Data type of the matrix
2179  , bool SO > // Storage order
2181  DynamicMatrix<Type,SO>::loadu( size_t i, size_t j ) const noexcept
2182 {
2183  using blaze::loadu;
2184 
2186 
2187  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2188  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2189  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2190 
2191  return loadu( v_+i*nn_+j );
2192 }
2193 //*************************************************************************************************
2194 
2195 
2196 //*************************************************************************************************
2212 template< typename Type // Data type of the matrix
2213  , bool SO > // Storage order
2215  DynamicMatrix<Type,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2216 {
2217  if( usePadding )
2218  storea( i, j, value );
2219  else
2220  storeu( i, j, value );
2221 }
2222 //*************************************************************************************************
2223 
2224 
2225 //*************************************************************************************************
2241 template< typename Type // Data type of the matrix
2242  , bool SO > // Storage order
2244  DynamicMatrix<Type,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2245 {
2246  using blaze::storea;
2247 
2249 
2250  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2251  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2252  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2253  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2254  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2255 
2256  storea( v_+i*nn_+j, value );
2257 }
2258 //*************************************************************************************************
2259 
2260 
2261 //*************************************************************************************************
2277 template< typename Type // Data type of the matrix
2278  , bool SO > // Storage order
2280  DynamicMatrix<Type,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2281 {
2282  using blaze::storeu;
2283 
2285 
2286  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2287  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2288  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2289 
2290  storeu( v_+i*nn_+j, value );
2291 }
2292 //*************************************************************************************************
2293 
2294 
2295 //*************************************************************************************************
2312 template< typename Type // Data type of the matrix
2313  , bool SO > // Storage order
2315  DynamicMatrix<Type,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2316 {
2317  using blaze::stream;
2318 
2320 
2321  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2322  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2323  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2324  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2325  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2326 
2327  stream( v_+i*nn_+j, value );
2328 }
2329 //*************************************************************************************************
2330 
2331 
2332 //*************************************************************************************************
2343 template< typename Type // Data type of the matrix
2344  , bool SO > // Storage order
2345 template< typename MT > // Type of the right-hand side dense matrix
2348 {
2349  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2350  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2351 
2352  const size_t jpos( n_ & size_t(-2) );
2353  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2354 
2355  for( size_t i=0UL; i<m_; ++i ) {
2356  for( size_t j=0UL; j<jpos; j+=2UL ) {
2357  v_[i*nn_+j ] = (~rhs)(i,j );
2358  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
2359  }
2360  if( jpos < n_ ) {
2361  v_[i*nn_+jpos] = (~rhs)(i,jpos);
2362  }
2363  }
2364 }
2365 //*************************************************************************************************
2366 
2367 
2368 //*************************************************************************************************
2379 template< typename Type // Data type of the matrix
2380  , bool SO > // Storage order
2381 template< typename MT > // Type of the right-hand side dense matrix
2384 {
2386 
2387  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2388  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2389 
2390  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2391 
2392  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2393  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2394 
2395  if( usePadding && useStreaming &&
2396  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
2397  {
2398  for( size_t i=0UL; i<m_; ++i )
2399  {
2400  size_t j( 0UL );
2401  Iterator left( begin(i) );
2402  ConstIterator_<MT> right( (~rhs).begin(i) );
2403 
2404  for( ; j<jpos; j+=SIMDSIZE, left+=SIMDSIZE, right+=SIMDSIZE ) {
2405  left.stream( right.load() );
2406  }
2407  for( ; remainder && j<n_; ++j, ++left, ++right ) {
2408  *left = *right;
2409  }
2410  }
2411  }
2412  else
2413  {
2414  for( size_t i=0UL; i<m_; ++i )
2415  {
2416  size_t j( 0UL );
2417  Iterator left( begin(i) );
2418  ConstIterator_<MT> right( (~rhs).begin(i) );
2419 
2420  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2421  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2422  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2423  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2424  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2425  }
2426  for( ; j<jpos; j+=SIMDSIZE ) {
2427  left.store( right.load() ); left+=SIMDSIZE, right+=SIMDSIZE;
2428  }
2429  for( ; remainder && j<n_; ++j ) {
2430  *left = *right; ++left; ++right;
2431  }
2432  }
2433  }
2434 }
2435 //*************************************************************************************************
2436 
2437 
2438 //*************************************************************************************************
2449 template< typename Type // Data type of the matrix
2450  , bool SO > // Storage order
2451 template< typename MT > // Type of the right-hand side dense matrix
2453 {
2455 
2456  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2457  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2458 
2459  constexpr size_t block( BLOCK_SIZE );
2460 
2461  for( size_t ii=0UL; ii<m_; ii+=block ) {
2462  const size_t iend( min( m_, ii+block ) );
2463  for( size_t jj=0UL; jj<n_; jj+=block ) {
2464  const size_t jend( min( n_, jj+block ) );
2465  for( size_t i=ii; i<iend; ++i ) {
2466  for( size_t j=jj; j<jend; ++j ) {
2467  v_[i*nn_+j] = (~rhs)(i,j);
2468  }
2469  }
2470  }
2471  }
2472 }
2473 //*************************************************************************************************
2474 
2475 
2476 //*************************************************************************************************
2487 template< typename Type // Data type of the matrix
2488  , bool SO > // Storage order
2489 template< typename MT > // Type of the right-hand side sparse matrix
2491 {
2492  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2493  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2494 
2495  for( size_t i=0UL; i<m_; ++i )
2496  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2497  v_[i*nn_+element->index()] = element->value();
2498 }
2499 //*************************************************************************************************
2500 
2501 
2502 //*************************************************************************************************
2513 template< typename Type // Data type of the matrix
2514  , bool SO > // Storage order
2515 template< typename MT > // Type of the right-hand side sparse matrix
2517 {
2519 
2520  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2521  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2522 
2523  for( size_t j=0UL; j<n_; ++j )
2524  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2525  v_[element->index()*nn_+j] = element->value();
2526 }
2527 //*************************************************************************************************
2528 
2529 
2530 //*************************************************************************************************
2541 template< typename Type // Data type of the matrix
2542  , bool SO > // Storage order
2543 template< typename MT > // Type of the right-hand side dense matrix
2544 inline DisableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2546 {
2547  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2548  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2549 
2550  for( size_t i=0UL; i<m_; ++i )
2551  {
2552  if( IsDiagonal<MT>::value )
2553  {
2554  v_[i*nn_+i] += (~rhs)(i,i);
2555  }
2556  else
2557  {
2558  const size_t jbegin( ( IsUpper<MT>::value )
2559  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2560  :( 0UL ) );
2561  const size_t jend ( ( IsLower<MT>::value )
2562  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2563  :( n_ ) );
2564  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2565 
2566  size_t j( jbegin );
2567 
2568  for( ; (j+2UL) <= jend; j+=2UL ) {
2569  v_[i*nn_+j ] += (~rhs)(i,j );
2570  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
2571  }
2572  if( j < jend ) {
2573  v_[i*nn_+j] += (~rhs)(i,j);
2574  }
2575  }
2576  }
2577 }
2578 //*************************************************************************************************
2579 
2580 
2581 //*************************************************************************************************
2592 template< typename Type // Data type of the matrix
2593  , bool SO > // Storage order
2594 template< typename MT > // Type of the right-hand side dense matrix
2595 inline EnableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2597 {
2600 
2601  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2602  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2603 
2604  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2605 
2606  for( size_t i=0UL; i<m_; ++i )
2607  {
2608  const size_t jbegin( ( IsUpper<MT>::value )
2609  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2610  :( 0UL ) );
2611  const size_t jend ( ( IsLower<MT>::value )
2612  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2613  :( n_ ) );
2614  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2615 
2616  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2617  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2618 
2619  size_t j( jbegin );
2620  Iterator left( begin(i) + jbegin );
2621  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2622 
2623  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2624  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2625  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2626  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2627  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2628  }
2629  for( ; j<jpos; j+=SIMDSIZE ) {
2630  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2631  }
2632  for( ; remainder && j<jend; ++j ) {
2633  *left += *right; ++left; ++right;
2634  }
2635  }
2636 }
2637 //*************************************************************************************************
2638 
2639 
2640 //*************************************************************************************************
2651 template< typename Type // Data type of the matrix
2652  , bool SO > // Storage order
2653 template< typename MT > // Type of the right-hand side dense matrix
2655 {
2657 
2658  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2659  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2660 
2661  constexpr size_t block( BLOCK_SIZE );
2662 
2663  for( size_t ii=0UL; ii<m_; ii+=block ) {
2664  const size_t iend( min( m_, ii+block ) );
2665  for( size_t jj=0UL; jj<n_; jj+=block )
2666  {
2667  if( IsLower<MT>::value && ii < jj ) break;
2668  if( IsUpper<MT>::value && ii > jj ) continue;
2669 
2670  for( size_t i=ii; i<iend; ++i )
2671  {
2672  const size_t jbegin( ( IsUpper<MT>::value )
2673  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2674  :( jj ) );
2675  const size_t jend ( ( IsLower<MT>::value )
2676  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2677  :( min( n_, jj+block ) ) );
2678  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2679 
2680  for( size_t j=jbegin; j<jend; ++j ) {
2681  v_[i*nn_+j] += (~rhs)(i,j);
2682  }
2683  }
2684  }
2685  }
2686 }
2687 //*************************************************************************************************
2688 
2689 
2690 //*************************************************************************************************
2701 template< typename Type // Data type of the matrix
2702  , bool SO > // Storage order
2703 template< typename MT > // Type of the right-hand side sparse matrix
2705 {
2706  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2707  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2708 
2709  for( size_t i=0UL; i<m_; ++i )
2710  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2711  v_[i*nn_+element->index()] += element->value();
2712 }
2713 //*************************************************************************************************
2714 
2715 
2716 //*************************************************************************************************
2727 template< typename Type // Data type of the matrix
2728  , bool SO > // Storage order
2729 template< typename MT > // Type of the right-hand side sparse matrix
2731 {
2733 
2734  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2735  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2736 
2737  for( size_t j=0UL; j<n_; ++j )
2738  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2739  v_[element->index()*nn_+j] += element->value();
2740 }
2741 //*************************************************************************************************
2742 
2743 
2744 //*************************************************************************************************
2755 template< typename Type // Data type of the matrix
2756  , bool SO > // Storage order
2757 template< typename MT > // Type of the right-hand side dense matrix
2758 inline DisableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
2760 {
2761  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2762  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2763 
2764  for( size_t i=0UL; i<m_; ++i )
2765  {
2766  if( IsDiagonal<MT>::value )
2767  {
2768  v_[i*nn_+i] -= (~rhs)(i,i);
2769  }
2770  else
2771  {
2772  const size_t jbegin( ( IsUpper<MT>::value )
2773  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2774  :( 0UL ) );
2775  const size_t jend ( ( IsLower<MT>::value )
2776  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2777  :( n_ ) );
2778  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2779 
2780  size_t j( jbegin );
2781 
2782  for( ; (j+2UL) <= jend; j+=2UL ) {
2783  v_[i*nn_+j ] -= (~rhs)(i,j );
2784  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
2785  }
2786  if( j < jend ) {
2787  v_[i*nn_+j] -= (~rhs)(i,j);
2788  }
2789  }
2790  }
2791 }
2792 //*************************************************************************************************
2793 
2794 
2795 //*************************************************************************************************
2806 template< typename Type // Data type of the matrix
2807  , bool SO > // Storage order
2808 template< typename MT > // Type of the right-hand side dense matrix
2809 inline EnableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
2811 {
2814 
2815  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2816  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2817 
2818  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2819 
2820  for( size_t i=0UL; i<m_; ++i )
2821  {
2822  const size_t jbegin( ( IsUpper<MT>::value )
2823  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2824  :( 0UL ) );
2825  const size_t jend ( ( IsLower<MT>::value )
2826  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2827  :( n_ ) );
2828  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2829 
2830  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2831  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2832 
2833  size_t j( jbegin );
2834  Iterator left( begin(i) + jbegin );
2835  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2836 
2837  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2838  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2839  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2840  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2841  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2842  }
2843  for( ; j<jpos; j+=SIMDSIZE ) {
2844  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2845  }
2846  for( ; remainder && j<jend; ++j ) {
2847  *left -= *right; ++left; ++right;
2848  }
2849  }
2850 }
2851 //*************************************************************************************************
2852 
2853 
2854 //*************************************************************************************************
2865 template< typename Type // Data type of the matrix
2866  , bool SO > // Storage order
2867 template< typename MT > // Type of the right-hand side dense matrix
2869 {
2871 
2872  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2873  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2874 
2875  constexpr size_t block( BLOCK_SIZE );
2876 
2877  for( size_t ii=0UL; ii<m_; ii+=block ) {
2878  const size_t iend( min( m_, ii+block ) );
2879  for( size_t jj=0UL; jj<n_; jj+=block )
2880  {
2881  if( IsLower<MT>::value && ii < jj ) break;
2882  if( IsUpper<MT>::value && ii > jj ) continue;
2883 
2884  for( size_t i=ii; i<iend; ++i )
2885  {
2886  const size_t jbegin( ( IsUpper<MT>::value )
2887  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2888  :( jj ) );
2889  const size_t jend ( ( IsLower<MT>::value )
2890  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2891  :( min( n_, jj+block ) ) );
2892  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2893 
2894  for( size_t j=jbegin; j<jend; ++j ) {
2895  v_[i*nn_+j] -= (~rhs)(i,j);
2896  }
2897  }
2898  }
2899  }
2900 }
2901 //*************************************************************************************************
2902 
2903 
2904 //*************************************************************************************************
2915 template< typename Type // Data type of the matrix
2916  , bool SO > // Storage order
2917 template< typename MT > // Type of the right-hand side sparse matrix
2919 {
2920  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2921  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2922 
2923  for( size_t i=0UL; i<m_; ++i )
2924  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2925  v_[i*nn_+element->index()] -= element->value();
2926 }
2927 //*************************************************************************************************
2928 
2929 
2930 //*************************************************************************************************
2941 template< typename Type // Data type of the matrix
2942  , bool SO > // Storage order
2943 template< typename MT > // Type of the right-hand side sparse matrix
2945 {
2947 
2948  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2949  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2950 
2951  for( size_t j=0UL; j<n_; ++j )
2952  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2953  v_[element->index()*nn_+j] -= element->value();
2954 }
2955 //*************************************************************************************************
2956 
2957 
2958 
2959 
2960 
2961 
2962 
2963 
2964 //=================================================================================================
2965 //
2966 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2967 //
2968 //=================================================================================================
2969 
2970 //*************************************************************************************************
2978 template< typename Type > // Data type of the matrix
2979 class DynamicMatrix<Type,true> : public DenseMatrix< DynamicMatrix<Type,true>, true >
2980 {
2981  public:
2982  //**Type definitions****************************************************************************
2983  typedef DynamicMatrix<Type,true> This;
2985  typedef This ResultType;
2988  typedef Type ElementType;
2990  typedef const Type& ReturnType;
2991  typedef const This& CompositeType;
2992 
2993  typedef Type& Reference;
2994  typedef const Type& ConstReference;
2995  typedef Type* Pointer;
2996  typedef const Type* ConstPointer;
2997 
3000  //**********************************************************************************************
3001 
3002  //**Rebind struct definition********************************************************************
3005  template< typename NewType > // Data type of the other matrix
3006  struct Rebind {
3007  typedef DynamicMatrix<NewType,true> Other;
3008  };
3009  //**********************************************************************************************
3010 
3011  //**Resize struct definition********************************************************************
3014  template< size_t NewM // Number of rows of the other matrix
3015  , size_t NewN > // Number of columns of the other matrix
3016  struct Resize {
3017  typedef DynamicMatrix<Type,true> Other;
3018  };
3019  //**********************************************************************************************
3020 
3021  //**Compilation flags***************************************************************************
3023 
3027  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3028 
3030 
3033  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
3034  //**********************************************************************************************
3035 
3036  //**Constructors********************************************************************************
3039  explicit inline DynamicMatrix() noexcept;
3040  explicit inline DynamicMatrix( size_t m, size_t n );
3041  explicit inline DynamicMatrix( size_t m, size_t n, const Type& init );
3042  explicit inline DynamicMatrix( initializer_list< initializer_list<Type> > list );
3043 
3044  template< typename Other > explicit inline DynamicMatrix( size_t m, size_t n, const Other* array );
3045 
3046  template< typename Other, size_t M, size_t N >
3047  explicit inline DynamicMatrix( const Other (&array)[M][N] );
3048 
3049  inline DynamicMatrix( const DynamicMatrix& m );
3050  inline DynamicMatrix( DynamicMatrix&& m );
3051  template< typename MT, bool SO > inline DynamicMatrix( const Matrix<MT,SO>& m );
3053  //**********************************************************************************************
3054 
3055  //**Destructor**********************************************************************************
3058  inline ~DynamicMatrix();
3060  //**********************************************************************************************
3061 
3062  //**Data access functions***********************************************************************
3065  inline Reference operator()( size_t i, size_t j ) noexcept;
3066  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3067  inline Reference at( size_t i, size_t j );
3068  inline ConstReference at( size_t i, size_t j ) const;
3069  inline Pointer data () noexcept;
3070  inline ConstPointer data () const noexcept;
3071  inline Pointer data ( size_t j ) noexcept;
3072  inline ConstPointer data ( size_t j ) const noexcept;
3073  inline Iterator begin ( size_t j ) noexcept;
3074  inline ConstIterator begin ( size_t j ) const noexcept;
3075  inline ConstIterator cbegin( size_t j ) const noexcept;
3076  inline Iterator end ( size_t j ) noexcept;
3077  inline ConstIterator end ( size_t j ) const noexcept;
3078  inline ConstIterator cend ( size_t j ) const noexcept;
3080  //**********************************************************************************************
3081 
3082  //**Assignment operators************************************************************************
3085  inline DynamicMatrix& operator=( const Type& rhs );
3086  inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list );
3087 
3088  template< typename Other, size_t M, size_t N >
3089  inline DynamicMatrix& operator=( const Other (&array)[M][N] );
3090 
3091  inline DynamicMatrix& operator=( const DynamicMatrix& rhs );
3092  inline DynamicMatrix& operator=( DynamicMatrix&& rhs );
3093 
3094  template< typename MT, bool SO > inline DynamicMatrix& operator= ( const Matrix<MT,SO>& rhs );
3095  template< typename MT, bool SO > inline DynamicMatrix& operator+=( const Matrix<MT,SO>& rhs );
3096  template< typename MT, bool SO > inline DynamicMatrix& operator-=( const Matrix<MT,SO>& rhs );
3097  template< typename MT, bool SO > inline DynamicMatrix& operator*=( const Matrix<MT,SO>& rhs );
3098 
3099  template< typename Other >
3100  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator*=( Other rhs );
3101 
3102  template< typename Other >
3103  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator/=( Other rhs );
3105  //**********************************************************************************************
3106 
3107  //**Utility functions***************************************************************************
3110  inline size_t rows() const noexcept;
3111  inline size_t columns() const noexcept;
3112  inline size_t spacing() const noexcept;
3113  inline size_t capacity() const noexcept;
3114  inline size_t capacity( size_t j ) const noexcept;
3115  inline size_t nonZeros() const;
3116  inline size_t nonZeros( size_t j ) const;
3117  inline void reset();
3118  inline void reset( size_t j );
3119  inline void clear();
3120  void resize ( size_t m, size_t n, bool preserve=true );
3121  inline void extend ( size_t m, size_t n, bool preserve=true );
3122  inline void reserve( size_t elements );
3123  inline void swap( DynamicMatrix& m ) noexcept;
3125  //**********************************************************************************************
3126 
3127  //**Numeric functions***************************************************************************
3130  inline DynamicMatrix& transpose();
3131  inline DynamicMatrix& ctranspose();
3132 
3133  template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
3135  //**********************************************************************************************
3136 
3137  private:
3138  //**********************************************************************************************
3140  template< typename MT >
3141  struct VectorizedAssign {
3142  enum : bool { value = useOptimizedKernels &&
3143  simdEnabled && MT::simdEnabled &&
3145  };
3146  //**********************************************************************************************
3147 
3148  //**********************************************************************************************
3150  template< typename MT >
3151  struct VectorizedAddAssign {
3152  enum : bool { value = useOptimizedKernels &&
3153  simdEnabled && MT::simdEnabled &&
3157  };
3158  //**********************************************************************************************
3159 
3160  //**********************************************************************************************
3162  template< typename MT >
3163  struct VectorizedSubAssign {
3164  enum : bool { value = useOptimizedKernels &&
3165  simdEnabled && MT::simdEnabled &&
3169  };
3170  //**********************************************************************************************
3171 
3172  //**********************************************************************************************
3174  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3175  //**********************************************************************************************
3176 
3177  public:
3178  //**Debugging functions*************************************************************************
3181  inline bool isIntact() const noexcept;
3183  //**********************************************************************************************
3184 
3185  //**Expression template evaluation functions****************************************************
3188  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3189  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3190 
3191  inline bool isAligned () const noexcept;
3192  inline bool canSMPAssign() const noexcept;
3193 
3194  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3195  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3196  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3197 
3198  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3199  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3200  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3201  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3202 
3203  template< typename MT >
3204  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3205 
3206  template< typename MT >
3207  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3208 
3209  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3210  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3211  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3212 
3213  template< typename MT >
3214  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3215 
3216  template< typename MT >
3217  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3218 
3219  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3220  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3221  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3222 
3223  template< typename MT >
3224  inline DisableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3225 
3226  template< typename MT >
3227  inline EnableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3228 
3229  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3230  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3231  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3233  //**********************************************************************************************
3234 
3235  private:
3236  //**Utility functions***************************************************************************
3239  inline size_t adjustRows( size_t minRows ) const noexcept;
3241  //**********************************************************************************************
3242 
3243  //**Member variables****************************************************************************
3246  size_t m_;
3247  size_t mm_;
3248  size_t n_;
3249  size_t capacity_;
3250  Type* BLAZE_RESTRICT v_;
3251 
3254  //**********************************************************************************************
3255 
3256  //**Compile time checks*************************************************************************
3261  //**********************************************************************************************
3262 };
3264 //*************************************************************************************************
3265 
3266 
3267 
3268 
3269 //=================================================================================================
3270 //
3271 // CONSTRUCTORS
3272 //
3273 //=================================================================================================
3274 
3275 //*************************************************************************************************
3279 template< typename Type > // Data type of the matrix
3281  : m_ ( 0UL ) // The current number of rows of the matrix
3282  , mm_ ( 0UL ) // The alignment adjusted number of rows
3283  , n_ ( 0UL ) // The current number of columns of the matrix
3284  , capacity_( 0UL ) // The maximum capacity of the matrix
3285  , v_ ( nullptr ) // The matrix elements
3286 {}
3288 //*************************************************************************************************
3289 
3290 
3291 //*************************************************************************************************
3301 template< typename Type > // Data type of the matrix
3302 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n )
3303  : m_ ( m ) // The current number of rows of the matrix
3304  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
3305  , n_ ( n ) // The current number of columns of the matrix
3306  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3307  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3308 {
3310  for( size_t j=0UL; j<n_; ++j ) {
3311  for( size_t i=m_; i<mm_; ++i ) {
3312  v_[i+j*mm_] = Type();
3313  }
3314  }
3315  }
3316 
3317  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3318 }
3320 //*************************************************************************************************
3321 
3322 
3323 //*************************************************************************************************
3333 template< typename Type > // Data type of the matrix
3334 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, const Type& init )
3335  : m_ ( m ) // The current number of rows of the matrix
3336  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
3337  , n_ ( n ) // The current number of columns of the matrix
3338  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3339  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3340 {
3341  for( size_t j=0UL; j<n_; ++j ) {
3342  for( size_t i=0UL; i<m_; ++i )
3343  v_[i+j*mm_] = init;
3344 
3346  for( size_t i=m_; i<mm_; ++i )
3347  v_[i+j*mm_] = Type();
3348  }
3349  }
3350 
3351  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3352 }
3354 //*************************************************************************************************
3355 
3356 
3357 //*************************************************************************************************
3378 template< typename Type > // Data type of the matrix
3380  : m_ ( list.size() ) // The current number of rows of the matrix
3381  , mm_ ( adjustRows( m_ ) ) // The alignment adjusted number of rows
3382  , n_ ( determineColumns( list ) ) // The current number of columns of the matrix
3383  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3384  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3385 {
3386  size_t i( 0UL );
3387 
3388  for( const auto& rowList : list ) {
3389  size_t j( 0UL );
3390  for( const auto& element : rowList ) {
3391  v_[i+j*mm_] = element;
3392  ++j;
3393  }
3394  for( ; j<n_; ++j ) {
3395  v_[i+j*mm_] = Type();
3396  }
3397  ++i;
3398  }
3399 
3400  BLAZE_INTERNAL_ASSERT( i == m_, "Invalid number of elements detected" );
3401 
3403  for( ; i<mm_; ++i ) {
3404  for( size_t j=0UL; j<n_; ++j ) {
3405  v_[i+j*mm_] = Type();
3406  }
3407  }
3408  }
3409 
3410  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3411 }
3413 //*************************************************************************************************
3414 
3415 
3416 //*************************************************************************************************
3440 template< typename Type > // Data type of the matrix
3441 template< typename Other > // Data type of the initialization array
3442 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, const Other* array )
3443  : m_ ( m ) // The current number of rows of the matrix
3444  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
3445  , n_ ( n ) // The current number of columns of the matrix
3446  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3447  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3448 {
3449  for( size_t j=0UL; j<n; ++j ) {
3450  for( size_t i=0UL; i<m; ++i )
3451  v_[i+j*mm_] = array[i+j*m];
3452 
3454  for( size_t i=m; i<mm_; ++i )
3455  v_[i+j*mm_] = Type();
3456  }
3457  }
3458 
3459  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3460 }
3462 //*************************************************************************************************
3463 
3464 
3465 //*************************************************************************************************
3487 template< typename Type > // Data type of the matrix
3488 template< typename Other // Data type of the initialization array
3489  , size_t M // Number of rows of the initialization array
3490  , size_t N > // Number of columns of the initialization array
3491 inline DynamicMatrix<Type,true>::DynamicMatrix( const Other (&array)[M][N] )
3492  : m_ ( M ) // The current number of rows of the matrix
3493  , mm_ ( adjustRows( M ) ) // The alignment adjusted number of rows
3494  , n_ ( N ) // The current number of columns of the matrix
3495  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3496  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3497 {
3498  for( size_t j=0UL; j<N; ++j ) {
3499  for( size_t i=0UL; i<M; ++i )
3500  v_[i+j*mm_] = array[i][j];
3501 
3503  for( size_t i=M; i<mm_; ++i )
3504  v_[i+j*mm_] = Type();
3505  }
3506  }
3507 
3508  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3509 }
3511 //*************************************************************************************************
3512 
3513 
3514 //*************************************************************************************************
3523 template< typename Type > // Data type of the matrix
3525  : m_ ( m.m_ ) // The current number of rows of the matrix
3526  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
3527  , n_ ( m.n_ ) // The current number of columns of the matrix
3528  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3529  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3530 {
3531  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
3532 
3533  for( size_t i=0UL; i<capacity_; ++i )
3534  v_[i] = m.v_[i];
3535 
3536  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3537 }
3539 //*************************************************************************************************
3540 
3541 
3542 //*************************************************************************************************
3548 template< typename Type > // Data type of the matrix
3550  : m_ ( m.m_ ) // The current number of rows of the matrix
3551  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
3552  , n_ ( m.n_ ) // The current number of columns of the matrix
3553  , capacity_( m.capacity_ ) // The maximum capacity of the matrix
3554  , v_ ( m.v_ ) // The matrix elements
3555 {
3556  m.m_ = 0UL;
3557  m.mm_ = 0UL;
3558  m.n_ = 0UL;
3559  m.capacity_ = 0UL;
3560  m.v_ = nullptr;
3561 }
3563 //*************************************************************************************************
3564 
3565 
3566 //*************************************************************************************************
3572 template< typename Type > // Data type of the matrix
3573 template< typename MT // Type of the foreign matrix
3574  , bool SO > // Storage order of the foreign matrix
3576  : m_ ( (~m).rows() ) // The current number of rows of the matrix
3577  , mm_ ( adjustRows( m_ ) ) // The alignment adjusted number of rows
3578  , n_ ( (~m).columns() ) // The current number of columns of the matrix
3579  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3580  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3581 {
3582  for( size_t j=0UL; j<n_; ++j ) {
3583  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : m_ );
3584  i<( IsVectorizable<Type>::value ? mm_ : m_ ); ++i ) {
3585  v_[i+j*mm_] = Type();
3586  }
3587  }
3588 
3589  smpAssign( *this, ~m );
3590 
3591  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3592 }
3594 //*************************************************************************************************
3595 
3596 
3597 
3598 
3599 //=================================================================================================
3600 //
3601 // DESTRUCTOR
3602 //
3603 //=================================================================================================
3604 
3605 //*************************************************************************************************
3609 template< typename Type > // Data type of the matrix
3611 {
3612  deallocate( v_ );
3613 }
3615 //*************************************************************************************************
3616 
3617 
3618 
3619 
3620 //=================================================================================================
3621 //
3622 // DATA ACCESS FUNCTIONS
3623 //
3624 //=================================================================================================
3625 
3626 //*************************************************************************************************
3637 template< typename Type > // Data type of the matrix
3639  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) noexcept
3640 {
3641  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3642  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3643  return v_[i+j*mm_];
3644 }
3646 //*************************************************************************************************
3647 
3648 
3649 //*************************************************************************************************
3660 template< typename Type > // Data type of the matrix
3662  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) const noexcept
3663 {
3664  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3665  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3666  return v_[i+j*mm_];
3667 }
3669 //*************************************************************************************************
3670 
3671 
3672 //*************************************************************************************************
3684 template< typename Type > // Data type of the matrix
3686  DynamicMatrix<Type,true>::at( size_t i, size_t j )
3687 {
3688  if( i >= m_ ) {
3689  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3690  }
3691  if( j >= n_ ) {
3692  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3693  }
3694  return (*this)(i,j);
3695 }
3697 //*************************************************************************************************
3698 
3699 
3700 //*************************************************************************************************
3712 template< typename Type > // Data type of the matrix
3714  DynamicMatrix<Type,true>::at( size_t i, size_t j ) const
3715 {
3716  if( i >= m_ ) {
3717  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3718  }
3719  if( j >= n_ ) {
3720  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3721  }
3722  return (*this)(i,j);
3723 }
3725 //*************************************************************************************************
3726 
3727 
3728 //*************************************************************************************************
3740 template< typename Type > // Data type of the matrix
3741 inline typename DynamicMatrix<Type,true>::Pointer
3743 {
3744  return v_;
3745 }
3747 //*************************************************************************************************
3748 
3749 
3750 //*************************************************************************************************
3762 template< typename Type > // Data type of the matrix
3764  DynamicMatrix<Type,true>::data() const noexcept
3765 {
3766  return v_;
3767 }
3769 //*************************************************************************************************
3770 
3771 
3772 //*************************************************************************************************
3781 template< typename Type > // Data type of the matrix
3782 inline typename DynamicMatrix<Type,true>::Pointer
3783  DynamicMatrix<Type,true>::data( size_t j ) noexcept
3784 {
3785  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3786  return v_ + j*mm_;
3787 }
3789 //*************************************************************************************************
3790 
3791 
3792 //*************************************************************************************************
3801 template< typename Type > // Data type of the matrix
3803  DynamicMatrix<Type,true>::data( size_t j ) const noexcept
3804 {
3805  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3806  return v_ + j*mm_;
3807 }
3809 //*************************************************************************************************
3810 
3811 
3812 //*************************************************************************************************
3819 template< typename Type > // Data type of the matrix
3820 inline typename DynamicMatrix<Type,true>::Iterator
3821  DynamicMatrix<Type,true>::begin( size_t j ) noexcept
3822 {
3823  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3824  return Iterator( v_ + j*mm_ );
3825 }
3827 //*************************************************************************************************
3828 
3829 
3830 //*************************************************************************************************
3837 template< typename Type > // Data type of the matrix
3839  DynamicMatrix<Type,true>::begin( size_t j ) const noexcept
3840 {
3841  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3842  return ConstIterator( v_ + j*mm_ );
3843 }
3845 //*************************************************************************************************
3846 
3847 
3848 //*************************************************************************************************
3855 template< typename Type > // Data type of the matrix
3857  DynamicMatrix<Type,true>::cbegin( size_t j ) const noexcept
3858 {
3859  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3860  return ConstIterator( v_ + j*mm_ );
3861 }
3863 //*************************************************************************************************
3864 
3865 
3866 //*************************************************************************************************
3873 template< typename Type > // Data type of the matrix
3874 inline typename DynamicMatrix<Type,true>::Iterator
3875  DynamicMatrix<Type,true>::end( size_t j ) noexcept
3876 {
3877  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3878  return Iterator( v_ + j*mm_ + m_ );
3879 }
3881 //*************************************************************************************************
3882 
3883 
3884 //*************************************************************************************************
3891 template< typename Type > // Data type of the matrix
3893  DynamicMatrix<Type,true>::end( size_t j ) const noexcept
3894 {
3895  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3896  return ConstIterator( v_ + j*mm_ + m_ );
3897 }
3899 //*************************************************************************************************
3900 
3901 
3902 //*************************************************************************************************
3909 template< typename Type > // Data type of the matrix
3911  DynamicMatrix<Type,true>::cend( size_t j ) const noexcept
3912 {
3913  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3914  return ConstIterator( v_ + j*mm_ + m_ );
3915 }
3917 //*************************************************************************************************
3918 
3919 
3920 
3921 
3922 //=================================================================================================
3923 //
3924 // ASSIGNMENT OPERATORS
3925 //
3926 //=================================================================================================
3927 
3928 //*************************************************************************************************
3935 template< typename Type > // Data type of the matrix
3937 {
3938  for( size_t j=0UL; j<n_; ++j )
3939  for( size_t i=0UL; i<m_; ++i )
3940  v_[i+j*mm_] = rhs;
3941 
3942  return *this;
3943 }
3945 //*************************************************************************************************
3946 
3947 
3948 //*************************************************************************************************
3970 template< typename Type > // Data type of the matrix
3973 {
3974  resize( list.size(), determineColumns( list ), false );
3975 
3976  size_t i( 0UL );
3977 
3978  for( const auto& rowList : list ) {
3979  size_t j( 0UL );
3980  for( const auto& element : rowList ) {
3981  v_[i+j*mm_] = element;
3982  ++j;
3983  }
3984  for( ; j<n_; ++j ) {
3985  v_[i+j*mm_] = Type();
3986  }
3987  ++i;
3988  }
3989 
3990  return *this;
3991 }
3993 //*************************************************************************************************
3994 
3995 
3996 //*************************************************************************************************
4018 template< typename Type > // Data type of the matrix
4019 template< typename Other // Data type of the initialization array
4020  , size_t M // Number of rows of the initialization array
4021  , size_t N > // Number of columns of the initialization array
4022 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Other (&array)[M][N] )
4023 {
4024  resize( M, N, false );
4025 
4026  for( size_t j=0UL; j<N; ++j )
4027  for( size_t i=0UL; i<M; ++i )
4028  v_[i+j*mm_] = array[i][j];
4029 
4030  return *this;
4031 }
4033 //*************************************************************************************************
4034 
4035 
4036 //*************************************************************************************************
4046 template< typename Type > // Data type of the matrix
4048 {
4049  if( &rhs == this ) return *this;
4050 
4051  resize( rhs.m_, rhs.n_, false );
4052  smpAssign( *this, ~rhs );
4053 
4054  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4055 
4056  return *this;
4057 }
4059 //*************************************************************************************************
4060 
4061 
4062 //*************************************************************************************************
4069 template< typename Type > // Data type of the matrix
4071 {
4072  deallocate( v_ );
4073 
4074  m_ = rhs.m_;
4075  mm_ = rhs.mm_;
4076  n_ = rhs.n_;
4077  capacity_ = rhs.capacity_;
4078  v_ = rhs.v_;
4079 
4080  rhs.m_ = 0UL;
4081  rhs.mm_ = 0UL;
4082  rhs.n_ = 0UL;
4083  rhs.capacity_ = 0UL;
4084  rhs.v_ = nullptr;
4085 
4086  return *this;
4087 }
4089 //*************************************************************************************************
4090 
4091 
4092 //*************************************************************************************************
4102 template< typename Type > // Data type of the matrix
4103 template< typename MT // Type of the right-hand side matrix
4104  , bool SO > // Storage order of the right-hand side matrix
4106 {
4107  typedef TransExprTrait_<This> TT;
4108  typedef CTransExprTrait_<This> CT;
4109  typedef InvExprTrait_<This> IT;
4110 
4111  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4112  transpose();
4113  }
4114  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4115  ctranspose();
4116  }
4117  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4118  DynamicMatrix tmp( ~rhs );
4119  swap( tmp );
4120  }
4121  else {
4122  resize( (~rhs).rows(), (~rhs).columns(), false );
4124  reset();
4125  smpAssign( *this, ~rhs );
4126  }
4127 
4128  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4129 
4130  return *this;
4131 }
4133 //*************************************************************************************************
4134 
4135 
4136 //*************************************************************************************************
4147 template< typename Type > // Data type of the matrix
4148 template< typename MT // Type of the right-hand side matrix
4149  , bool SO > // Storage order of the right-hand side matrix
4151 {
4152  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4153  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4154  }
4155 
4156  if( (~rhs).canAlias( this ) ) {
4157  const ResultType_<MT> tmp( ~rhs );
4158  smpAddAssign( *this, tmp );
4159  }
4160  else {
4161  smpAddAssign( *this, ~rhs );
4162  }
4163 
4164  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4165 
4166  return *this;
4167 }
4169 //*************************************************************************************************
4170 
4171 
4172 //*************************************************************************************************
4183 template< typename Type > // Data type of the matrix
4184 template< typename MT // Type of the right-hand side matrix
4185  , bool SO > // Storage order of the right-hand side matrix
4187 {
4188  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4189  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4190  }
4191 
4192  if( (~rhs).canAlias( this ) ) {
4193  const ResultType_<MT> tmp( ~rhs );
4194  smpSubAssign( *this, tmp );
4195  }
4196  else {
4197  smpSubAssign( *this, ~rhs );
4198  }
4199 
4200  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4201 
4202  return *this;
4203 }
4205 //*************************************************************************************************
4206 
4207 
4208 //*************************************************************************************************
4219 template< typename Type > // Data type of the matrix
4220 template< typename MT // Type of the right-hand side matrix
4221  , bool SO > // Storage order of the right-hand side matrix
4223 {
4224  if( (~rhs).rows() != n_ ) {
4225  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4226  }
4227 
4228  DynamicMatrix tmp( *this * (~rhs) );
4229  swap( tmp );
4230 
4231  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4232 
4233  return *this;
4234 }
4236 //*************************************************************************************************
4237 
4238 
4239 //*************************************************************************************************
4247 template< typename Type > // Data type of the matrix
4248 template< typename Other > // Data type of the right-hand side scalar
4249 inline EnableIf_<IsNumeric<Other>, DynamicMatrix<Type,true> >&
4251 {
4252  smpAssign( *this, (*this) * rhs );
4253 
4254  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4255 
4256  return *this;
4257 }
4259 //*************************************************************************************************
4260 
4261 
4262 //*************************************************************************************************
4270 template< typename Type > // Data type of the matrix
4271 template< typename Other > // Data type of the right-hand side scalar
4272 inline EnableIf_<IsNumeric<Other>, DynamicMatrix<Type,true> >&
4274 {
4275  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4276 
4277  smpAssign( *this, (*this) / rhs );
4278 
4279  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4280 
4281  return *this;
4282 }
4284 //*************************************************************************************************
4285 
4286 
4287 
4288 
4289 //=================================================================================================
4290 //
4291 // UTILITY FUNCTIONS
4292 //
4293 //=================================================================================================
4294 
4295 //*************************************************************************************************
4301 template< typename Type > // Data type of the matrix
4302 inline size_t DynamicMatrix<Type,true>::rows() const noexcept
4303 {
4304  return m_;
4305 }
4307 //*************************************************************************************************
4308 
4309 
4310 //*************************************************************************************************
4316 template< typename Type > // Data type of the matrix
4317 inline size_t DynamicMatrix<Type,true>::columns() const noexcept
4318 {
4319  return n_;
4320 }
4322 //*************************************************************************************************
4323 
4324 
4325 //*************************************************************************************************
4334 template< typename Type > // Data type of the matrix
4335 inline size_t DynamicMatrix<Type,true>::spacing() const noexcept
4336 {
4337  return mm_;
4338 }
4340 //*************************************************************************************************
4341 
4342 
4343 //*************************************************************************************************
4349 template< typename Type > // Data type of the matrix
4350 inline size_t DynamicMatrix<Type,true>::capacity() const noexcept
4351 {
4352  return capacity_;
4353 }
4355 //*************************************************************************************************
4356 
4357 
4358 //*************************************************************************************************
4365 template< typename Type > // Data type of the matrix
4366 inline size_t DynamicMatrix<Type,true>::capacity( size_t j ) const noexcept
4367 {
4368  UNUSED_PARAMETER( j );
4369  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4370  return mm_;
4371 }
4373 //*************************************************************************************************
4374 
4375 
4376 //*************************************************************************************************
4382 template< typename Type > // Data type of the matrix
4383 inline size_t DynamicMatrix<Type,true>::nonZeros() const
4384 {
4385  size_t nonzeros( 0UL );
4386 
4387  for( size_t j=0UL; j<n_; ++j )
4388  for( size_t i=0UL; i<m_; ++i )
4389  if( !isDefault( v_[i+j*mm_] ) )
4390  ++nonzeros;
4391 
4392  return nonzeros;
4393 }
4395 //*************************************************************************************************
4396 
4397 
4398 //*************************************************************************************************
4405 template< typename Type > // Data type of the matrix
4406 inline size_t DynamicMatrix<Type,true>::nonZeros( size_t j ) const
4407 {
4408  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4409 
4410  const size_t iend( j*mm_ + m_ );
4411  size_t nonzeros( 0UL );
4412 
4413  for( size_t i=j*mm_; i<iend; ++i )
4414  if( !isDefault( v_[i] ) )
4415  ++nonzeros;
4416 
4417  return nonzeros;
4418 }
4420 //*************************************************************************************************
4421 
4422 
4423 //*************************************************************************************************
4429 template< typename Type > // Data type of the matrix
4430 inline void DynamicMatrix<Type,true>::reset()
4431 {
4432  using blaze::clear;
4433 
4434  for( size_t j=0UL; j<n_; ++j )
4435  for( size_t i=0UL; i<m_; ++i )
4436  clear( v_[i+j*mm_] );
4437 }
4439 //*************************************************************************************************
4440 
4441 
4442 //*************************************************************************************************
4452 template< typename Type > // Data type of the matrix
4453 inline void DynamicMatrix<Type,true>::reset( size_t j )
4454 {
4455  using blaze::clear;
4456 
4457  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4458  for( size_t i=0UL; i<m_; ++i )
4459  clear( v_[i+j*mm_] );
4460 }
4462 //*************************************************************************************************
4463 
4464 
4465 //*************************************************************************************************
4473 template< typename Type > // Data type of the matrix
4474 inline void DynamicMatrix<Type,true>::clear()
4475 {
4476  resize( 0UL, 0UL, false );
4477 }
4479 //*************************************************************************************************
4480 
4481 
4482 //*************************************************************************************************
4517 template< typename Type > // Data type of the matrix
4518 void DynamicMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
4519 {
4520  using blaze::min;
4521 
4522  if( m == m_ && n == n_ ) return;
4523 
4524  const size_t mm( adjustRows( m ) );
4525 
4526  if( preserve )
4527  {
4528  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
4529  const size_t min_m( min( m, m_ ) );
4530  const size_t min_n( min( n, n_ ) );
4531 
4532  for( size_t j=0UL; j<min_n; ++j ) {
4533  transfer( v_+j*mm_, v_+min_m+j*mm_, v+j*mm );
4534  }
4535 
4536  std::swap( v_, v );
4537  deallocate( v );
4538  capacity_ = mm*n;
4539  }
4540  else if( mm*n > capacity_ ) {
4541  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
4542  std::swap( v_, v );
4543  deallocate( v );
4544  capacity_ = mm*n;
4545  }
4546 
4548  for( size_t j=0UL; j<n; ++j )
4549  for( size_t i=m; i<mm; ++i )
4550  v_[i+j*mm] = Type();
4551  }
4552 
4553  m_ = m;
4554  mm_ = mm;
4555  n_ = n;
4556 }
4558 //*************************************************************************************************
4559 
4560 
4561 //*************************************************************************************************
4576 template< typename Type > // Data type of the matrix
4577 inline void DynamicMatrix<Type,true>::extend( size_t m, size_t n, bool preserve )
4578 {
4579  resize( m_+m, n_+n, preserve );
4580 }
4582 //*************************************************************************************************
4583 
4584 
4585 //*************************************************************************************************
4595 template< typename Type > // Data type of the matrix
4596 inline void DynamicMatrix<Type,true>::reserve( size_t elements )
4597 {
4598  if( elements > capacity_ )
4599  {
4600  // Allocating a new array
4601  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
4602 
4603  // Initializing the new array
4604  transfer( v_, v_+capacity_, tmp );
4605 
4607  for( size_t i=capacity_; i<elements; ++i )
4608  tmp[i] = Type();
4609  }
4610 
4611  // Replacing the old array
4612  std::swap( tmp, v_ );
4613  deallocate( tmp );
4614  capacity_ = elements;
4615  }
4616 }
4618 //*************************************************************************************************
4619 
4620 
4621 //*************************************************************************************************
4628 template< typename Type > // Data type of the matrix
4629 inline void DynamicMatrix<Type,true>::swap( DynamicMatrix& m ) noexcept
4630 {
4631  std::swap( m_ , m.m_ );
4632  std::swap( mm_, m.mm_ );
4633  std::swap( n_ , m.n_ );
4635  std::swap( v_ , m.v_ );
4636 }
4638 //*************************************************************************************************
4639 
4640 
4641 //*************************************************************************************************
4648 template< typename Type > // Data type of the matrix
4649 inline size_t DynamicMatrix<Type,true>::adjustRows( size_t minRows ) const noexcept
4650 {
4652  return nextMultiple<size_t>( minRows, SIMDSIZE );
4653  else return minRows;
4654 }
4656 //*************************************************************************************************
4657 
4658 
4659 
4660 
4661 //=================================================================================================
4662 //
4663 // NUMERIC FUNCTIONS
4664 //
4665 //=================================================================================================
4666 
4667 //*************************************************************************************************
4673 template< typename Type > // Data type of the matrix
4675 {
4676  using std::swap;
4677 
4678  constexpr size_t block( BLOCK_SIZE );
4679 
4680  if( m_ == n_ )
4681  {
4682  for( size_t jj=0UL; jj<n_; jj+=block ) {
4683  const size_t jend( min( jj+block, n_ ) );
4684  for( size_t ii=0UL; ii<=jj; ii+=block ) {
4685  for( size_t j=jj; j<jend; ++j ) {
4686  const size_t iend( min( ii+block, m_, j ) );
4687  for( size_t i=ii; i<iend; ++i ) {
4688  swap( v_[i+j*mm_], v_[j+i*mm_] );
4689  }
4690  }
4691  }
4692  }
4693  }
4694  else
4695  {
4696  DynamicMatrix tmp( trans(*this) );
4697  this->swap( tmp );
4698  }
4699 
4700  return *this;
4701 }
4703 //*************************************************************************************************
4704 
4705 
4706 //*************************************************************************************************
4712 template< typename Type > // Data type of the matrix
4714 {
4715  constexpr size_t block( BLOCK_SIZE );
4716 
4717  if( m_ == n_ )
4718  {
4719  for( size_t jj=0UL; jj<n_; jj+=block ) {
4720  const size_t jend( min( jj+block, n_ ) );
4721  for( size_t ii=0UL; ii<jj; ii+=block ) {
4722  const size_t iend( min( ii+block, m_ ) );
4723  for( size_t j=jj; j<jend; ++j ) {
4724  for( size_t i=ii; i<iend; ++i ) {
4725  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4726  }
4727  }
4728  }
4729  for( size_t j=jj; j<jend; ++j ) {
4730  for( size_t i=jj; i<j; ++i ) {
4731  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4732  }
4733  conjugate( v_[j+j*mm_] );
4734  }
4735  }
4736  }
4737  else
4738  {
4739  DynamicMatrix tmp( ctrans(*this) );
4740  this->swap( tmp );
4741  }
4742 
4743  return *this;
4744 }
4746 //*************************************************************************************************
4747 
4748 
4749 //*************************************************************************************************
4756 template< typename Type > // Data type of the matrix
4757 template< typename Other > // Data type of the scalar value
4758 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::scale( const Other& scalar )
4759 {
4760  for( size_t j=0UL; j<n_; ++j )
4761  for( size_t i=0UL; i<m_; ++i )
4762  v_[i+j*mm_] *= scalar;
4763 
4764  return *this;
4765 }
4767 //*************************************************************************************************
4768 
4769 
4770 
4771 
4772 //=================================================================================================
4773 //
4774 // DEBUGGING FUNCTIONS
4775 //
4776 //=================================================================================================
4777 
4778 //*************************************************************************************************
4788 template< typename Type > // Data type of the matrix
4789 inline bool DynamicMatrix<Type,true>::isIntact() const noexcept
4790 {
4791  if( m_ * n_ > capacity_ )
4792  return false;
4793 
4795  for( size_t j=0UL; j<n_; ++j ) {
4796  for( size_t i=m_; i<mm_; ++i ) {
4797  if( v_[i+j*mm_] != Type() )
4798  return false;
4799  }
4800  }
4801  }
4802 
4803  return true;
4804 }
4806 //*************************************************************************************************
4807 
4808 
4809 
4810 
4811 //=================================================================================================
4812 //
4813 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4814 //
4815 //=================================================================================================
4816 
4817 //*************************************************************************************************
4828 template< typename Type > // Data type of the matrix
4829 template< typename Other > // Data type of the foreign expression
4830 inline bool DynamicMatrix<Type,true>::canAlias( const Other* alias ) const noexcept
4831 {
4832  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4833 }
4835 //*************************************************************************************************
4836 
4837 
4838 //*************************************************************************************************
4849 template< typename Type > // Data type of the matrix
4850 template< typename Other > // Data type of the foreign expression
4851 inline bool DynamicMatrix<Type,true>::isAliased( const Other* alias ) const noexcept
4852 {
4853  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4854 }
4856 //*************************************************************************************************
4857 
4858 
4859 //*************************************************************************************************
4869 template< typename Type > // Data type of the matrix
4870 inline bool DynamicMatrix<Type,true>::isAligned() const noexcept
4871 {
4872  return ( usePadding || rows() % SIMDSIZE == 0UL );
4873 }
4875 //*************************************************************************************************
4876 
4877 
4878 //*************************************************************************************************
4889 template< typename Type > // Data type of the matrix
4890 inline bool DynamicMatrix<Type,true>::canSMPAssign() const noexcept
4891 {
4892  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
4893 }
4895 //*************************************************************************************************
4896 
4897 
4898 //*************************************************************************************************
4913 template< typename Type > // Data type of the matrix
4915  DynamicMatrix<Type,true>::load( size_t i, size_t j ) const noexcept
4916 {
4917  if( usePadding )
4918  return loada( i, j );
4919  else
4920  return loadu( i, j );
4921 }
4923 //*************************************************************************************************
4924 
4925 
4926 //*************************************************************************************************
4941 template< typename Type > // Data type of the matrix
4943  DynamicMatrix<Type,true>::loada( size_t i, size_t j ) const noexcept
4944 {
4945  using blaze::loada;
4946 
4948 
4949  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4950  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
4951  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
4952  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4953  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
4954 
4955  return loada( v_+i+j*mm_ );
4956 }
4958 //*************************************************************************************************
4959 
4960 
4961 //*************************************************************************************************
4976 template< typename Type > // Data type of the matrix
4978  DynamicMatrix<Type,true>::loadu( size_t i, size_t j ) const noexcept
4979 {
4980  using blaze::loadu;
4981 
4983 
4984  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4985  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
4986  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4987 
4988  return loadu( v_+i+j*mm_ );
4989 }
4991 //*************************************************************************************************
4992 
4993 
4994 //*************************************************************************************************
5010 template< typename Type > // Data type of the matrix
5012  DynamicMatrix<Type,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5013 {
5014  if( usePadding )
5015  storea( i, j, value );
5016  else
5017  storeu( i, j, value );
5018 }
5020 //*************************************************************************************************
5021 
5022 
5023 //*************************************************************************************************
5039 template< typename Type > // Data type of the matrix
5041  DynamicMatrix<Type,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5042 {
5043  using blaze::storea;
5044 
5046 
5047  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5048  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5049  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5050  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5051  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5052 
5053  storea( v_+i+j*mm_, value );
5054 }
5056 //*************************************************************************************************
5057 
5058 
5059 //*************************************************************************************************
5075 template< typename Type > // Data type of the matrix
5077  DynamicMatrix<Type,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5078 {
5079  using blaze::storeu;
5080 
5082 
5083  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5084  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5085  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5086 
5087  storeu( v_+i+j*mm_, value );
5088 }
5090 //*************************************************************************************************
5091 
5092 
5093 //*************************************************************************************************
5110 template< typename Type > // Data type of the matrix
5112  DynamicMatrix<Type,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5113 {
5114  using blaze::stream;
5115 
5117 
5118  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5119  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5120  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5121  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5122  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5123 
5124  stream( v_+i+j*mm_, value );
5125 }
5127 //*************************************************************************************************
5128 
5129 
5130 //*************************************************************************************************
5142 template< typename Type > // Data type of the matrix
5143 template< typename MT > // Type of the right-hand side dense matrix
5146 {
5147  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5148  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5149 
5150  const size_t ipos( m_ & size_t(-2) );
5151  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5152 
5153  for( size_t j=0UL; j<n_; ++j ) {
5154  for( size_t i=0UL; i<ipos; i+=2UL ) {
5155  v_[i +j*mm_] = (~rhs)(i ,j);
5156  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
5157  }
5158  if( ipos < m_ ) {
5159  v_[ipos+j*mm_] = (~rhs)(ipos,j);
5160  }
5161  }
5162 }
5164 //*************************************************************************************************
5165 
5166 
5167 //*************************************************************************************************
5179 template< typename Type > // Data type of the matrix
5180 template< typename MT > // Type of the right-hand side dense matrix
5183 {
5185 
5186  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5187  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5188 
5189  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5190 
5191  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5192  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5193 
5194  if( usePadding && useStreaming &&
5195  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
5196  {
5197  for( size_t j=0UL; j<n_; ++j )
5198  {
5199  size_t i( 0UL );
5200  Iterator left( begin(j) );
5201  ConstIterator_<MT> right( (~rhs).begin(j) );
5202 
5203  for( ; i<ipos; i+=SIMDSIZE ) {
5204  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5205  }
5206  for( ; remainder && i<m_; ++i ) {
5207  *left = *right; ++left; ++right;
5208  }
5209  }
5210  }
5211  else
5212  {
5213  for( size_t j=0UL; j<n_; ++j )
5214  {
5215  size_t i( 0UL );
5216  Iterator left( begin(j) );
5217  ConstIterator_<MT> right( (~rhs).begin(j) );
5218 
5219  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5220  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5221  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5222  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5223  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5224  }
5225  for( ; i<ipos; i+=SIMDSIZE ) {
5226  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5227  }
5228  for( ; remainder && i<m_; ++i ) {
5229  *left = *right; ++left; ++right;
5230  }
5231  }
5232  }
5233 }
5235 //*************************************************************************************************
5236 
5237 
5238 //*************************************************************************************************
5250 template< typename Type > // Data type of the matrix
5251 template< typename MT > // Type of the right-hand side dense matrix
5253 {
5255 
5256  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5257  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5258 
5259  constexpr size_t block( BLOCK_SIZE );
5260 
5261  for( size_t jj=0UL; jj<n_; jj+=block ) {
5262  const size_t jend( min( n_, jj+block ) );
5263  for( size_t ii=0UL; ii<m_; ii+=block ) {
5264  const size_t iend( min( m_, ii+block ) );
5265  for( size_t j=jj; j<jend; ++j ) {
5266  for( size_t i=ii; i<iend; ++i ) {
5267  v_[i+j*mm_] = (~rhs)(i,j);
5268  }
5269  }
5270  }
5271  }
5272 }
5274 //*************************************************************************************************
5275 
5276 
5277 //*************************************************************************************************
5289 template< typename Type > // Data type of the matrix
5290 template< typename MT > // Type of the right-hand side sparse matrix
5292 {
5293  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5294  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5295 
5296  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5297  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5298  v_[element->index()+j*mm_] = element->value();
5299 }
5301 //*************************************************************************************************
5302 
5303 
5304 //*************************************************************************************************
5316 template< typename Type > // Data type of the matrix
5317 template< typename MT > // Type of the right-hand side sparse matrix
5319 {
5321 
5322  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5323  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5324 
5325  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5326  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5327  v_[i+element->index()*mm_] = element->value();
5328 }
5330 //*************************************************************************************************
5331 
5332 
5333 //*************************************************************************************************
5345 template< typename Type > // Data type of the matrix
5346 template< typename MT > // Type of the right-hand side dense matrix
5347 inline DisableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5349 {
5350  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5351  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5352 
5353  for( size_t j=0UL; j<n_; ++j )
5354  {
5355  if( IsDiagonal<MT>::value )
5356  {
5357  v_[j+j*mm_] += (~rhs)(j,j);
5358  }
5359  else
5360  {
5361  const size_t ibegin( ( IsLower<MT>::value )
5362  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5363  :( 0UL ) );
5364  const size_t iend ( ( IsUpper<MT>::value )
5365  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5366  :( m_ ) );
5367  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5368 
5369  size_t i( ibegin );
5370 
5371  for( ; (i+2UL) <= iend; i+=2UL ) {
5372  v_[i +j*mm_] += (~rhs)(i ,j);
5373  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
5374  }
5375  if( i < iend ) {
5376  v_[i+j*mm_] += (~rhs)(i,j);
5377  }
5378  }
5379  }
5380 }
5382 //*************************************************************************************************
5383 
5384 
5385 //*************************************************************************************************
5397 template< typename Type > // Data type of the matrix
5398 template< typename MT > // Type of the right-hand side dense matrix
5399 inline EnableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5401 {
5404 
5405  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5406  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5407 
5408  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5409 
5410  for( size_t j=0UL; j<n_; ++j )
5411  {
5412  const size_t ibegin( ( IsLower<MT>::value )
5413  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5414  :( 0UL ) );
5415  const size_t iend ( ( IsUpper<MT>::value )
5416  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5417  :( m_ ) );
5418  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5419 
5420  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5421  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5422 
5423  size_t i( ibegin );
5424  Iterator left( begin(j) + ibegin );
5425  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
5426 
5427  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5428  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5429  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5430  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5431  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5432  }
5433  for( ; i<ipos; i+=SIMDSIZE ) {
5434  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5435  }
5436  for( ; remainder && i<iend; ++i ) {
5437  *left += *right; ++left; ++right;
5438  }
5439  }
5440 }
5442 //*************************************************************************************************
5443 
5444 
5445 //*************************************************************************************************
5457 template< typename Type > // Data type of the matrix
5458 template< typename MT > // Type of the right-hand side dense matrix
5460 {
5462 
5463  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5464  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5465 
5466  constexpr size_t block( BLOCK_SIZE );
5467 
5468  for( size_t jj=0UL; jj<n_; jj+=block ) {
5469  const size_t jend( min( n_, jj+block ) );
5470  for( size_t ii=0UL; ii<m_; ii+=block )
5471  {
5472  if( IsLower<MT>::value && ii < jj ) continue;
5473  if( IsUpper<MT>::value && ii > jj ) break;
5474 
5475  for( size_t j=jj; j<jend; ++j )
5476  {
5477  const size_t ibegin( ( IsLower<MT>::value )
5478  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5479  :( ii ) );
5480  const size_t iend ( ( IsUpper<MT>::value )
5481  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5482  :( min( m_, ii+block ) ) );
5483  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5484 
5485  for( size_t i=ibegin; i<iend; ++i ) {
5486  v_[i+j*mm_] += (~rhs)(i,j);
5487  }
5488  }
5489  }
5490  }
5491 }
5493 //*************************************************************************************************
5494 
5495 
5496 //*************************************************************************************************
5508 template< typename Type > // Data type of the matrix
5509 template< typename MT > // Type of the right-hand side sparse matrix
5511 {
5512  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5513  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5514 
5515  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5516  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5517  v_[element->index()+j*mm_] += element->value();
5518 }
5520 //*************************************************************************************************
5521 
5522 
5523 //*************************************************************************************************
5535 template< typename Type > // Data type of the matrix
5536 template< typename MT > // Type of the right-hand side sparse matrix
5538 {
5540 
5541  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5542  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5543 
5544  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5545  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5546  v_[i+element->index()*mm_] += element->value();
5547 }
5549 //*************************************************************************************************
5550 
5551 
5552 //*************************************************************************************************
5564 template< typename Type > // Data type of the matrix
5565 template< typename MT > // Type of the right-hand side dense matrix
5566 inline DisableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5568 {
5569  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5570  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5571 
5572  for( size_t j=0UL; j<n_; ++j )
5573  {
5574  if( IsDiagonal<MT>::value )
5575  {
5576  v_[j+j*mm_] -= (~rhs)(j,j);
5577  }
5578  else
5579  {
5580  const size_t ibegin( ( IsLower<MT>::value )
5581  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5582  :( 0UL ) );
5583  const size_t iend ( ( IsUpper<MT>::value )
5584  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5585  :( m_ ) );
5586  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5587 
5588  size_t i( ibegin );
5589 
5590  for( ; (i+2UL) <= iend; i+=2UL ) {
5591  v_[i +j*mm_] -= (~rhs)(i ,j);
5592  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
5593  }
5594  if( i < iend ) {
5595  v_[i+j*mm_] -= (~rhs)(i,j);
5596  }
5597  }
5598  }
5599 }
5601 //*************************************************************************************************
5602 
5603 
5604 //*************************************************************************************************
5616 template< typename Type > // Data type of the matrix
5617 template< typename MT > // Type of the right-hand side dense matrix
5618 inline EnableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5620 {
5623 
5624  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5625  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5626 
5627  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5628 
5629  for( size_t j=0UL; j<n_; ++j )
5630  {
5631  const size_t ibegin( ( IsLower<MT>::value )
5632  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5633  :( 0UL ) );
5634  const size_t iend ( ( IsUpper<MT>::value )
5635  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5636  :( m_ ) );
5637  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5638 
5639  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5640  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5641 
5642  size_t i( ibegin );
5643  Iterator left( begin(j) + ibegin );
5644  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
5645 
5646  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5647  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5648  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5649  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5650  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5651  }
5652  for( ; i<ipos; i+=SIMDSIZE ) {
5653  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5654  }
5655  for( ; remainder && i<iend; ++i ) {
5656  *left -= *right; ++left; ++right;
5657  }
5658  }
5659 }
5661 //*************************************************************************************************
5662 
5663 
5664 //*************************************************************************************************
5676 template< typename Type > // Data type of the matrix
5677 template< typename MT > // Type of the right-hand side dense matrix
5679 {
5681 
5682  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5683  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5684 
5685  constexpr size_t block( BLOCK_SIZE );
5686 
5687  for( size_t jj=0UL; jj<n_; jj+=block ) {
5688  const size_t jend( min( n_, jj+block ) );
5689  for( size_t ii=0UL; ii<m_; ii+=block )
5690  {
5691  if( IsLower<MT>::value && ii < jj ) continue;
5692  if( IsUpper<MT>::value && ii > jj ) break;
5693 
5694  for( size_t j=jj; j<jend; ++j )
5695  {
5696  const size_t ibegin( ( IsLower<MT>::value )
5697  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5698  :( ii ) );
5699  const size_t iend ( ( IsUpper<MT>::value )
5700  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5701  :( min( m_, ii+block ) ) );
5702  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5703 
5704  for( size_t i=ibegin; i<iend; ++i ) {
5705  v_[i+j*mm_] -= (~rhs)(i,j);
5706  }
5707  }
5708  }
5709  }
5710 }
5712 //*************************************************************************************************
5713 
5714 
5715 //*************************************************************************************************
5727 template< typename Type > // Data type of the matrix
5728 template< typename MT > // Type of the right-hand side sparse matrix
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<(~rhs).columns(); ++j )
5735  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5736  v_[element->index()+j*mm_] -= element->value();
5737 }
5739 //*************************************************************************************************
5740 
5741 
5742 //*************************************************************************************************
5754 template< typename Type > // Data type of the matrix
5755 template< typename MT > // Type of the right-hand side sparse matrix
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<(~rhs).rows(); ++i )
5764  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5765  v_[i+element->index()*mm_] -= element->value();
5766 }
5768 //*************************************************************************************************
5769 
5770 
5771 
5772 
5773 
5774 
5775 
5776 
5777 //=================================================================================================
5778 //
5779 // DYNAMICMATRIX OPERATORS
5780 //
5781 //=================================================================================================
5782 
5783 //*************************************************************************************************
5786 template< typename Type, bool SO >
5787 inline void reset( DynamicMatrix<Type,SO>& m );
5788 
5789 template< typename Type, bool SO >
5790 inline void reset( DynamicMatrix<Type,SO>& m, size_t i );
5791 
5792 template< typename Type, bool SO >
5793 inline void clear( DynamicMatrix<Type,SO>& m );
5794 
5795 template< bool RF, typename Type, bool SO >
5796 inline bool isDefault( const DynamicMatrix<Type,SO>& m );
5797 
5798 template< typename Type, bool SO >
5799 inline bool isIntact( const DynamicMatrix<Type,SO>& m ) noexcept;
5800 
5801 template< typename Type, bool SO >
5802 inline void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) noexcept;
5804 //*************************************************************************************************
5805 
5806 
5807 //*************************************************************************************************
5814 template< typename Type // Data type of the matrix
5815  , bool SO > // Storage order
5817 {
5818  m.reset();
5819 }
5820 //*************************************************************************************************
5821 
5822 
5823 //*************************************************************************************************
5836 template< typename Type // Data type of the matrix
5837  , bool SO > // Storage order
5838 inline void reset( DynamicMatrix<Type,SO>& m, size_t i )
5839 {
5840  m.reset( i );
5841 }
5842 //*************************************************************************************************
5843 
5844 
5845 //*************************************************************************************************
5852 template< typename Type // Data type of the matrix
5853  , bool SO > // Storage order
5855 {
5856  m.clear();
5857 }
5858 //*************************************************************************************************
5859 
5860 
5861 //*************************************************************************************************
5886 template< bool RF // Relaxation flag
5887  , typename Type // Data type of the matrix
5888  , bool SO > // Storage order
5889 inline bool isDefault( const DynamicMatrix<Type,SO>& m )
5890 {
5891  return ( m.rows() == 0UL && m.columns() == 0UL );
5892 }
5893 //*************************************************************************************************
5894 
5895 
5896 //*************************************************************************************************
5914 template< typename Type // Data type of the matrix
5915  , bool SO > // Storage order
5916 inline bool isIntact( const DynamicMatrix<Type,SO>& m ) noexcept
5917 {
5918  return m.isIntact();
5919 }
5920 //*************************************************************************************************
5921 
5922 
5923 //*************************************************************************************************
5931 template< typename Type // Data type of the matrix
5932  , bool SO > // Storage order
5934 {
5935  a.swap( b );
5936 }
5937 //*************************************************************************************************
5938 
5939 
5940 
5941 
5942 //=================================================================================================
5943 //
5944 // HASCONSTDATAACCESS SPECIALIZATIONS
5945 //
5946 //=================================================================================================
5947 
5948 //*************************************************************************************************
5950 template< typename T, bool SO >
5951 struct HasConstDataAccess< DynamicMatrix<T,SO> > : public TrueType
5952 {};
5954 //*************************************************************************************************
5955 
5956 
5957 
5958 
5959 //=================================================================================================
5960 //
5961 // HASMUTABLEDATAACCESS SPECIALIZATIONS
5962 //
5963 //=================================================================================================
5964 
5965 //*************************************************************************************************
5967 template< typename T, bool SO >
5968 struct HasMutableDataAccess< DynamicMatrix<T,SO> > : public TrueType
5969 {};
5971 //*************************************************************************************************
5972 
5973 
5974 
5975 
5976 //=================================================================================================
5977 //
5978 // ISALIGNED SPECIALIZATIONS
5979 //
5980 //=================================================================================================
5981 
5982 //*************************************************************************************************
5984 template< typename T, bool SO >
5985 struct IsAligned< DynamicMatrix<T,SO> > : public BoolConstant<usePadding>
5986 {};
5988 //*************************************************************************************************
5989 
5990 
5991 
5992 
5993 //=================================================================================================
5994 //
5995 // ISPADDED SPECIALIZATIONS
5996 //
5997 //=================================================================================================
5998 
5999 //*************************************************************************************************
6001 template< typename T, bool SO >
6002 struct IsPadded< DynamicMatrix<T,SO> > : public BoolConstant<usePadding>
6003 {};
6005 //*************************************************************************************************
6006 
6007 
6008 
6009 
6010 //=================================================================================================
6011 //
6012 // ISRESIZABLE SPECIALIZATIONS
6013 //
6014 //=================================================================================================
6015 
6016 //*************************************************************************************************
6018 template< typename T, bool SO >
6019 struct IsResizable< DynamicMatrix<T,SO> > : public TrueType
6020 {};
6022 //*************************************************************************************************
6023 
6024 
6025 
6026 
6027 //=================================================================================================
6028 //
6029 // ADDTRAIT SPECIALIZATIONS
6030 //
6031 //=================================================================================================
6032 
6033 //*************************************************************************************************
6035 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6036 struct AddTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
6037 {
6038  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6039 };
6040 
6041 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6042 struct AddTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6043 {
6044  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6045 };
6046 
6047 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6048 struct AddTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6049 {
6050  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6051 };
6052 
6053 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6054 struct AddTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6055 {
6056  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6057 };
6058 
6059 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6060 struct AddTrait< DynamicMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6061 {
6062  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6063 };
6064 
6065 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6066 struct AddTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6067 {
6068  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6069 };
6070 
6071 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6072 struct AddTrait< HybridMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6073 {
6074  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6075 };
6076 
6077 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6078 struct AddTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6079 {
6080  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6081 };
6082 
6083 template< typename T1, bool SO, typename T2 >
6084 struct AddTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6085 {
6086  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6087 };
6088 
6089 template< typename T1, bool SO1, typename T2, bool SO2 >
6090 struct AddTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6091 {
6092  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6093 };
6095 //*************************************************************************************************
6096 
6097 
6098 
6099 
6100 //=================================================================================================
6101 //
6102 // SUBTRAIT SPECIALIZATIONS
6103 //
6104 //=================================================================================================
6105 
6106 //*************************************************************************************************
6108 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6109 struct SubTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
6110 {
6111  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6112 };
6113 
6114 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6115 struct SubTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6116 {
6117  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6118 };
6119 
6120 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6121 struct SubTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6122 {
6123  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6124 };
6125 
6126 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6127 struct SubTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6128 {
6129  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6130 };
6131 
6132 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6133 struct SubTrait< DynamicMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6134 {
6135  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6136 };
6137 
6138 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6139 struct SubTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6140 {
6141  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6142 };
6143 
6144 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6145 struct SubTrait< HybridMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6146 {
6147  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6148 };
6149 
6150 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6151 struct SubTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6152 {
6153  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6154 };
6155 
6156 template< typename T1, bool SO, typename T2 >
6157 struct SubTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6158 {
6159  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6160 };
6161 
6162 template< typename T1, bool SO1, typename T2, bool SO2 >
6163 struct SubTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6164 {
6165  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6166 };
6168 //*************************************************************************************************
6169 
6170 
6171 
6172 
6173 //=================================================================================================
6174 //
6175 // MULTTRAIT SPECIALIZATIONS
6176 //
6177 //=================================================================================================
6178 
6179 //*************************************************************************************************
6181 template< typename T1, bool SO, typename T2 >
6182 struct MultTrait< DynamicMatrix<T1,SO>, T2, EnableIf_<IsNumeric<T2> > >
6183 {
6184  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6185 };
6186 
6187 template< typename T1, typename T2, bool SO >
6188 struct MultTrait< T1, DynamicMatrix<T2,SO>, EnableIf_<IsNumeric<T1> > >
6189 {
6190  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6191 };
6192 
6193 template< typename T1, bool SO, typename T2, size_t N >
6194 struct MultTrait< DynamicMatrix<T1,SO>, StaticVector<T2,N,false> >
6195 {
6196  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6197 };
6198 
6199 template< typename T1, size_t N, typename T2, bool SO >
6200 struct MultTrait< StaticVector<T1,N,true>, DynamicMatrix<T2,SO> >
6201 {
6202  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6203 };
6204 
6205 template< typename T1, bool SO, typename T2, size_t N >
6206 struct MultTrait< DynamicMatrix<T1,SO>, HybridVector<T2,N,false> >
6207 {
6208  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6209 };
6210 
6211 template< typename T1, size_t N, typename T2, bool SO >
6212 struct MultTrait< HybridVector<T1,N,true>, DynamicMatrix<T2,SO> >
6213 {
6214  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6215 };
6216 
6217 template< typename T1, bool SO, typename T2 >
6218 struct MultTrait< DynamicMatrix<T1,SO>, DynamicVector<T2,false> >
6219 {
6220  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6221 };
6222 
6223 template< typename T1, typename T2, bool SO >
6224 struct MultTrait< DynamicVector<T1,true>, DynamicMatrix<T2,SO> >
6225 {
6226  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6227 };
6228 
6229 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6230 struct MultTrait< DynamicMatrix<T1,SO>, CustomVector<T2,AF,PF,false> >
6231 {
6232  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6233 };
6234 
6235 template< typename T1, bool AF, bool PF, typename T2, bool SO >
6236 struct MultTrait< CustomVector<T1,AF,PF,true>, DynamicMatrix<T2,SO> >
6237 {
6238  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6239 };
6240 
6241 template< typename T1, bool SO, typename T2 >
6242 struct MultTrait< DynamicMatrix<T1,SO>, CompressedVector<T2,false> >
6243 {
6244  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6245 };
6246 
6247 template< typename T1, typename T2, bool SO >
6248 struct MultTrait< CompressedVector<T1,true>, DynamicMatrix<T2,SO> >
6249 {
6250  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6251 };
6252 
6253 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6254 struct MultTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6255 {
6256  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6257 };
6258 
6259 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6260 struct MultTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6261 {
6262  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6263 };
6264 
6265 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6266 struct MultTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6267 {
6268  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6269 };
6270 
6271 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6272 struct MultTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6273 {
6274  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6275 };
6276 
6277 template< typename T1, bool SO1, typename T2, bool SO2 >
6278 struct MultTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6279 {
6280  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6281 };
6283 //*************************************************************************************************
6284 
6285 
6286 
6287 
6288 //=================================================================================================
6289 //
6290 // DIVTRAIT SPECIALIZATIONS
6291 //
6292 //=================================================================================================
6293 
6294 //*************************************************************************************************
6296 template< typename T1, bool SO, typename T2 >
6297 struct DivTrait< DynamicMatrix<T1,SO>, T2, EnableIf_<IsNumeric<T2> > >
6298 {
6299  using Type = DynamicMatrix< DivTrait_<T1,T2>, SO >;
6300 };
6302 //*************************************************************************************************
6303 
6304 
6305 
6306 
6307 //=================================================================================================
6308 //
6309 // HIGHTYPE SPECIALIZATIONS
6310 //
6311 //=================================================================================================
6312 
6313 //*************************************************************************************************
6315 template< typename T1, bool SO, typename T2 >
6316 struct HighType< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6317 {
6319 };
6321 //*************************************************************************************************
6322 
6323 
6324 
6325 
6326 //=================================================================================================
6327 //
6328 // LOWTYPE SPECIALIZATIONS
6329 //
6330 //=================================================================================================
6331 
6332 //*************************************************************************************************
6334 template< typename T1, bool SO, typename T2 >
6335 struct LowType< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6336 {
6338 };
6340 //*************************************************************************************************
6341 
6342 
6343 
6344 
6345 //=================================================================================================
6346 //
6347 // SUBMATRIXTRAIT SPECIALIZATIONS
6348 //
6349 //=================================================================================================
6350 
6351 //*************************************************************************************************
6353 template< typename T1, bool SO >
6354 struct SubmatrixTrait< DynamicMatrix<T1,SO> >
6355 {
6356  using Type = DynamicMatrix<T1,SO>;
6357 };
6359 //*************************************************************************************************
6360 
6361 
6362 
6363 
6364 //=================================================================================================
6365 //
6366 // ROWTRAIT SPECIALIZATIONS
6367 //
6368 //=================================================================================================
6369 
6370 //*************************************************************************************************
6372 template< typename T1, bool SO >
6373 struct RowTrait< DynamicMatrix<T1,SO> >
6374 {
6375  using Type = DynamicVector<T1,true>;
6376 };
6378 //*************************************************************************************************
6379 
6380 
6381 
6382 
6383 //=================================================================================================
6384 //
6385 // COLUMNTRAIT SPECIALIZATIONS
6386 //
6387 //=================================================================================================
6388 
6389 //*************************************************************************************************
6391 template< typename T1, bool SO >
6392 struct ColumnTrait< DynamicMatrix<T1,SO> >
6393 {
6394  using Type = DynamicVector<T1,false>;
6395 };
6397 //*************************************************************************************************
6398 
6399 } // namespace blaze
6400 
6401 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:133
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
size_t n_
The current number of columns of the matrix.
Definition: DynamicMatrix.h:479
Header file for auxiliary alias declarations.
BLAZE_ALWAYS_INLINE void storeu(size_t i, size_t j, const SIMDType &value) noexcept
Unaligned store of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2280
Header file for kernel specific block sizes.
Availability of a SIMD subtraction for the given data types.Depending on the available instruction se...
Definition: HasSIMDSub.h:163
Header file for mathematical functions.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: DynamicMatrix.h:2074
void reserve(size_t elements)
Setting the minimum capacity of the matrix.
Definition: DynamicMatrix.h:1809
Compile time check for low-level access to constant data.This type trait tests whether the given data...
Definition: HasConstDataAccess.h:75
#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.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DynamicMatrix.h:1513
Header file for the UNUSED_PARAMETER function template.
Header file for the subtraction trait.
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2118
Header file for basic type definitions.
const SIMDType load() const noexcept
Load of the SIMD element at the current iterator position.
Definition: DenseIterator.h:403
size_t adjustColumns(size_t minColumns) const noexcept
Adjusting the number columns of the matrix according to its data type Type.
Definition: DynamicMatrix.h:1860
Header file for the row trait.
Type *BLAZE_RESTRICT v_
The dynamically allocated matrix elements.
Definition: DynamicMatrix.h:482
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t i, size_t j) const noexcept
Unaligned load of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2181
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:117
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > 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
Header file for the IsSparseMatrix type trait.
DynamicMatrix & operator=(const Type &rhs)
Homogenous assignment to all matrix elements.
Definition: DynamicMatrix.h:1167
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: DynamicMatrix.h:1733
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:261
const CTransExprTrait_< MT > ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatForEachExpr.h:1251
constexpr size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
DynamicMatrix() noexcept
The default constructor for DynamicMatrix.
Definition: DynamicMatrix.h:520
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
Header file for the IsSame and IsStrictlySame type traits.
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const SIMDType &value) noexcept
Store of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2215
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:315
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
OutputIterator transfer(InputIterator first, InputIterator last, OutputIterator dest)
Transfers the elements from the given source range to the destination range.
Definition: Algorithm.h:71
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1755
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:163
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:79
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: DynamicMatrix.h:1143
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member constant is set to true, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to false, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:138
DenseMatrix< This, SO > BaseType
Base type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:209
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
Efficient implementation of an arbitrary sized vector.The DynamicVector class template is the represe...
Definition: DynamicVector.h:177
Header file for memory allocation and deallocation functionality.
System settings for performance optimizations.
Efficient implementation of a dynamic matrix.The DynamicMatrix class template is the representation ...
Definition: DynamicMatrix.h:204
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
Compile time check for data types.This type trait tests whether or not the given types can be combine...
Definition: IsSIMDCombinable.h:120
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1802
EnableIf_< IsDenseMatrix< MT1 > > 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
BLAZE_ALWAYS_INLINE void stream(size_t i, size_t j, const SIMDType &value) noexcept
Aligned, non-temporal store of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2315
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:71
const This & CompositeType
Data type for composite expression templates.
Definition: DynamicMatrix.h:216
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:119
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: DynamicMatrix.h:2093
Constraint on the data type.
~DynamicMatrix()
The destructor for DynamicMatrix.
Definition: DynamicMatrix.h:824
This ResultType
Result type for expression template evaluations.
Definition: DynamicMatrix.h:210
Header file for the std::initializer_list aliases.
Header file for the SparseMatrix base class.
Compile time check for low-level access to mutable data.This type trait tests whether the given data ...
Definition: HasMutableDataAccess.h:75
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
EnableIf_< IsBuiltin< T >, T *> allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:150
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DynamicMatrix.h:1546
Base template for the RowTrait class.
Definition: RowTrait.h:117
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: DynamicMatrix.h:223
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:143
Header file for the DisableIf class template.
Header file for the LowType type trait.
Base template for the HighType type trait.
Definition: HighType.h:133
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:143
DynamicMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: DynamicMatrix.h:1922
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.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5635
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: DynamicMatrix.h:2056
constexpr bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
Type ElementType
Type of the matrix elements.
Definition: DynamicMatrix.h:213
Header file for all forward declarations of the math module.
#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:79
Header file for the IsSMPAssignable type trait.
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:76
EnableIf_< IsDenseMatrix< MT1 > > 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
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
DynamicMatrix< Type, SO > This
Type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:208
Header file for the HasSIMDAdd type trait.
DynamicMatrix< NewType, SO > Other
The type of the other DynamicMatrix.
Definition: DynamicMatrix.h:232
Efficient implementation of a fixed-sized matrix.The StaticMatrix class template is the representatio...
Definition: Forward.h:60
Header file for the DenseMatrix base class.
Header file for the DenseIterator class template.
void stream(const SIMDType &value) const noexcept
Aligned, non-temporal store of the SIMD element at the current iterator position. ...
Definition: DenseIterator.h:531
const Type & ReturnType
Return type for expression template evaluations.
Definition: DynamicMatrix.h:215
Header file for all SIMD functionality.
Constraint on the data type.
void store(const SIMDType &value) const noexcept
Store of the SIMD element at the current iterator position.
Definition: DenseIterator.h:468
#define BLAZE_CONSTRAINT_MUST_NOT_BE_DIAGONAL_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a diagonal matrix type, a compilation error is created.
Definition: Diagonal.h:79
Header file for the IsLower type trait.
Header file for the IsAligned type trait.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
void extend(size_t m, size_t n, bool preserve=true)
Extending the size of the matrix.
Definition: DynamicMatrix.h:1791
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
#define BLAZE_RESTRICT
Platform dependent setup of the restrict keyword.
Definition: Restrict.h:81
Header file for the default storage order for all vectors of the Blaze library.
#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:61
void reset()
Reset to the default initial values.
Definition: DynamicMatrix.h:1646
Header file for the exception macros of the math module.
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Compile time check for data types.This type trait tests whether or not the given template parameter i...
Definition: IsSMPAssignable.h:119
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DynamicMatrix.h:1527
Headerfile for generic algorithms.
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:553
Header file for the IsPadded type trait.
DynamicMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DynamicMatrix.h:211
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: DynamicMatrix.h:214
BLAZE_ALWAYS_INLINE void storea(size_t i, size_t j, const SIMDType &value) noexcept
Aligned store of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2244
Header file for the IsVectorizable type trait.
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: DynamicMatrix.h:952
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: DynamicMatrix.h:852
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
Base template for the LowType type trait.
Definition: LowType.h:133
Header file for the HasConstDataAccess type trait.
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
size_t nn_
The alignment adjusted number of columns.
Definition: DynamicMatrix.h:480
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Type * Pointer
Pointer to a non-constant matrix value.
Definition: DynamicMatrix.h:220
Header file for the IsSIMDCombinable type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
DynamicMatrix< Type, SO > Other
The type of the other DynamicMatrix.
Definition: DynamicMatrix.h:242
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determine the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:80
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:143
Base template for the MultTrait class.
Definition: MultTrait.h:143
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: DynamicMatrix.h:1033
Header file for the addition trait.
void clear()
Clearing the matrix.
Definition: DynamicMatrix.h:1690
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: DynamicMatrix.h:221
Header file for the division trait.
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: DynamicMatrix.h:1077
Constraint on the data type.
size_t m_
The current number of rows of the matrix.
Definition: DynamicMatrix.h:478
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:296
Header file for the cache size of the target architecture.
Efficient implementation of a dynamically sized matrix with static memory.The HybridMatrix class temp...
Definition: Forward.h:58
#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:79
Header file for the column trait.
Header file for the isDefault shim.
System settings for the restrict keyword.
Header file for the TransExprTrait class template.
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: DynamicMatrix.h:2036
Constraint on the data type.
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.
void swap(DynamicMatrix &m) noexcept
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:1841
Constraint on the data type.
Header file for the HasSIMDSub type trait.
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric< T >::value)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Header file for the HasMutableDataAccess type trait.
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: DynamicMatrix.h:1596
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:225
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
Base template for the DivTrait class.
Definition: DivTrait.h:143
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric< T >::value)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
Type & Reference
Reference to a non-constant matrix value.
Definition: DynamicMatrix.h:218
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
constexpr bool usePadding
Configuration of the padding of dense vectors and matrices.This configuration switch enables/disables...
Definition: Optimizations.h:52
DenseIterator< const Type, usePadding > ConstIterator
Iterator over constant elements.
Definition: DynamicMatrix.h:224
BLAZE_ALWAYS_INLINE SIMDType loada(size_t i, size_t j) const noexcept
Aligned load of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2146
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: DynamicMatrix.h:1099
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:733
Initializer list type of the Blaze library.
bool isIntact() const noexcept
Returns whether the invariants of the dynamic matrix are intact.
Definition: DynamicMatrix.h:1996
Header file for the alignment check function.
typename InvExprTrait< T >::Type InvExprTrait_
Auxiliary alias declaration for the InvExprTrait class template.The InvExprTrait_ alias declaration p...
Definition: InvExprTrait.h:134
size_t capacity_
The maximum capacity of the matrix.
Definition: DynamicMatrix.h:481
Header file for the IntegralConstant class template.
Resize mechanism to obtain a DynamicMatrix with different fixed dimensions.
Definition: DynamicMatrix.h:241
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:78
Rebind mechanism to obtain a DynamicMatrix with different data/element type.
Definition: DynamicMatrix.h:231
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Base template for the SubTrait class.
Definition: SubTrait.h:143
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1303
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: DynamicMatrix.h:1560
Header file for the CTransExprTrait class template.
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: DynamicMatrix.h:897
Header file for the IsResizable type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#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
DynamicMatrix & transpose()
In-place transpose of the matrix.
Definition: DynamicMatrix.h:1884
const Type & ConstReference
Reference to a constant matrix value.
Definition: DynamicMatrix.h:219
DynamicMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: DynamicMatrix.h:212
Header file for the HighType type trait.
Header file for the TrueType type/value trait base class.
constexpr bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56