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/shims/Reset.h>
60 #include <blaze/math/SIMD.h>
93 #include <blaze/system/Blocking.h>
94 #include <blaze/system/CacheSize.h>
95 #include <blaze/system/Inline.h>
97 #include <blaze/system/Restrict.h>
104 #include <blaze/util/Assert.h>
110 #include <blaze/util/DisableIf.h>
111 #include <blaze/util/EnableIf.h>
113 #include <blaze/util/Memory.h>
114 #include <blaze/util/Template.h>
115 #include <blaze/util/TrueType.h>
116 #include <blaze/util/Types.h>
120 #include <blaze/util/Unused.h>
121 
122 
123 namespace blaze {
124 
125 //=================================================================================================
126 //
127 // CLASS DEFINITION
128 //
129 //=================================================================================================
130 
131 //*************************************************************************************************
210 template< typename Type // Data type of the matrix
211  , bool SO = defaultStorageOrder > // Storage order
213  : public DenseMatrix< DynamicMatrix<Type,SO>, SO >
214 {
215  public:
216  //**Type definitions****************************************************************************
219  using ResultType = This;
222  using ElementType = Type;
224  using ReturnType = const Type&;
225  using CompositeType = const This&;
226 
227  using Reference = Type&;
228  using ConstReference = const Type&;
229  using Pointer = Type*;
230  using ConstPointer = const Type*;
231 
234  //**********************************************************************************************
235 
236  //**Rebind struct definition********************************************************************
239  template< typename NewType > // Data type of the other matrix
240  struct Rebind {
242  };
243  //**********************************************************************************************
244 
245  //**Resize struct definition********************************************************************
248  template< size_t NewM // Number of rows of the other matrix
249  , size_t NewN > // Number of columns of the other matrix
250  struct Resize {
252  };
253  //**********************************************************************************************
254 
255  //**Compilation flags***************************************************************************
257 
261  enum : bool { simdEnabled = IsVectorizable<Type>::value };
262 
264 
267  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
268  //**********************************************************************************************
269 
270  //**Constructors********************************************************************************
273  explicit inline DynamicMatrix() noexcept;
274  explicit inline DynamicMatrix( size_t m, size_t n );
275  explicit inline DynamicMatrix( size_t m, size_t n, const Type& init );
276  explicit inline DynamicMatrix( initializer_list< initializer_list<Type> > list );
277 
278  template< typename Other >
279  explicit inline DynamicMatrix( size_t m, size_t n, const Other* array );
280 
281  template< typename Other, size_t Rows, size_t Cols >
282  explicit inline DynamicMatrix( const Other (&array)[Rows][Cols] );
283 
284  inline DynamicMatrix( const DynamicMatrix& m );
285  inline DynamicMatrix( DynamicMatrix&& m ) noexcept;
286  template< typename MT, bool SO2 > inline DynamicMatrix( const Matrix<MT,SO2>& m );
288  //**********************************************************************************************
289 
290  //**Destructor**********************************************************************************
293  inline ~DynamicMatrix();
295  //**********************************************************************************************
296 
297  //**Data access functions***********************************************************************
300  inline Reference operator()( size_t i, size_t j ) noexcept;
301  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
302  inline Reference at( size_t i, size_t j );
303  inline ConstReference at( size_t i, size_t j ) const;
304  inline Pointer data () noexcept;
305  inline ConstPointer data () const noexcept;
306  inline Pointer data ( size_t i ) noexcept;
307  inline ConstPointer data ( size_t i ) const noexcept;
308  inline Iterator begin ( size_t i ) noexcept;
309  inline ConstIterator begin ( size_t i ) const noexcept;
310  inline ConstIterator cbegin( size_t i ) const noexcept;
311  inline Iterator end ( size_t i ) noexcept;
312  inline ConstIterator end ( size_t i ) const noexcept;
313  inline ConstIterator cend ( size_t i ) const noexcept;
315  //**********************************************************************************************
316 
317  //**Assignment operators************************************************************************
320  inline DynamicMatrix& operator=( const Type& rhs );
321  inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list );
322 
323  template< typename Other, size_t Rows, size_t Cols >
324  inline DynamicMatrix& operator=( const Other (&array)[Rows][Cols] );
325 
326  inline DynamicMatrix& operator=( const DynamicMatrix& rhs );
327  inline DynamicMatrix& operator=( DynamicMatrix&& rhs ) noexcept;
328 
329  template< typename MT, bool SO2 > inline DynamicMatrix& operator= ( const Matrix<MT,SO2>& rhs );
330  template< typename MT, bool SO2 > inline DynamicMatrix& operator+=( const Matrix<MT,SO2>& rhs );
331  template< typename MT, bool SO2 > inline DynamicMatrix& operator-=( const Matrix<MT,SO2>& rhs );
332  template< typename MT, bool SO2 > inline DynamicMatrix& operator%=( const Matrix<MT,SO2>& rhs );
333  template< typename MT, bool SO2 > inline DynamicMatrix& operator*=( const Matrix<MT,SO2>& rhs );
334 
335  template< typename Other >
336  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator*=( Other rhs );
337 
338  template< typename Other >
339  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator/=( Other rhs );
341  //**********************************************************************************************
342 
343  //**Utility functions***************************************************************************
346  inline size_t rows() const noexcept;
347  inline size_t columns() const noexcept;
348  inline size_t spacing() const noexcept;
349  inline size_t capacity() const noexcept;
350  inline size_t capacity( size_t i ) const noexcept;
351  inline size_t nonZeros() const;
352  inline size_t nonZeros( size_t i ) const;
353  inline void reset();
354  inline void reset( size_t i );
355  inline void clear();
356  void resize ( size_t m, size_t n, bool preserve=true );
357  inline void extend ( size_t m, size_t n, bool preserve=true );
358  inline void reserve( size_t elements );
359  inline void shrinkToFit();
360  inline void swap( DynamicMatrix& m ) noexcept;
362  //**********************************************************************************************
363 
364  //**Numeric functions***************************************************************************
367  inline DynamicMatrix& transpose();
368  inline DynamicMatrix& ctranspose();
369 
370  template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
372  //**********************************************************************************************
373 
374  private:
375  //**********************************************************************************************
377  template< typename MT >
379  struct VectorizedAssign {
380  enum : bool { value = useOptimizedKernels &&
381  simdEnabled && MT::simdEnabled &&
383  };
385  //**********************************************************************************************
386 
387  //**********************************************************************************************
389  template< typename MT >
391  struct VectorizedAddAssign {
392  enum : bool { value = useOptimizedKernels &&
393  simdEnabled && MT::simdEnabled &&
397  };
399  //**********************************************************************************************
400 
401  //**********************************************************************************************
403  template< typename MT >
405  struct VectorizedSubAssign {
406  enum : bool { value = useOptimizedKernels &&
407  simdEnabled && MT::simdEnabled &&
411  };
413  //**********************************************************************************************
414 
415  //**********************************************************************************************
417  template< typename MT >
419  struct VectorizedSchurAssign {
420  enum : bool { value = useOptimizedKernels &&
421  simdEnabled && MT::simdEnabled &&
424  };
426  //**********************************************************************************************
427 
428  //**********************************************************************************************
430  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
431  //**********************************************************************************************
432 
433  public:
434  //**Debugging functions*************************************************************************
437  inline bool isIntact() const noexcept;
439  //**********************************************************************************************
440 
441  //**Expression template evaluation functions****************************************************
444  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
445  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
446 
447  inline bool isAligned () const noexcept;
448  inline bool canSMPAssign() const noexcept;
449 
450  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
451  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
452  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
453 
454  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
455  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
456  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
457  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
458 
459  template< typename MT >
460  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
461 
462  template< typename MT >
463  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
464 
465  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
466  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
467  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
468 
469  template< typename MT >
470  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
471 
472  template< typename MT >
473  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
474 
475  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
476  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
477  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
478 
479  template< typename MT >
480  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
481 
482  template< typename MT >
483  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
484 
485  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
486  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
487  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
488 
489  template< typename MT >
490  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
491 
492  template< typename MT >
493  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
494 
495  template< typename MT > inline void schurAssign( const DenseMatrix<MT,!SO>& rhs );
496  template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
497  template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
499  //**********************************************************************************************
500 
501  private:
502  //**Utility functions***************************************************************************
505  inline size_t addPadding( size_t value ) const noexcept;
507  //**********************************************************************************************
508 
509  //**Member variables****************************************************************************
512  size_t m_;
513  size_t n_;
514  size_t nn_;
515  size_t capacity_;
517 
527  //**********************************************************************************************
528 
529  //**Compile time checks*************************************************************************
536  //**********************************************************************************************
537 };
538 //*************************************************************************************************
539 
540 
541 
542 
543 //=================================================================================================
544 //
545 // CONSTRUCTORS
546 //
547 //=================================================================================================
548 
549 //*************************************************************************************************
552 template< typename Type // Data type of the matrix
553  , bool SO > // Storage order
555  : m_ ( 0UL ) // The current number of rows of the matrix
556  , n_ ( 0UL ) // The current number of columns of the matrix
557  , nn_ ( 0UL ) // The alignment adjusted number of columns
558  , capacity_( 0UL ) // The maximum capacity of the matrix
559  , v_ ( nullptr ) // The matrix elements
560 {}
561 //*************************************************************************************************
562 
563 
564 //*************************************************************************************************
573 template< typename Type // Data type of the matrix
574  , bool SO > // Storage order
575 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n )
576  : m_ ( m ) // The current number of rows of the matrix
577  , n_ ( n ) // The current number of columns of the matrix
578  , nn_ ( addPadding( n ) ) // The alignment adjusted number of columns
579  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
580  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
581 {
583  for( size_t i=0UL; i<m_; ++i ) {
584  for( size_t j=n_; j<nn_; ++j ) {
585  v_[i*nn_+j] = Type();
586  }
587  }
588  }
589 
590  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
591 }
592 //*************************************************************************************************
593 
594 
595 //*************************************************************************************************
604 template< typename Type // Data type of the matrix
605  , bool SO > // Storage order
606 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, const Type& init )
607  : m_ ( m ) // The current number of rows of the matrix
608  , n_ ( n ) // The current number of columns of the matrix
609  , nn_ ( addPadding( n ) ) // The alignment adjusted number of columns
610  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
611  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
612 {
613  for( size_t i=0UL; i<m; ++i ) {
614  for( size_t j=0UL; j<n_; ++j )
615  v_[i*nn_+j] = init;
616 
618  for( size_t j=n_; j<nn_; ++j )
619  v_[i*nn_+j] = Type();
620  }
621  }
622 
623  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
624 }
625 //*************************************************************************************************
626 
627 
628 //*************************************************************************************************
648 template< typename Type // Data type of the matrix
649  , bool SO > // Storage order
651  : m_ ( list.size() ) // The current number of rows of the matrix
652  , n_ ( determineColumns( list ) ) // The current number of columns of the matrix
653  , nn_ ( addPadding( n_ ) ) // The alignment adjusted number of columns
654  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
655  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
656 {
657  size_t i( 0UL );
658 
659  for( const auto& rowList : list ) {
660  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ), v_+(i+1UL)*nn_, Type() );
661  ++i;
662  }
663 
664  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
665 }
666 //*************************************************************************************************
667 
668 
669 //*************************************************************************************************
692 template< typename Type // Data type of the matrix
693  , bool SO > // Storage order
694 template< typename Other > // Data type of the initialization array
695 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, const Other* array )
696  : m_ ( m ) // The current number of rows of the matrix
697  , n_ ( n ) // The current number of columns of the matrix
698  , nn_ ( addPadding( n ) ) // The alignment adjusted number of columns
699  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
700  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
701 {
702  for( size_t i=0UL; i<m; ++i ) {
703  for( size_t j=0UL; j<n; ++j )
704  v_[i*nn_+j] = array[i*n+j];
705 
707  for( size_t j=n; j<nn_; ++j )
708  v_[i*nn_+j] = Type();
709  }
710  }
711 
712  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
713 }
714 //*************************************************************************************************
715 
716 
717 //*************************************************************************************************
738 template< typename Type // Data type of the matrix
739  , bool SO > // Storage order
740 template< typename Other // Data type of the initialization array
741  , size_t Rows // Number of rows of the initialization array
742  , size_t Cols > // Number of columns of the initialization array
743 inline DynamicMatrix<Type,SO>::DynamicMatrix( const Other (&array)[Rows][Cols] )
744  : m_ ( Rows ) // The current number of rows of the matrix
745  , n_ ( Cols ) // The current number of columns of the matrix
746  , nn_ ( addPadding( Cols ) ) // The alignment adjusted number of columns
747  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
748  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
749 {
750  for( size_t i=0UL; i<Rows; ++i ) {
751  for( size_t j=0UL; j<Cols; ++j )
752  v_[i*nn_+j] = array[i][j];
753 
755  for( size_t j=Cols; j<nn_; ++j )
756  v_[i*nn_+j] = Type();
757  }
758  }
759 
760  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
761 }
762 //*************************************************************************************************
763 
764 
765 //*************************************************************************************************
773 template< typename Type // Data type of the matrix
774  , bool SO > // Storage order
776  : m_ ( m.m_ ) // The current number of rows of the matrix
777  , n_ ( m.n_ ) // The current number of columns of the matrix
778  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
779  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
780  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
781 {
782  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
783 
784  for( size_t i=0UL; i<capacity_; ++i )
785  v_[i] = m.v_[i];
786 
787  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
788 }
789 //*************************************************************************************************
790 
791 
792 //*************************************************************************************************
797 template< typename Type // Data type of the matrix
798  , bool SO > // Storage order
800  : m_ ( m.m_ ) // The current number of rows of the matrix
801  , n_ ( m.n_ ) // The current number of columns of the matrix
802  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
803  , capacity_( m.capacity_ ) // The maximum capacity of the matrix
804  , v_ ( m.v_ ) // The matrix elements
805 {
806  m.m_ = 0UL;
807  m.n_ = 0UL;
808  m.nn_ = 0UL;
809  m.capacity_ = 0UL;
810  m.v_ = nullptr;
811 }
812 //*************************************************************************************************
813 
814 
815 //*************************************************************************************************
820 template< typename Type // Data type of the matrix
821  , bool SO > // Storage order
822 template< typename MT // Type of the foreign matrix
823  , bool SO2 > // Storage order of the foreign matrix
825  : m_ ( (~m).rows() ) // The current number of rows of the matrix
826  , n_ ( (~m).columns() ) // The current number of columns of the matrix
827  , nn_ ( addPadding( n_ ) ) // The alignment adjusted number of columns
828  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
829  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
830 {
831  for( size_t i=0UL; i<m_; ++i ) {
832  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : n_ );
833  j<( IsVectorizable<Type>::value ? nn_ : n_ ); ++j ) {
834  v_[i*nn_+j] = Type();
835  }
836  }
837 
838  smpAssign( *this, ~m );
839 
840  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
841 }
842 //*************************************************************************************************
843 
844 
845 
846 
847 //=================================================================================================
848 //
849 // DESTRUCTOR
850 //
851 //=================================================================================================
852 
853 //*************************************************************************************************
856 template< typename Type // Data type of the matrix
857  , bool SO > // Storage order
859 {
860  deallocate( v_ );
861 }
862 //*************************************************************************************************
863 
864 
865 
866 
867 //=================================================================================================
868 //
869 // DATA ACCESS FUNCTIONS
870 //
871 //=================================================================================================
872 
873 //*************************************************************************************************
883 template< typename Type // Data type of the matrix
884  , bool SO > // Storage order
885 inline typename DynamicMatrix<Type,SO>::Reference
886  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) noexcept
887 {
888  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
889  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
890  return v_[i*nn_+j];
891 }
892 //*************************************************************************************************
893 
894 
895 //*************************************************************************************************
905 template< typename Type // Data type of the matrix
906  , bool SO > // Storage order
908  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) const noexcept
909 {
910  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
911  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
912  return v_[i*nn_+j];
913 }
914 //*************************************************************************************************
915 
916 
917 //*************************************************************************************************
928 template< typename Type // Data type of the matrix
929  , bool SO > // Storage order
930 inline typename DynamicMatrix<Type,SO>::Reference
931  DynamicMatrix<Type,SO>::at( size_t i, size_t j )
932 {
933  if( i >= m_ ) {
934  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
935  }
936  if( j >= n_ ) {
937  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
938  }
939  return (*this)(i,j);
940 }
941 //*************************************************************************************************
942 
943 
944 //*************************************************************************************************
955 template< typename Type // Data type of the matrix
956  , bool SO > // Storage order
958  DynamicMatrix<Type,SO>::at( size_t i, size_t j ) const
959 {
960  if( i >= m_ ) {
961  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
962  }
963  if( j >= n_ ) {
964  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
965  }
966  return (*this)(i,j);
967 }
968 //*************************************************************************************************
969 
970 
971 //*************************************************************************************************
983 template< typename Type // Data type of the matrix
984  , bool SO > // Storage order
985 inline typename DynamicMatrix<Type,SO>::Pointer
987 {
988  return v_;
989 }
990 //*************************************************************************************************
991 
992 
993 //*************************************************************************************************
1005 template< typename Type // Data type of the matrix
1006  , bool SO > // Storage order
1009 {
1010  return v_;
1011 }
1012 //*************************************************************************************************
1013 
1014 
1015 //*************************************************************************************************
1023 template< typename Type // Data type of the matrix
1024  , bool SO > // Storage order
1025 inline typename DynamicMatrix<Type,SO>::Pointer
1026  DynamicMatrix<Type,SO>::data( size_t i ) noexcept
1027 {
1028  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1029  return v_ + i*nn_;
1030 }
1031 //*************************************************************************************************
1032 
1033 
1034 //*************************************************************************************************
1042 template< typename Type // Data type of the matrix
1043  , bool SO > // Storage order
1045  DynamicMatrix<Type,SO>::data( size_t i ) const noexcept
1046 {
1047  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1048  return v_ + i*nn_;
1049 }
1050 //*************************************************************************************************
1051 
1052 
1053 //*************************************************************************************************
1064 template< typename Type // Data type of the matrix
1065  , bool SO > // Storage order
1066 inline typename DynamicMatrix<Type,SO>::Iterator
1067  DynamicMatrix<Type,SO>::begin( size_t i ) noexcept
1068 {
1069  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1070  return Iterator( v_ + i*nn_ );
1071 }
1072 //*************************************************************************************************
1073 
1074 
1075 //*************************************************************************************************
1086 template< typename Type // Data type of the matrix
1087  , bool SO > // Storage order
1089  DynamicMatrix<Type,SO>::begin( size_t i ) const noexcept
1090 {
1091  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1092  return ConstIterator( v_ + i*nn_ );
1093 }
1094 //*************************************************************************************************
1095 
1096 
1097 //*************************************************************************************************
1108 template< typename Type // Data type of the matrix
1109  , bool SO > // Storage order
1111  DynamicMatrix<Type,SO>::cbegin( size_t i ) const noexcept
1112 {
1113  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1114  return ConstIterator( v_ + i*nn_ );
1115 }
1116 //*************************************************************************************************
1117 
1118 
1119 //*************************************************************************************************
1130 template< typename Type // Data type of the matrix
1131  , bool SO > // Storage order
1132 inline typename DynamicMatrix<Type,SO>::Iterator
1133  DynamicMatrix<Type,SO>::end( size_t i ) noexcept
1134 {
1135  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1136  return Iterator( v_ + i*nn_ + n_ );
1137 }
1138 //*************************************************************************************************
1139 
1140 
1141 //*************************************************************************************************
1152 template< typename Type // Data type of the matrix
1153  , bool SO > // Storage order
1155  DynamicMatrix<Type,SO>::end( size_t i ) const noexcept
1156 {
1157  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1158  return ConstIterator( v_ + i*nn_ + n_ );
1159 }
1160 //*************************************************************************************************
1161 
1162 
1163 //*************************************************************************************************
1174 template< typename Type // Data type of the matrix
1175  , bool SO > // Storage order
1177  DynamicMatrix<Type,SO>::cend( size_t i ) const noexcept
1178 {
1179  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1180  return ConstIterator( v_ + i*nn_ + n_ );
1181 }
1182 //*************************************************************************************************
1183 
1184 
1185 
1186 
1187 //=================================================================================================
1188 //
1189 // ASSIGNMENT OPERATORS
1190 //
1191 //=================================================================================================
1192 
1193 //*************************************************************************************************
1199 template< typename Type // Data type of the matrix
1200  , bool SO > // Storage order
1202 {
1203  for( size_t i=0UL; i<m_; ++i )
1204  for( size_t j=0UL; j<n_; ++j )
1205  v_[i*nn_+j] = rhs;
1206 
1207  return *this;
1208 }
1209 //*************************************************************************************************
1210 
1211 
1212 //*************************************************************************************************
1233 template< typename Type // Data type of the matrix
1234  , bool SO > // Storage order
1235 inline DynamicMatrix<Type,SO>&
1237 {
1238  resize( list.size(), determineColumns( list ), false );
1239 
1240  size_t i( 0UL );
1241 
1242  for( const auto& rowList : list ) {
1243  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ), v_+(i+1UL)*nn_, Type() );
1244  ++i;
1245  }
1246 
1247  return *this;
1248 }
1249 //*************************************************************************************************
1250 
1251 
1252 //*************************************************************************************************
1273 template< typename Type // Data type of the matrix
1274  , bool SO > // Storage order
1275 template< typename Other // Data type of the initialization array
1276  , size_t Rows // Number of rows of the initialization array
1277  , size_t Cols > // Number of columns of the initialization array
1278 inline DynamicMatrix<Type,SO>& DynamicMatrix<Type,SO>::operator=( const Other (&array)[Rows][Cols] )
1279 {
1280  resize( Rows, Cols, false );
1281 
1282  for( size_t i=0UL; i<Rows; ++i )
1283  for( size_t j=0UL; j<Cols; ++j )
1284  v_[i*nn_+j] = array[i][j];
1285 
1286  return *this;
1287 }
1288 //*************************************************************************************************
1289 
1290 
1291 //*************************************************************************************************
1300 template< typename Type // Data type of the matrix
1301  , bool SO > // Storage order
1303 {
1304  if( &rhs == this ) return *this;
1305 
1306  resize( rhs.m_, rhs.n_, false );
1307  smpAssign( *this, ~rhs );
1308 
1309  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1310 
1311  return *this;
1312 }
1313 //*************************************************************************************************
1314 
1315 
1316 //*************************************************************************************************
1322 template< typename Type // Data type of the matrix
1323  , bool SO > // Storage order
1325 {
1326  deallocate( v_ );
1327 
1328  m_ = rhs.m_;
1329  n_ = rhs.n_;
1330  nn_ = rhs.nn_;
1331  capacity_ = rhs.capacity_;
1332  v_ = rhs.v_;
1333 
1334  rhs.m_ = 0UL;
1335  rhs.n_ = 0UL;
1336  rhs.nn_ = 0UL;
1337  rhs.capacity_ = 0UL;
1338  rhs.v_ = nullptr;
1339 
1340  return *this;
1341 }
1342 //*************************************************************************************************
1343 
1344 
1345 //*************************************************************************************************
1354 template< typename Type // Data type of the matrix
1355  , bool SO > // Storage order
1356 template< typename MT // Type of the right-hand side matrix
1357  , bool SO2 > // Storage order of the right-hand side matrix
1359 {
1360  using TT = TransExprTrait_<This>;
1361  using CT = CTransExprTrait_<This>;
1362  using IT = InvExprTrait_<This>;
1363 
1364  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1365  transpose();
1366  }
1367  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1368  ctranspose();
1369  }
1370  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1371  DynamicMatrix tmp( ~rhs );
1372  swap( tmp );
1373  }
1374  else {
1375  resize( (~rhs).rows(), (~rhs).columns(), false );
1377  reset();
1378  smpAssign( *this, ~rhs );
1379  }
1380 
1381  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1382 
1383  return *this;
1384 }
1385 //*************************************************************************************************
1386 
1387 
1388 //*************************************************************************************************
1398 template< typename Type // Data type of the matrix
1399  , bool SO > // Storage order
1400 template< typename MT // Type of the right-hand side matrix
1401  , bool SO2 > // Storage order of the right-hand side matrix
1403 {
1404  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1405  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1406  }
1407 
1408  if( (~rhs).canAlias( this ) ) {
1409  const ResultType_<MT> tmp( ~rhs );
1410  smpAddAssign( *this, tmp );
1411  }
1412  else {
1413  smpAddAssign( *this, ~rhs );
1414  }
1415 
1416  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1417 
1418  return *this;
1419 }
1420 //*************************************************************************************************
1421 
1422 
1423 //*************************************************************************************************
1433 template< typename Type // Data type of the matrix
1434  , bool SO > // Storage order
1435 template< typename MT // Type of the right-hand side matrix
1436  , bool SO2 > // Storage order of the right-hand side matrix
1438 {
1439  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1440  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1441  }
1442 
1443  if( (~rhs).canAlias( this ) ) {
1444  const ResultType_<MT> tmp( ~rhs );
1445  smpSubAssign( *this, tmp );
1446  }
1447  else {
1448  smpSubAssign( *this, ~rhs );
1449  }
1450 
1451  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1452 
1453  return *this;
1454 }
1455 //*************************************************************************************************
1456 
1457 
1458 //*************************************************************************************************
1468 template< typename Type // Data type of the matrix
1469  , bool SO > // Storage order
1470 template< typename MT // Type of the right-hand side matrix
1471  , bool SO2 > // Storage order of the right-hand side matrix
1473 {
1474  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1475  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1476  }
1477 
1478  if( (~rhs).canAlias( this ) ) {
1479  const ResultType_<MT> tmp( ~rhs );
1480  smpSchurAssign( *this, tmp );
1481  }
1482  else {
1483  smpSchurAssign( *this, ~rhs );
1484  }
1485 
1486  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1487 
1488  return *this;
1489 }
1490 //*************************************************************************************************
1491 
1492 
1493 //*************************************************************************************************
1503 template< typename Type // Data type of the matrix
1504  , bool SO > // Storage order
1505 template< typename MT // Type of the right-hand side matrix
1506  , bool SO2 > // Storage order of the right-hand side matrix
1508 {
1509  if( (~rhs).rows() != n_ ) {
1510  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1511  }
1512 
1513  DynamicMatrix tmp( *this * (~rhs) );
1514  swap( tmp );
1515 
1516  return *this;
1517 }
1518 //*************************************************************************************************
1519 
1520 
1521 //*************************************************************************************************
1528 template< typename Type // Data type of the matrix
1529  , bool SO > // Storage order
1530 template< typename Other > // Data type of the right-hand side scalar
1533 {
1534  smpAssign( *this, (*this) * rhs );
1535 
1536  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1537 
1538  return *this;
1539 }
1540 //*************************************************************************************************
1541 
1542 
1543 //*************************************************************************************************
1550 template< typename Type // Data type of the matrix
1551  , bool SO > // Storage order
1552 template< typename Other > // Data type of the right-hand side scalar
1553 inline EnableIf_<IsNumeric<Other>, DynamicMatrix<Type,SO> >&
1555 {
1556  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1557 
1558  smpAssign( *this, (*this) / rhs );
1559 
1560  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1561 
1562  return *this;
1563 }
1564 //*************************************************************************************************
1565 
1566 
1567 
1568 
1569 //=================================================================================================
1570 //
1571 // UTILITY FUNCTIONS
1572 //
1573 //=================================================================================================
1574 
1575 //*************************************************************************************************
1580 template< typename Type // Data type of the matrix
1581  , bool SO > // Storage order
1582 inline size_t DynamicMatrix<Type,SO>::rows() const noexcept
1583 {
1584  return m_;
1585 }
1586 //*************************************************************************************************
1587 
1588 
1589 //*************************************************************************************************
1594 template< typename Type // Data type of the matrix
1595  , bool SO > // Storage order
1596 inline size_t DynamicMatrix<Type,SO>::columns() const noexcept
1597 {
1598  return n_;
1599 }
1600 //*************************************************************************************************
1601 
1602 
1603 //*************************************************************************************************
1613 template< typename Type // Data type of the matrix
1614  , bool SO > // Storage order
1615 inline size_t DynamicMatrix<Type,SO>::spacing() const noexcept
1616 {
1617  return nn_;
1618 }
1619 //*************************************************************************************************
1620 
1621 
1622 //*************************************************************************************************
1627 template< typename Type // Data type of the matrix
1628  , bool SO > // Storage order
1629 inline size_t DynamicMatrix<Type,SO>::capacity() const noexcept
1630 {
1631  return capacity_;
1632 }
1633 //*************************************************************************************************
1634 
1635 
1636 //*************************************************************************************************
1647 template< typename Type // Data type of the matrix
1648  , bool SO > // Storage order
1649 inline size_t DynamicMatrix<Type,SO>::capacity( size_t i ) const noexcept
1650 {
1651  UNUSED_PARAMETER( i );
1652  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1653  return nn_;
1654 }
1655 //*************************************************************************************************
1656 
1657 
1658 //*************************************************************************************************
1663 template< typename Type // Data type of the matrix
1664  , bool SO > // Storage order
1666 {
1667  size_t nonzeros( 0UL );
1668 
1669  for( size_t i=0UL; i<m_; ++i )
1670  for( size_t j=0UL; j<n_; ++j )
1671  if( !isDefault( v_[i*nn_+j] ) )
1672  ++nonzeros;
1673 
1674  return nonzeros;
1675 }
1676 //*************************************************************************************************
1677 
1678 
1679 //*************************************************************************************************
1690 template< typename Type // Data type of the matrix
1691  , bool SO > // Storage order
1692 inline size_t DynamicMatrix<Type,SO>::nonZeros( size_t i ) const
1693 {
1694  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1695 
1696  const size_t jend( i*nn_ + n_ );
1697  size_t nonzeros( 0UL );
1698 
1699  for( size_t j=i*nn_; j<jend; ++j )
1700  if( !isDefault( v_[j] ) )
1701  ++nonzeros;
1702 
1703  return nonzeros;
1704 }
1705 //*************************************************************************************************
1706 
1707 
1708 //*************************************************************************************************
1713 template< typename Type // Data type of the matrix
1714  , bool SO > // Storage order
1716 {
1717  using blaze::clear;
1718 
1719  for( size_t i=0UL; i<m_; ++i )
1720  for( size_t j=0UL; j<n_; ++j )
1721  clear( v_[i*nn_+j] );
1722 }
1723 //*************************************************************************************************
1724 
1725 
1726 //*************************************************************************************************
1737 template< typename Type // Data type of the matrix
1738  , bool SO > // Storage order
1739 inline void DynamicMatrix<Type,SO>::reset( size_t i )
1740 {
1741  using blaze::clear;
1742 
1743  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1744  for( size_t j=0UL; j<n_; ++j )
1745  clear( v_[i*nn_+j] );
1746 }
1747 //*************************************************************************************************
1748 
1749 
1750 //*************************************************************************************************
1757 template< typename Type // Data type of the matrix
1758  , bool SO > // Storage order
1760 {
1761  resize( 0UL, 0UL, false );
1762 }
1763 //*************************************************************************************************
1764 
1765 
1766 //*************************************************************************************************
1800 template< typename Type // Data type of the matrix
1801  , bool SO > // Storage order
1802 void DynamicMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1803 {
1804  using blaze::min;
1805 
1806  if( m == m_ && n == n_ ) return;
1807 
1808  const size_t nn( addPadding( n ) );
1809 
1810  if( preserve )
1811  {
1812  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1813  const size_t min_m( min( m, m_ ) );
1814  const size_t min_n( min( n, n_ ) );
1815 
1816  for( size_t i=0UL; i<min_m; ++i ) {
1817  transfer( v_+i*nn_, v_+i*nn_+min_n, v+i*nn );
1818  }
1819 
1820  std::swap( v_, v );
1821  deallocate( v );
1822  capacity_ = m*nn;
1823  }
1824  else if( m*nn > capacity_ ) {
1825  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1826  std::swap( v_, v );
1827  deallocate( v );
1828  capacity_ = m*nn;
1829  }
1830 
1832  for( size_t i=0UL; i<m; ++i )
1833  for( size_t j=n; j<nn; ++j )
1834  v_[i*nn+j] = Type();
1835  }
1836 
1837  m_ = m;
1838  n_ = n;
1839  nn_ = nn;
1840 }
1841 //*************************************************************************************************
1842 
1843 
1844 //*************************************************************************************************
1858 template< typename Type // Data type of the matrix
1859  , bool SO > // Storage order
1860 inline void DynamicMatrix<Type,SO>::extend( size_t m, size_t n, bool preserve )
1861 {
1862  resize( m_+m, n_+n, preserve );
1863 }
1864 //*************************************************************************************************
1865 
1866 
1867 //*************************************************************************************************
1876 template< typename Type // Data type of the matrix
1877  , bool SO > // Storage order
1878 inline void DynamicMatrix<Type,SO>::reserve( size_t elements )
1879 {
1880  if( elements > capacity_ )
1881  {
1882  // Allocating a new array
1883  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
1884 
1885  // Initializing the new array
1886  transfer( v_, v_+capacity_, tmp );
1887 
1889  for( size_t i=capacity_; i<elements; ++i )
1890  tmp[i] = Type();
1891  }
1892 
1893  // Replacing the old array
1894  std::swap( tmp, v_ );
1895  deallocate( tmp );
1896  capacity_ = elements;
1897  }
1898 }
1899 //*************************************************************************************************
1900 
1901 
1902 //*************************************************************************************************
1912 template< typename Type // Data type of the matrix
1913  , bool SO > // Storage order
1915 {
1916  if( ( m_ * nn_ ) < capacity_ ) {
1917  DynamicMatrix( *this ).swap( *this );
1918  }
1919 }
1920 //*************************************************************************************************
1921 
1922 
1923 //*************************************************************************************************
1929 template< typename Type // Data type of the matrix
1930  , bool SO > // Storage order
1932 {
1933  std::swap( m_ , m.m_ );
1934  std::swap( n_ , m.n_ );
1935  std::swap( nn_, m.nn_ );
1936  std::swap( capacity_, m.capacity_ );
1937  std::swap( v_ , m.v_ );
1938 }
1939 //*************************************************************************************************
1940 
1941 
1942 //*************************************************************************************************
1951 template< typename Type // Data type of the matrix
1952  , bool SO > // Storage order
1953 inline size_t DynamicMatrix<Type,SO>::addPadding( size_t value ) const noexcept
1954 {
1955  if( usePadding && IsVectorizable<Type>::value )
1956  return nextMultiple<size_t>( value, SIMDSIZE );
1957  else return value;
1958 }
1959 //*************************************************************************************************
1960 
1961 
1962 
1963 
1964 //=================================================================================================
1965 //
1966 // NUMERIC FUNCTIONS
1967 //
1968 //=================================================================================================
1969 
1970 //*************************************************************************************************
1975 template< typename Type // Data type of the matrix
1976  , bool SO > // Storage order
1978 {
1979  using std::swap;
1980 
1981  constexpr size_t block( BLOCK_SIZE );
1982 
1983  if( m_ == n_ )
1984  {
1985  for( size_t ii=0UL; ii<m_; ii+=block ) {
1986  const size_t iend( min( ii+block, m_ ) );
1987  for( size_t jj=0UL; jj<=ii; jj+=block ) {
1988  for( size_t i=ii; i<iend; ++i ) {
1989  const size_t jend( min( jj+block, n_, i ) );
1990  for( size_t j=jj; j<jend; ++j ) {
1991  swap( v_[i*nn_+j], v_[j*nn_+i] );
1992  }
1993  }
1994  }
1995  }
1996  }
1997  else
1998  {
1999  DynamicMatrix tmp( trans(*this) );
2000  this->swap( tmp );
2001  }
2002 
2003  return *this;
2004 }
2005 //*************************************************************************************************
2006 
2007 
2008 //*************************************************************************************************
2013 template< typename Type // Data type of the matrix
2014  , bool SO > // Storage order
2016 {
2017  constexpr size_t block( BLOCK_SIZE );
2018 
2019  if( m_ == n_ )
2020  {
2021  for( size_t ii=0UL; ii<m_; ii+=block ) {
2022  const size_t iend( min( ii+block, m_ ) );
2023  for( size_t jj=0UL; jj<ii; jj+=block ) {
2024  const size_t jend( min( jj+block, n_ ) );
2025  for( size_t i=ii; i<iend; ++i ) {
2026  for( size_t j=jj; j<jend; ++j ) {
2027  cswap( v_[i*nn_+j], v_[j*nn_+i] );
2028  }
2029  }
2030  }
2031  for( size_t i=ii; i<iend; ++i ) {
2032  for( size_t j=ii; j<i; ++j ) {
2033  cswap( v_[i*nn_+j], v_[j*nn_+i] );
2034  }
2035  conjugate( v_[i*nn_+i] );
2036  }
2037  }
2038  }
2039  else
2040  {
2041  DynamicMatrix tmp( ctrans(*this) );
2042  swap( tmp );
2043  }
2044 
2045  return *this;
2046 }
2047 //*************************************************************************************************
2048 
2049 
2050 //*************************************************************************************************
2067 template< typename Type // Data type of the matrix
2068  , bool SO > // Storage order
2069 template< typename Other > // Data type of the scalar value
2071 {
2072  for( size_t i=0UL; i<m_; ++i )
2073  for( size_t j=0UL; j<n_; ++j )
2074  v_[i*nn_+j] *= scalar;
2075 
2076  return *this;
2077 }
2078 //*************************************************************************************************
2079 
2080 
2081 
2082 
2083 //=================================================================================================
2084 //
2085 // DEBUGGING FUNCTIONS
2086 //
2087 //=================================================================================================
2088 
2089 //*************************************************************************************************
2098 template< typename Type // Data type of the matrix
2099  , bool SO > // Storage order
2100 inline bool DynamicMatrix<Type,SO>::isIntact() const noexcept
2101 {
2102  if( m_ * n_ > capacity_ )
2103  return false;
2104 
2106  for( size_t i=0UL; i<m_; ++i ) {
2107  for( size_t j=n_; j<nn_; ++j ) {
2108  if( v_[i*nn_+j] != Type() )
2109  return false;
2110  }
2111  }
2112  }
2113 
2114  return true;
2115 }
2116 //*************************************************************************************************
2117 
2118 
2119 
2120 
2121 //=================================================================================================
2122 //
2123 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2124 //
2125 //=================================================================================================
2126 
2127 //*************************************************************************************************
2137 template< typename Type // Data type of the matrix
2138  , bool SO > // Storage order
2139 template< typename Other > // Data type of the foreign expression
2140 inline bool DynamicMatrix<Type,SO>::canAlias( const Other* alias ) const noexcept
2141 {
2142  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2143 }
2144 //*************************************************************************************************
2145 
2146 
2147 //*************************************************************************************************
2157 template< typename Type // Data type of the matrix
2158  , bool SO > // Storage order
2159 template< typename Other > // Data type of the foreign expression
2160 inline bool DynamicMatrix<Type,SO>::isAliased( const Other* alias ) const noexcept
2161 {
2162  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2163 }
2164 //*************************************************************************************************
2165 
2166 
2167 //*************************************************************************************************
2176 template< typename Type // Data type of the matrix
2177  , bool SO > // Storage order
2178 inline bool DynamicMatrix<Type,SO>::isAligned() const noexcept
2179 {
2180  return ( usePadding || columns() % SIMDSIZE == 0UL );
2181 }
2182 //*************************************************************************************************
2183 
2184 
2185 //*************************************************************************************************
2195 template< typename Type // Data type of the matrix
2196  , bool SO > // Storage order
2197 inline bool DynamicMatrix<Type,SO>::canSMPAssign() const noexcept
2198 {
2199  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2200 }
2201 //*************************************************************************************************
2202 
2203 
2204 //*************************************************************************************************
2219 template< typename Type // Data type of the matrix
2220  , bool SO > // Storage order
2222  DynamicMatrix<Type,SO>::load( size_t i, size_t j ) const noexcept
2223 {
2224  if( usePadding )
2225  return loada( i, j );
2226  else
2227  return loadu( i, j );
2228 }
2229 //*************************************************************************************************
2230 
2231 
2232 //*************************************************************************************************
2247 template< typename Type // Data type of the matrix
2248  , bool SO > // Storage order
2250  DynamicMatrix<Type,SO>::loada( size_t i, size_t j ) const noexcept
2251 {
2252  using blaze::loada;
2253 
2255 
2256  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2257  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2258  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2259  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2260  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2261 
2262  return loada( v_+i*nn_+j );
2263 }
2264 //*************************************************************************************************
2265 
2266 
2267 //*************************************************************************************************
2282 template< typename Type // Data type of the matrix
2283  , bool SO > // Storage order
2285  DynamicMatrix<Type,SO>::loadu( size_t i, size_t j ) const noexcept
2286 {
2287  using blaze::loadu;
2288 
2290 
2291  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2292  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2293  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2294 
2295  return loadu( v_+i*nn_+j );
2296 }
2297 //*************************************************************************************************
2298 
2299 
2300 //*************************************************************************************************
2316 template< typename Type // Data type of the matrix
2317  , bool SO > // Storage order
2319  DynamicMatrix<Type,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2320 {
2321  if( usePadding )
2322  storea( i, j, value );
2323  else
2324  storeu( i, j, value );
2325 }
2326 //*************************************************************************************************
2327 
2328 
2329 //*************************************************************************************************
2345 template< typename Type // Data type of the matrix
2346  , bool SO > // Storage order
2348  DynamicMatrix<Type,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2349 {
2350  using blaze::storea;
2351 
2353 
2354  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2355  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2356  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2357  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2358  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2359 
2360  storea( v_+i*nn_+j, value );
2361 }
2362 //*************************************************************************************************
2363 
2364 
2365 //*************************************************************************************************
2381 template< typename Type // Data type of the matrix
2382  , bool SO > // Storage order
2384  DynamicMatrix<Type,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2385 {
2386  using blaze::storeu;
2387 
2389 
2390  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2391  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2392  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2393 
2394  storeu( v_+i*nn_+j, value );
2395 }
2396 //*************************************************************************************************
2397 
2398 
2399 //*************************************************************************************************
2416 template< typename Type // Data type of the matrix
2417  , bool SO > // Storage order
2419  DynamicMatrix<Type,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2420 {
2421  using blaze::stream;
2422 
2424 
2425  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2426  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2427  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2428  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2429  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2430 
2431  stream( v_+i*nn_+j, value );
2432 }
2433 //*************************************************************************************************
2434 
2435 
2436 //*************************************************************************************************
2447 template< typename Type // Data type of the matrix
2448  , bool SO > // Storage order
2449 template< typename MT > // Type of the right-hand side dense matrix
2452 {
2453  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2454  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2455 
2456  const size_t jpos( n_ & size_t(-2) );
2457  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2458 
2459  for( size_t i=0UL; i<m_; ++i ) {
2460  for( size_t j=0UL; j<jpos; j+=2UL ) {
2461  v_[i*nn_+j ] = (~rhs)(i,j );
2462  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
2463  }
2464  if( jpos < n_ ) {
2465  v_[i*nn_+jpos] = (~rhs)(i,jpos);
2466  }
2467  }
2468 }
2469 //*************************************************************************************************
2470 
2471 
2472 //*************************************************************************************************
2483 template< typename Type // Data type of the matrix
2484  , bool SO > // Storage order
2485 template< typename MT > // Type of the right-hand side dense matrix
2488 {
2490 
2491  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2492  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2493 
2494  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2495 
2496  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2497  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2498 
2499  if( usePadding && useStreaming &&
2500  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
2501  {
2502  for( size_t i=0UL; i<m_; ++i )
2503  {
2504  size_t j( 0UL );
2505  Iterator left( begin(i) );
2506  ConstIterator_<MT> right( (~rhs).begin(i) );
2507 
2508  for( ; j<jpos; j+=SIMDSIZE, left+=SIMDSIZE, right+=SIMDSIZE ) {
2509  left.stream( right.load() );
2510  }
2511  for( ; remainder && j<n_; ++j, ++left, ++right ) {
2512  *left = *right;
2513  }
2514  }
2515  }
2516  else
2517  {
2518  for( size_t i=0UL; i<m_; ++i )
2519  {
2520  size_t j( 0UL );
2521  Iterator left( begin(i) );
2522  ConstIterator_<MT> right( (~rhs).begin(i) );
2523 
2524  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2525  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2526  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2527  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2528  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2529  }
2530  for( ; j<jpos; j+=SIMDSIZE ) {
2531  left.store( right.load() ); left+=SIMDSIZE, right+=SIMDSIZE;
2532  }
2533  for( ; remainder && j<n_; ++j ) {
2534  *left = *right; ++left; ++right;
2535  }
2536  }
2537  }
2538 }
2539 //*************************************************************************************************
2540 
2541 
2542 //*************************************************************************************************
2553 template< typename Type // Data type of the matrix
2554  , bool SO > // Storage order
2555 template< typename MT > // Type of the right-hand side dense matrix
2557 {
2559 
2560  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2561  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2562 
2563  constexpr size_t block( BLOCK_SIZE );
2564 
2565  for( size_t ii=0UL; ii<m_; ii+=block ) {
2566  const size_t iend( min( m_, ii+block ) );
2567  for( size_t jj=0UL; jj<n_; jj+=block ) {
2568  const size_t jend( min( n_, jj+block ) );
2569  for( size_t i=ii; i<iend; ++i ) {
2570  for( size_t j=jj; j<jend; ++j ) {
2571  v_[i*nn_+j] = (~rhs)(i,j);
2572  }
2573  }
2574  }
2575  }
2576 }
2577 //*************************************************************************************************
2578 
2579 
2580 //*************************************************************************************************
2591 template< typename Type // Data type of the matrix
2592  , bool SO > // Storage order
2593 template< typename MT > // Type of the right-hand side sparse matrix
2595 {
2596  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2597  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2598 
2599  for( size_t i=0UL; i<m_; ++i )
2600  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2601  v_[i*nn_+element->index()] = element->value();
2602 }
2603 //*************************************************************************************************
2604 
2605 
2606 //*************************************************************************************************
2617 template< typename Type // Data type of the matrix
2618  , bool SO > // Storage order
2619 template< typename MT > // Type of the right-hand side sparse matrix
2621 {
2623 
2624  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2625  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2626 
2627  for( size_t j=0UL; j<n_; ++j )
2628  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2629  v_[element->index()*nn_+j] = element->value();
2630 }
2631 //*************************************************************************************************
2632 
2633 
2634 //*************************************************************************************************
2645 template< typename Type // Data type of the matrix
2646  , bool SO > // Storage order
2647 template< typename MT > // Type of the right-hand side dense matrix
2648 inline DisableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2650 {
2651  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2652  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2653 
2654  for( size_t i=0UL; i<m_; ++i )
2655  {
2656  if( IsDiagonal<MT>::value )
2657  {
2658  v_[i*nn_+i] += (~rhs)(i,i);
2659  }
2660  else
2661  {
2662  const size_t jbegin( ( IsUpper<MT>::value )
2663  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2664  :( 0UL ) );
2665  const size_t jend ( ( IsLower<MT>::value )
2666  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2667  :( n_ ) );
2668  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2669 
2670  size_t j( jbegin );
2671 
2672  for( ; (j+2UL) <= jend; j+=2UL ) {
2673  v_[i*nn_+j ] += (~rhs)(i,j );
2674  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
2675  }
2676  if( j < jend ) {
2677  v_[i*nn_+j] += (~rhs)(i,j);
2678  }
2679  }
2680  }
2681 }
2682 //*************************************************************************************************
2683 
2684 
2685 //*************************************************************************************************
2696 template< typename Type // Data type of the matrix
2697  , bool SO > // Storage order
2698 template< typename MT > // Type of the right-hand side dense matrix
2699 inline EnableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2701 {
2704 
2705  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2706  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2707 
2708  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2709 
2710  for( size_t i=0UL; i<m_; ++i )
2711  {
2712  const size_t jbegin( ( IsUpper<MT>::value )
2713  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2714  :( 0UL ) );
2715  const size_t jend ( ( IsLower<MT>::value )
2716  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2717  :( n_ ) );
2718  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2719 
2720  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2721  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2722 
2723  size_t j( jbegin );
2724  Iterator left( begin(i) + jbegin );
2725  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2726 
2727  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2728  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2729  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2730  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2731  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2732  }
2733  for( ; j<jpos; j+=SIMDSIZE ) {
2734  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2735  }
2736  for( ; remainder && j<jend; ++j ) {
2737  *left += *right; ++left; ++right;
2738  }
2739  }
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
2759 {
2761 
2762  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2763  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2764 
2765  constexpr size_t block( BLOCK_SIZE );
2766 
2767  for( size_t ii=0UL; ii<m_; ii+=block ) {
2768  const size_t iend( min( m_, ii+block ) );
2769  for( size_t jj=0UL; jj<n_; jj+=block )
2770  {
2771  if( IsLower<MT>::value && ii < jj ) break;
2772  if( IsUpper<MT>::value && ii > jj ) continue;
2773 
2774  for( size_t i=ii; i<iend; ++i )
2775  {
2776  const size_t jbegin( ( IsUpper<MT>::value )
2777  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2778  :( jj ) );
2779  const size_t jend ( ( IsLower<MT>::value )
2780  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2781  :( min( n_, jj+block ) ) );
2782  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2783 
2784  for( size_t j=jbegin; j<jend; ++j ) {
2785  v_[i*nn_+j] += (~rhs)(i,j);
2786  }
2787  }
2788  }
2789  }
2790 }
2791 //*************************************************************************************************
2792 
2793 
2794 //*************************************************************************************************
2805 template< typename Type // Data type of the matrix
2806  , bool SO > // Storage order
2807 template< typename MT > // Type of the right-hand side sparse matrix
2809 {
2810  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2811  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2812 
2813  for( size_t i=0UL; i<m_; ++i )
2814  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2815  v_[i*nn_+element->index()] += element->value();
2816 }
2817 //*************************************************************************************************
2818 
2819 
2820 //*************************************************************************************************
2831 template< typename Type // Data type of the matrix
2832  , bool SO > // Storage order
2833 template< typename MT > // Type of the right-hand side sparse matrix
2835 {
2837 
2838  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2839  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2840 
2841  for( size_t j=0UL; j<n_; ++j )
2842  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2843  v_[element->index()*nn_+j] += element->value();
2844 }
2845 //*************************************************************************************************
2846 
2847 
2848 //*************************************************************************************************
2859 template< typename Type // Data type of the matrix
2860  , bool SO > // Storage order
2861 template< typename MT > // Type of the right-hand side dense matrix
2862 inline DisableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
2864 {
2865  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2866  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2867 
2868  for( size_t i=0UL; i<m_; ++i )
2869  {
2870  if( IsDiagonal<MT>::value )
2871  {
2872  v_[i*nn_+i] -= (~rhs)(i,i);
2873  }
2874  else
2875  {
2876  const size_t jbegin( ( IsUpper<MT>::value )
2877  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2878  :( 0UL ) );
2879  const size_t jend ( ( IsLower<MT>::value )
2880  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2881  :( n_ ) );
2882  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2883 
2884  size_t j( jbegin );
2885 
2886  for( ; (j+2UL) <= jend; j+=2UL ) {
2887  v_[i*nn_+j ] -= (~rhs)(i,j );
2888  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
2889  }
2890  if( j < jend ) {
2891  v_[i*nn_+j] -= (~rhs)(i,j);
2892  }
2893  }
2894  }
2895 }
2896 //*************************************************************************************************
2897 
2898 
2899 //*************************************************************************************************
2910 template< typename Type // Data type of the matrix
2911  , bool SO > // Storage order
2912 template< typename MT > // Type of the right-hand side dense matrix
2913 inline EnableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
2915 {
2918 
2919  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2920  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2921 
2922  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2923 
2924  for( size_t i=0UL; i<m_; ++i )
2925  {
2926  const size_t jbegin( ( IsUpper<MT>::value )
2927  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2928  :( 0UL ) );
2929  const size_t jend ( ( IsLower<MT>::value )
2930  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2931  :( n_ ) );
2932  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2933 
2934  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2935  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2936 
2937  size_t j( jbegin );
2938  Iterator left( begin(i) + jbegin );
2939  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2940 
2941  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2942  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2943  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2944  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2945  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2946  }
2947  for( ; j<jpos; j+=SIMDSIZE ) {
2948  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2949  }
2950  for( ; remainder && j<jend; ++j ) {
2951  *left -= *right; ++left; ++right;
2952  }
2953  }
2954 }
2955 //*************************************************************************************************
2956 
2957 
2958 //*************************************************************************************************
2969 template< typename Type // Data type of the matrix
2970  , bool SO > // Storage order
2971 template< typename MT > // Type of the right-hand side dense matrix
2973 {
2975 
2976  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2977  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2978 
2979  constexpr size_t block( BLOCK_SIZE );
2980 
2981  for( size_t ii=0UL; ii<m_; ii+=block ) {
2982  const size_t iend( min( m_, ii+block ) );
2983  for( size_t jj=0UL; jj<n_; jj+=block )
2984  {
2985  if( IsLower<MT>::value && ii < jj ) break;
2986  if( IsUpper<MT>::value && ii > jj ) continue;
2987 
2988  for( size_t i=ii; i<iend; ++i )
2989  {
2990  const size_t jbegin( ( IsUpper<MT>::value )
2991  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2992  :( jj ) );
2993  const size_t jend ( ( IsLower<MT>::value )
2994  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2995  :( min( n_, jj+block ) ) );
2996  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2997 
2998  for( size_t j=jbegin; j<jend; ++j ) {
2999  v_[i*nn_+j] -= (~rhs)(i,j);
3000  }
3001  }
3002  }
3003  }
3004 }
3005 //*************************************************************************************************
3006 
3007 
3008 //*************************************************************************************************
3019 template< typename Type // Data type of the matrix
3020  , bool SO > // Storage order
3021 template< typename MT > // Type of the right-hand side sparse matrix
3023 {
3024  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3025  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3026 
3027  for( size_t i=0UL; i<m_; ++i )
3028  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3029  v_[i*nn_+element->index()] -= element->value();
3030 }
3031 //*************************************************************************************************
3032 
3033 
3034 //*************************************************************************************************
3045 template< typename Type // Data type of the matrix
3046  , bool SO > // Storage order
3047 template< typename MT > // Type of the right-hand side sparse matrix
3049 {
3051 
3052  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3053  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3054 
3055  for( size_t j=0UL; j<n_; ++j )
3056  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3057  v_[element->index()*nn_+j] -= element->value();
3058 }
3059 //*************************************************************************************************
3060 
3061 
3062 //*************************************************************************************************
3073 template< typename Type // Data type of the matrix
3074  , bool SO > // Storage order
3075 template< typename MT > // Type of the right-hand side dense matrix
3076 inline DisableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3078 {
3079  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3080  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3081 
3082  const size_t jpos( n_ & size_t(-2) );
3083  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
3084 
3085  for( size_t i=0UL; i<m_; ++i ) {
3086  for( size_t j=0UL; j<jpos; j+=2UL ) {
3087  v_[i*nn_+j ] *= (~rhs)(i,j );
3088  v_[i*nn_+j+1UL] *= (~rhs)(i,j+1UL);
3089  }
3090  if( jpos < n_ ) {
3091  v_[i*nn_+jpos] *= (~rhs)(i,jpos);
3092  }
3093  }
3094 }
3095 //*************************************************************************************************
3096 
3097 
3098 //*************************************************************************************************
3109 template< typename Type // Data type of the matrix
3110  , bool SO > // Storage order
3111 template< typename MT > // Type of the right-hand side dense matrix
3112 inline EnableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3114 {
3116 
3117  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3118  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3119 
3120  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
3121 
3122  for( size_t i=0UL; i<m_; ++i )
3123  {
3124  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
3125  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3126 
3127  size_t j( 0UL );
3128  Iterator left( begin(i) );
3129  ConstIterator_<MT> right( (~rhs).begin(i) );
3130 
3131  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3132  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3133  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3134  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3135  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3136  }
3137  for( ; j<jpos; j+=SIMDSIZE ) {
3138  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3139  }
3140  for( ; remainder && j<n_; ++j ) {
3141  *left *= *right; ++left; ++right;
3142  }
3143  }
3144 }
3145 //*************************************************************************************************
3146 
3147 
3148 //*************************************************************************************************
3159 template< typename Type // Data type of the matrix
3160  , bool SO > // Storage order
3161 template< typename MT > // Type of the right-hand side dense matrix
3163 {
3165 
3166  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3167  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3168 
3169  constexpr size_t block( BLOCK_SIZE );
3170 
3171  for( size_t ii=0UL; ii<m_; ii+=block ) {
3172  const size_t iend( min( m_, ii+block ) );
3173  for( size_t jj=0UL; jj<n_; jj+=block ) {
3174  const size_t jend( min( n_, jj+block ) );
3175  for( size_t i=ii; i<iend; ++i ) {
3176  for( size_t j=jj; j<jend; ++j ) {
3177  v_[i*nn_+j] *= (~rhs)(i,j);
3178  }
3179  }
3180  }
3181  }
3182 }
3183 //*************************************************************************************************
3184 
3185 
3186 //*************************************************************************************************
3197 template< typename Type // Data type of the matrix
3198  , bool SO > // Storage order
3199 template< typename MT > // Type of the right-hand side sparse matrix
3201 {
3202  using blaze::reset;
3203 
3204  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3205  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3206 
3207  for( size_t i=0UL; i<m_; ++i )
3208  {
3209  size_t j( 0UL );
3210 
3211  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
3212  for( ; j<element->index(); ++j )
3213  reset( v_[i*nn_+j] );
3214  v_[i*nn_+j] *= element->value();
3215  ++j;
3216  }
3217 
3218  for( ; j<n_; ++j ) {
3219  reset( v_[i*nn_+j] );
3220  }
3221  }
3222 }
3223 //*************************************************************************************************
3224 
3225 
3226 //*************************************************************************************************
3237 template< typename Type // Data type of the matrix
3238  , bool SO > // Storage order
3239 template< typename MT > // Type of the right-hand side sparse matrix
3241 {
3242  using blaze::reset;
3243 
3245 
3246  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3247  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3248 
3249  for( size_t j=0UL; j<n_; ++j )
3250  {
3251  size_t i( 0UL );
3252 
3253  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
3254  for( ; i<element->index(); ++i )
3255  reset( v_[i*nn_+j] );
3256  v_[i*nn_+j] *= element->value();
3257  ++i;
3258  }
3259 
3260  for( ; i<m_; ++i ) {
3261  reset( v_[i*nn_+j] );
3262  }
3263  }
3264 }
3265 //*************************************************************************************************
3266 
3267 
3268 
3269 
3270 
3271 
3272 
3273 
3274 //=================================================================================================
3275 //
3276 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3277 //
3278 //=================================================================================================
3279 
3280 //*************************************************************************************************
3288 template< typename Type > // Data type of the matrix
3289 class DynamicMatrix<Type,true>
3290  : public DenseMatrix< DynamicMatrix<Type,true>, true >
3291 {
3292  public:
3293  //**Type definitions****************************************************************************
3294  using This = DynamicMatrix<Type,true>;
3296  using ResultType = This;
3299  using ElementType = Type;
3301  using ReturnType = const Type&;
3302  using CompositeType = const This&;
3303 
3304  using Reference = Type&;
3305  using ConstReference = const Type&;
3306  using Pointer = Type*;
3307  using ConstPointer = const Type*;
3308 
3311  //**********************************************************************************************
3312 
3313  //**Rebind struct definition********************************************************************
3316  template< typename NewType > // Data type of the other matrix
3317  struct Rebind {
3318  using Other = DynamicMatrix<NewType,true>;
3319  };
3320  //**********************************************************************************************
3321 
3322  //**Resize struct definition********************************************************************
3325  template< size_t NewM // Number of rows of the other matrix
3326  , size_t NewN > // Number of columns of the other matrix
3327  struct Resize {
3328  using Other = DynamicMatrix<Type,true>;
3329  };
3330  //**********************************************************************************************
3331 
3332  //**Compilation flags***************************************************************************
3334 
3338  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3339 
3341 
3344  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
3345  //**********************************************************************************************
3346 
3347  //**Constructors********************************************************************************
3350  explicit inline DynamicMatrix() noexcept;
3351  explicit inline DynamicMatrix( size_t m, size_t n );
3352  explicit inline DynamicMatrix( size_t m, size_t n, const Type& init );
3353  explicit inline DynamicMatrix( initializer_list< initializer_list<Type> > list );
3354 
3355  template< typename Other > explicit inline DynamicMatrix( size_t m, size_t n, const Other* array );
3356 
3357  template< typename Other, size_t Rows, size_t Cols >
3358  explicit inline DynamicMatrix( const Other (&array)[Rows][Cols] );
3359 
3360  inline DynamicMatrix( const DynamicMatrix& m );
3361  inline DynamicMatrix( DynamicMatrix&& m );
3362  template< typename MT, bool SO > inline DynamicMatrix( const Matrix<MT,SO>& m );
3364  //**********************************************************************************************
3365 
3366  //**Destructor**********************************************************************************
3369  inline ~DynamicMatrix();
3371  //**********************************************************************************************
3372 
3373  //**Data access functions***********************************************************************
3376  inline Reference operator()( size_t i, size_t j ) noexcept;
3377  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3378  inline Reference at( size_t i, size_t j );
3379  inline ConstReference at( size_t i, size_t j ) const;
3380  inline Pointer data () noexcept;
3381  inline ConstPointer data () const noexcept;
3382  inline Pointer data ( size_t j ) noexcept;
3383  inline ConstPointer data ( size_t j ) const noexcept;
3384  inline Iterator begin ( size_t j ) noexcept;
3385  inline ConstIterator begin ( size_t j ) const noexcept;
3386  inline ConstIterator cbegin( size_t j ) const noexcept;
3387  inline Iterator end ( size_t j ) noexcept;
3388  inline ConstIterator end ( size_t j ) const noexcept;
3389  inline ConstIterator cend ( size_t j ) const noexcept;
3391  //**********************************************************************************************
3392 
3393  //**Assignment operators************************************************************************
3396  inline DynamicMatrix& operator=( const Type& rhs );
3397  inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list );
3398 
3399  template< typename Other, size_t Rows, size_t Cols >
3400  inline DynamicMatrix& operator=( const Other (&array)[Rows][Cols] );
3401 
3402  inline DynamicMatrix& operator=( const DynamicMatrix& rhs );
3403  inline DynamicMatrix& operator=( DynamicMatrix&& rhs );
3404 
3405  template< typename MT, bool SO > inline DynamicMatrix& operator= ( const Matrix<MT,SO>& rhs );
3406  template< typename MT, bool SO > inline DynamicMatrix& operator+=( const Matrix<MT,SO>& rhs );
3407  template< typename MT, bool SO > inline DynamicMatrix& operator-=( const Matrix<MT,SO>& rhs );
3408  template< typename MT, bool SO > inline DynamicMatrix& operator%=( const Matrix<MT,SO>& rhs );
3409  template< typename MT, bool SO > inline DynamicMatrix& operator*=( const Matrix<MT,SO>& rhs );
3410 
3411  template< typename Other >
3412  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator*=( Other rhs );
3413 
3414  template< typename Other >
3415  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator/=( Other rhs );
3417  //**********************************************************************************************
3418 
3419  //**Utility functions***************************************************************************
3422  inline size_t rows() const noexcept;
3423  inline size_t columns() const noexcept;
3424  inline size_t spacing() const noexcept;
3425  inline size_t capacity() const noexcept;
3426  inline size_t capacity( size_t j ) const noexcept;
3427  inline size_t nonZeros() const;
3428  inline size_t nonZeros( size_t j ) const;
3429  inline void reset();
3430  inline void reset( size_t j );
3431  inline void clear();
3432  void resize ( size_t m, size_t n, bool preserve=true );
3433  inline void extend ( size_t m, size_t n, bool preserve=true );
3434  inline void reserve( size_t elements );
3435  inline void shrinkToFit();
3436  inline void swap( DynamicMatrix& m ) noexcept;
3438  //**********************************************************************************************
3439 
3440  //**Numeric functions***************************************************************************
3443  inline DynamicMatrix& transpose();
3444  inline DynamicMatrix& ctranspose();
3445 
3446  template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
3448  //**********************************************************************************************
3449 
3450  private:
3451  //**********************************************************************************************
3453  template< typename MT >
3454  struct VectorizedAssign {
3455  enum : bool { value = useOptimizedKernels &&
3456  simdEnabled && MT::simdEnabled &&
3458  };
3459  //**********************************************************************************************
3460 
3461  //**********************************************************************************************
3463  template< typename MT >
3464  struct VectorizedAddAssign {
3465  enum : bool { value = useOptimizedKernels &&
3466  simdEnabled && MT::simdEnabled &&
3470  };
3471  //**********************************************************************************************
3472 
3473  //**********************************************************************************************
3475  template< typename MT >
3476  struct VectorizedSubAssign {
3477  enum : bool { value = useOptimizedKernels &&
3478  simdEnabled && MT::simdEnabled &&
3482  };
3483  //**********************************************************************************************
3484 
3485  //**********************************************************************************************
3487  template< typename MT >
3488  struct VectorizedSchurAssign {
3489  enum : bool { value = useOptimizedKernels &&
3490  simdEnabled && MT::simdEnabled &&
3493  };
3494  //**********************************************************************************************
3495 
3496  //**********************************************************************************************
3498  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3499  //**********************************************************************************************
3500 
3501  public:
3502  //**Debugging functions*************************************************************************
3505  inline bool isIntact() const noexcept;
3507  //**********************************************************************************************
3508 
3509  //**Expression template evaluation functions****************************************************
3512  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3513  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3514 
3515  inline bool isAligned () const noexcept;
3516  inline bool canSMPAssign() const noexcept;
3517 
3518  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3519  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3520  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3521 
3522  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3523  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3524  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3525  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3526 
3527  template< typename MT >
3528  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3529 
3530  template< typename MT >
3531  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3532 
3533  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3534  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3535  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3536 
3537  template< typename MT >
3538  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3539 
3540  template< typename MT >
3541  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3542 
3543  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3544  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3545  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3546 
3547  template< typename MT >
3548  inline DisableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3549 
3550  template< typename MT >
3551  inline EnableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3552 
3553  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3554  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3555  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3556 
3557  template< typename MT >
3558  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign ( const DenseMatrix<MT,true>& rhs );
3559 
3560  template< typename MT >
3561  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign ( const DenseMatrix<MT,true>& rhs );
3562 
3563  template< typename MT > inline void schurAssign( const DenseMatrix<MT,false>& rhs );
3564  template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3565  template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3567  //**********************************************************************************************
3568 
3569  private:
3570  //**Utility functions***************************************************************************
3573  inline size_t addPadding( size_t minRows ) const noexcept;
3575  //**********************************************************************************************
3576 
3577  //**Member variables****************************************************************************
3580  size_t m_;
3581  size_t mm_;
3582  size_t n_;
3583  size_t capacity_;
3584  Type* BLAZE_RESTRICT v_;
3585 
3588  //**********************************************************************************************
3589 
3590  //**Compile time checks*************************************************************************
3595  //**********************************************************************************************
3596 };
3598 //*************************************************************************************************
3599 
3600 
3601 
3602 
3603 //=================================================================================================
3604 //
3605 // CONSTRUCTORS
3606 //
3607 //=================================================================================================
3608 
3609 //*************************************************************************************************
3613 template< typename Type > // Data type of the matrix
3615  : m_ ( 0UL ) // The current number of rows of the matrix
3616  , mm_ ( 0UL ) // The alignment adjusted number of rows
3617  , n_ ( 0UL ) // The current number of columns of the matrix
3618  , capacity_( 0UL ) // The maximum capacity of the matrix
3619  , v_ ( nullptr ) // The matrix elements
3620 {}
3622 //*************************************************************************************************
3623 
3624 
3625 //*************************************************************************************************
3635 template< typename Type > // Data type of the matrix
3636 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n )
3637  : m_ ( m ) // The current number of rows of the matrix
3638  , mm_ ( addPadding( m ) ) // The alignment adjusted number of rows
3639  , n_ ( n ) // The current number of columns of the matrix
3640  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3641  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3642 {
3644  for( size_t j=0UL; j<n_; ++j ) {
3645  for( size_t i=m_; i<mm_; ++i ) {
3646  v_[i+j*mm_] = Type();
3647  }
3648  }
3649  }
3650 
3651  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3652 }
3654 //*************************************************************************************************
3655 
3656 
3657 //*************************************************************************************************
3667 template< typename Type > // Data type of the matrix
3668 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, const Type& init )
3669  : m_ ( m ) // The current number of rows of the matrix
3670  , mm_ ( addPadding( m ) ) // The alignment adjusted number of rows
3671  , n_ ( n ) // The current number of columns of the matrix
3672  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3673  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3674 {
3675  for( size_t j=0UL; j<n_; ++j ) {
3676  for( size_t i=0UL; i<m_; ++i )
3677  v_[i+j*mm_] = init;
3678 
3680  for( size_t i=m_; i<mm_; ++i )
3681  v_[i+j*mm_] = Type();
3682  }
3683  }
3684 
3685  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3686 }
3688 //*************************************************************************************************
3689 
3690 
3691 //*************************************************************************************************
3712 template< typename Type > // Data type of the matrix
3714  : m_ ( list.size() ) // The current number of rows of the matrix
3715  , mm_ ( addPadding( m_ ) ) // The alignment adjusted number of rows
3716  , n_ ( determineColumns( list ) ) // The current number of columns of the matrix
3717  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3718  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3719 {
3720  size_t i( 0UL );
3721 
3722  for( const auto& rowList : list ) {
3723  size_t j( 0UL );
3724  for( const auto& element : rowList ) {
3725  v_[i+j*mm_] = element;
3726  ++j;
3727  }
3728  for( ; j<n_; ++j ) {
3729  v_[i+j*mm_] = Type();
3730  }
3731  ++i;
3732  }
3733 
3734  BLAZE_INTERNAL_ASSERT( i == m_, "Invalid number of elements detected" );
3735 
3737  for( ; i<mm_; ++i ) {
3738  for( size_t j=0UL; j<n_; ++j ) {
3739  v_[i+j*mm_] = Type();
3740  }
3741  }
3742  }
3743 
3744  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3745 }
3747 //*************************************************************************************************
3748 
3749 
3750 //*************************************************************************************************
3774 template< typename Type > // Data type of the matrix
3775 template< typename Other > // Data type of the initialization array
3776 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, const Other* array )
3777  : m_ ( m ) // The current number of rows of the matrix
3778  , mm_ ( addPadding( m ) ) // The alignment adjusted number of rows
3779  , n_ ( n ) // The current number of columns of the matrix
3780  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3781  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3782 {
3783  for( size_t j=0UL; j<n; ++j ) {
3784  for( size_t i=0UL; i<m; ++i )
3785  v_[i+j*mm_] = array[i+j*m];
3786 
3788  for( size_t i=m; i<mm_; ++i )
3789  v_[i+j*mm_] = Type();
3790  }
3791  }
3792 
3793  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3794 }
3796 //*************************************************************************************************
3797 
3798 
3799 //*************************************************************************************************
3821 template< typename Type > // Data type of the matrix
3822 template< typename Other // Data type of the initialization array
3823  , size_t Rows // Number of rows of the initialization array
3824  , size_t Cols > // Number of columns of the initialization array
3825 inline DynamicMatrix<Type,true>::DynamicMatrix( const Other (&array)[Rows][Cols] )
3826  : m_ ( Rows ) // The current number of rows of the matrix
3827  , mm_ ( addPadding( Rows ) ) // The alignment adjusted number of rows
3828  , n_ ( Cols ) // The current number of columns of the matrix
3829  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3830  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3831 {
3832  for( size_t j=0UL; j<Cols; ++j ) {
3833  for( size_t i=0UL; i<Rows; ++i )
3834  v_[i+j*mm_] = array[i][j];
3835 
3837  for( size_t i=Rows; i<mm_; ++i )
3838  v_[i+j*mm_] = Type();
3839  }
3840  }
3841 
3842  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3843 }
3845 //*************************************************************************************************
3846 
3847 
3848 //*************************************************************************************************
3857 template< typename Type > // Data type of the matrix
3859  : m_ ( m.m_ ) // The current number of rows of the matrix
3860  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
3861  , n_ ( m.n_ ) // The current number of columns of the matrix
3862  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3863  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3864 {
3865  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
3866 
3867  for( size_t i=0UL; i<capacity_; ++i )
3868  v_[i] = m.v_[i];
3869 
3870  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3871 }
3873 //*************************************************************************************************
3874 
3875 
3876 //*************************************************************************************************
3882 template< typename Type > // Data type of the matrix
3884  : m_ ( m.m_ ) // The current number of rows of the matrix
3885  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
3886  , n_ ( m.n_ ) // The current number of columns of the matrix
3887  , capacity_( m.capacity_ ) // The maximum capacity of the matrix
3888  , v_ ( m.v_ ) // The matrix elements
3889 {
3890  m.m_ = 0UL;
3891  m.mm_ = 0UL;
3892  m.n_ = 0UL;
3893  m.capacity_ = 0UL;
3894  m.v_ = nullptr;
3895 }
3897 //*************************************************************************************************
3898 
3899 
3900 //*************************************************************************************************
3906 template< typename Type > // Data type of the matrix
3907 template< typename MT // Type of the foreign matrix
3908  , bool SO > // Storage order of the foreign matrix
3910  : m_ ( (~m).rows() ) // The current number of rows of the matrix
3911  , mm_ ( addPadding( m_ ) ) // The alignment adjusted number of rows
3912  , n_ ( (~m).columns() ) // The current number of columns of the matrix
3913  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3914  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3915 {
3916  for( size_t j=0UL; j<n_; ++j ) {
3917  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : m_ );
3918  i<( IsVectorizable<Type>::value ? mm_ : m_ ); ++i ) {
3919  v_[i+j*mm_] = Type();
3920  }
3921  }
3922 
3923  smpAssign( *this, ~m );
3924 
3925  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3926 }
3928 //*************************************************************************************************
3929 
3930 
3931 
3932 
3933 //=================================================================================================
3934 //
3935 // DESTRUCTOR
3936 //
3937 //=================================================================================================
3938 
3939 //*************************************************************************************************
3943 template< typename Type > // Data type of the matrix
3945 {
3946  deallocate( v_ );
3947 }
3949 //*************************************************************************************************
3950 
3951 
3952 
3953 
3954 //=================================================================================================
3955 //
3956 // DATA ACCESS FUNCTIONS
3957 //
3958 //=================================================================================================
3959 
3960 //*************************************************************************************************
3971 template< typename Type > // Data type of the matrix
3973  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) noexcept
3974 {
3975  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3976  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3977  return v_[i+j*mm_];
3978 }
3980 //*************************************************************************************************
3981 
3982 
3983 //*************************************************************************************************
3994 template< typename Type > // Data type of the matrix
3996  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) const noexcept
3997 {
3998  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3999  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
4000  return v_[i+j*mm_];
4001 }
4003 //*************************************************************************************************
4004 
4005 
4006 //*************************************************************************************************
4018 template< typename Type > // Data type of the matrix
4020  DynamicMatrix<Type,true>::at( size_t i, size_t j )
4021 {
4022  if( i >= m_ ) {
4023  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4024  }
4025  if( j >= n_ ) {
4026  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4027  }
4028  return (*this)(i,j);
4029 }
4031 //*************************************************************************************************
4032 
4033 
4034 //*************************************************************************************************
4046 template< typename Type > // Data type of the matrix
4048  DynamicMatrix<Type,true>::at( size_t i, size_t j ) const
4049 {
4050  if( i >= m_ ) {
4051  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4052  }
4053  if( j >= n_ ) {
4054  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4055  }
4056  return (*this)(i,j);
4057 }
4059 //*************************************************************************************************
4060 
4061 
4062 //*************************************************************************************************
4074 template< typename Type > // Data type of the matrix
4075 inline typename DynamicMatrix<Type,true>::Pointer
4077 {
4078  return v_;
4079 }
4081 //*************************************************************************************************
4082 
4083 
4084 //*************************************************************************************************
4096 template< typename Type > // Data type of the matrix
4098  DynamicMatrix<Type,true>::data() const noexcept
4099 {
4100  return v_;
4101 }
4103 //*************************************************************************************************
4104 
4105 
4106 //*************************************************************************************************
4115 template< typename Type > // Data type of the matrix
4116 inline typename DynamicMatrix<Type,true>::Pointer
4117  DynamicMatrix<Type,true>::data( size_t j ) noexcept
4118 {
4119  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4120  return v_ + j*mm_;
4121 }
4123 //*************************************************************************************************
4124 
4125 
4126 //*************************************************************************************************
4135 template< typename Type > // Data type of the matrix
4137  DynamicMatrix<Type,true>::data( size_t j ) const noexcept
4138 {
4139  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4140  return v_ + j*mm_;
4141 }
4143 //*************************************************************************************************
4144 
4145 
4146 //*************************************************************************************************
4153 template< typename Type > // Data type of the matrix
4154 inline typename DynamicMatrix<Type,true>::Iterator
4155  DynamicMatrix<Type,true>::begin( size_t j ) noexcept
4156 {
4157  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4158  return Iterator( v_ + j*mm_ );
4159 }
4161 //*************************************************************************************************
4162 
4163 
4164 //*************************************************************************************************
4171 template< typename Type > // Data type of the matrix
4173  DynamicMatrix<Type,true>::begin( size_t j ) const noexcept
4174 {
4175  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4176  return ConstIterator( v_ + j*mm_ );
4177 }
4179 //*************************************************************************************************
4180 
4181 
4182 //*************************************************************************************************
4189 template< typename Type > // Data type of the matrix
4191  DynamicMatrix<Type,true>::cbegin( size_t j ) const noexcept
4192 {
4193  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4194  return ConstIterator( v_ + j*mm_ );
4195 }
4197 //*************************************************************************************************
4198 
4199 
4200 //*************************************************************************************************
4207 template< typename Type > // Data type of the matrix
4208 inline typename DynamicMatrix<Type,true>::Iterator
4209  DynamicMatrix<Type,true>::end( size_t j ) noexcept
4210 {
4211  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4212  return Iterator( v_ + j*mm_ + m_ );
4213 }
4215 //*************************************************************************************************
4216 
4217 
4218 //*************************************************************************************************
4225 template< typename Type > // Data type of the matrix
4227  DynamicMatrix<Type,true>::end( size_t j ) const noexcept
4228 {
4229  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4230  return ConstIterator( v_ + j*mm_ + m_ );
4231 }
4233 //*************************************************************************************************
4234 
4235 
4236 //*************************************************************************************************
4243 template< typename Type > // Data type of the matrix
4245  DynamicMatrix<Type,true>::cend( size_t j ) const noexcept
4246 {
4247  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4248  return ConstIterator( v_ + j*mm_ + m_ );
4249 }
4251 //*************************************************************************************************
4252 
4253 
4254 
4255 
4256 //=================================================================================================
4257 //
4258 // ASSIGNMENT OPERATORS
4259 //
4260 //=================================================================================================
4261 
4262 //*************************************************************************************************
4269 template< typename Type > // Data type of the matrix
4271 {
4272  for( size_t j=0UL; j<n_; ++j )
4273  for( size_t i=0UL; i<m_; ++i )
4274  v_[i+j*mm_] = rhs;
4275 
4276  return *this;
4277 }
4279 //*************************************************************************************************
4280 
4281 
4282 //*************************************************************************************************
4304 template< typename Type > // Data type of the matrix
4307 {
4308  resize( list.size(), determineColumns( list ), false );
4309 
4310  size_t i( 0UL );
4311 
4312  for( const auto& rowList : list ) {
4313  size_t j( 0UL );
4314  for( const auto& element : rowList ) {
4315  v_[i+j*mm_] = element;
4316  ++j;
4317  }
4318  for( ; j<n_; ++j ) {
4319  v_[i+j*mm_] = Type();
4320  }
4321  ++i;
4322  }
4323 
4324  return *this;
4325 }
4327 //*************************************************************************************************
4328 
4329 
4330 //*************************************************************************************************
4352 template< typename Type > // Data type of the matrix
4353 template< typename Other // Data type of the initialization array
4354  , size_t Rows // Number of rows of the initialization array
4355  , size_t Cols > // Number of columns of the initialization array
4356 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Other (&array)[Rows][Cols] )
4357 {
4358  resize( Rows, Cols, false );
4359 
4360  for( size_t j=0UL; j<Cols; ++j )
4361  for( size_t i=0UL; i<Rows; ++i )
4362  v_[i+j*mm_] = array[i][j];
4363 
4364  return *this;
4365 }
4367 //*************************************************************************************************
4368 
4369 
4370 //*************************************************************************************************
4380 template< typename Type > // Data type of the matrix
4382 {
4383  if( &rhs == this ) return *this;
4384 
4385  resize( rhs.m_, rhs.n_, false );
4386  smpAssign( *this, ~rhs );
4387 
4388  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4389 
4390  return *this;
4391 }
4393 //*************************************************************************************************
4394 
4395 
4396 //*************************************************************************************************
4403 template< typename Type > // Data type of the matrix
4405 {
4406  deallocate( v_ );
4407 
4408  m_ = rhs.m_;
4409  mm_ = rhs.mm_;
4410  n_ = rhs.n_;
4411  capacity_ = rhs.capacity_;
4412  v_ = rhs.v_;
4413 
4414  rhs.m_ = 0UL;
4415  rhs.mm_ = 0UL;
4416  rhs.n_ = 0UL;
4417  rhs.capacity_ = 0UL;
4418  rhs.v_ = nullptr;
4419 
4420  return *this;
4421 }
4423 //*************************************************************************************************
4424 
4425 
4426 //*************************************************************************************************
4436 template< typename Type > // Data type of the matrix
4437 template< typename MT // Type of the right-hand side matrix
4438  , bool SO > // Storage order of the right-hand side matrix
4440 {
4441  using TT = TransExprTrait_<This>;
4442  using CT = CTransExprTrait_<This>;
4443  using IT = InvExprTrait_<This>;
4444 
4445  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4446  transpose();
4447  }
4448  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4449  ctranspose();
4450  }
4451  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4452  DynamicMatrix tmp( ~rhs );
4453  swap( tmp );
4454  }
4455  else {
4456  resize( (~rhs).rows(), (~rhs).columns(), false );
4458  reset();
4459  smpAssign( *this, ~rhs );
4460  }
4461 
4462  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4463 
4464  return *this;
4465 }
4467 //*************************************************************************************************
4468 
4469 
4470 //*************************************************************************************************
4481 template< typename Type > // Data type of the matrix
4482 template< typename MT // Type of the right-hand side matrix
4483  , bool SO > // Storage order of the right-hand side matrix
4485 {
4486  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4487  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4488  }
4489 
4490  if( (~rhs).canAlias( this ) ) {
4491  const ResultType_<MT> tmp( ~rhs );
4492  smpAddAssign( *this, tmp );
4493  }
4494  else {
4495  smpAddAssign( *this, ~rhs );
4496  }
4497 
4498  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4499 
4500  return *this;
4501 }
4503 //*************************************************************************************************
4504 
4505 
4506 //*************************************************************************************************
4517 template< typename Type > // Data type of the matrix
4518 template< typename MT // Type of the right-hand side matrix
4519  , bool SO > // Storage order of the right-hand side matrix
4521 {
4522  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4523  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4524  }
4525 
4526  if( (~rhs).canAlias( this ) ) {
4527  const ResultType_<MT> tmp( ~rhs );
4528  smpSubAssign( *this, tmp );
4529  }
4530  else {
4531  smpSubAssign( *this, ~rhs );
4532  }
4533 
4534  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4535 
4536  return *this;
4537 }
4539 //*************************************************************************************************
4540 
4541 
4542 //*************************************************************************************************
4553 template< typename Type > // Data type of the matrix
4554 template< typename MT // Type of the right-hand side matrix
4555  , bool SO > // Storage order of the right-hand side matrix
4557 {
4558  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4559  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4560  }
4561 
4562  if( (~rhs).canAlias( this ) ) {
4563  const ResultType_<MT> tmp( ~rhs );
4564  smpSchurAssign( *this, tmp );
4565  }
4566  else {
4567  smpSchurAssign( *this, ~rhs );
4568  }
4569 
4570  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4571 
4572  return *this;
4573 }
4575 //*************************************************************************************************
4576 
4577 
4578 //*************************************************************************************************
4589 template< typename Type > // Data type of the matrix
4590 template< typename MT // Type of the right-hand side matrix
4591  , bool SO > // Storage order of the right-hand side matrix
4593 {
4594  if( (~rhs).rows() != n_ ) {
4595  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4596  }
4597 
4598  DynamicMatrix tmp( *this * (~rhs) );
4599  swap( tmp );
4600 
4601  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4602 
4603  return *this;
4604 }
4606 //*************************************************************************************************
4607 
4608 
4609 //*************************************************************************************************
4617 template< typename Type > // Data type of the matrix
4618 template< typename Other > // Data type of the right-hand side scalar
4619 inline EnableIf_<IsNumeric<Other>, DynamicMatrix<Type,true> >&
4621 {
4622  smpAssign( *this, (*this) * rhs );
4623 
4624  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4625 
4626  return *this;
4627 }
4629 //*************************************************************************************************
4630 
4631 
4632 //*************************************************************************************************
4640 template< typename Type > // Data type of the matrix
4641 template< typename Other > // Data type of the right-hand side scalar
4642 inline EnableIf_<IsNumeric<Other>, DynamicMatrix<Type,true> >&
4644 {
4645  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4646 
4647  smpAssign( *this, (*this) / rhs );
4648 
4649  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4650 
4651  return *this;
4652 }
4654 //*************************************************************************************************
4655 
4656 
4657 
4658 
4659 //=================================================================================================
4660 //
4661 // UTILITY FUNCTIONS
4662 //
4663 //=================================================================================================
4664 
4665 //*************************************************************************************************
4671 template< typename Type > // Data type of the matrix
4672 inline size_t DynamicMatrix<Type,true>::rows() const noexcept
4673 {
4674  return m_;
4675 }
4677 //*************************************************************************************************
4678 
4679 
4680 //*************************************************************************************************
4686 template< typename Type > // Data type of the matrix
4687 inline size_t DynamicMatrix<Type,true>::columns() const noexcept
4688 {
4689  return n_;
4690 }
4692 //*************************************************************************************************
4693 
4694 
4695 //*************************************************************************************************
4704 template< typename Type > // Data type of the matrix
4705 inline size_t DynamicMatrix<Type,true>::spacing() const noexcept
4706 {
4707  return mm_;
4708 }
4710 //*************************************************************************************************
4711 
4712 
4713 //*************************************************************************************************
4719 template< typename Type > // Data type of the matrix
4720 inline size_t DynamicMatrix<Type,true>::capacity() const noexcept
4721 {
4722  return capacity_;
4723 }
4725 //*************************************************************************************************
4726 
4727 
4728 //*************************************************************************************************
4735 template< typename Type > // Data type of the matrix
4736 inline size_t DynamicMatrix<Type,true>::capacity( size_t j ) const noexcept
4737 {
4738  UNUSED_PARAMETER( j );
4739  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4740  return mm_;
4741 }
4743 //*************************************************************************************************
4744 
4745 
4746 //*************************************************************************************************
4752 template< typename Type > // Data type of the matrix
4753 inline size_t DynamicMatrix<Type,true>::nonZeros() const
4754 {
4755  size_t nonzeros( 0UL );
4756 
4757  for( size_t j=0UL; j<n_; ++j )
4758  for( size_t i=0UL; i<m_; ++i )
4759  if( !isDefault( v_[i+j*mm_] ) )
4760  ++nonzeros;
4761 
4762  return nonzeros;
4763 }
4765 //*************************************************************************************************
4766 
4767 
4768 //*************************************************************************************************
4775 template< typename Type > // Data type of the matrix
4776 inline size_t DynamicMatrix<Type,true>::nonZeros( size_t j ) const
4777 {
4778  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4779 
4780  const size_t iend( j*mm_ + m_ );
4781  size_t nonzeros( 0UL );
4782 
4783  for( size_t i=j*mm_; i<iend; ++i )
4784  if( !isDefault( v_[i] ) )
4785  ++nonzeros;
4786 
4787  return nonzeros;
4788 }
4790 //*************************************************************************************************
4791 
4792 
4793 //*************************************************************************************************
4799 template< typename Type > // Data type of the matrix
4800 inline void DynamicMatrix<Type,true>::reset()
4801 {
4802  using blaze::clear;
4803 
4804  for( size_t j=0UL; j<n_; ++j )
4805  for( size_t i=0UL; i<m_; ++i )
4806  clear( v_[i+j*mm_] );
4807 }
4809 //*************************************************************************************************
4810 
4811 
4812 //*************************************************************************************************
4822 template< typename Type > // Data type of the matrix
4823 inline void DynamicMatrix<Type,true>::reset( size_t j )
4824 {
4825  using blaze::clear;
4826 
4827  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4828  for( size_t i=0UL; i<m_; ++i )
4829  clear( v_[i+j*mm_] );
4830 }
4832 //*************************************************************************************************
4833 
4834 
4835 //*************************************************************************************************
4843 template< typename Type > // Data type of the matrix
4844 inline void DynamicMatrix<Type,true>::clear()
4845 {
4846  resize( 0UL, 0UL, false );
4847 }
4849 //*************************************************************************************************
4850 
4851 
4852 //*************************************************************************************************
4887 template< typename Type > // Data type of the matrix
4888 void DynamicMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
4889 {
4890  using blaze::min;
4891 
4892  if( m == m_ && n == n_ ) return;
4893 
4894  const size_t mm( addPadding( m ) );
4895 
4896  if( preserve )
4897  {
4898  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
4899  const size_t min_m( min( m, m_ ) );
4900  const size_t min_n( min( n, n_ ) );
4901 
4902  for( size_t j=0UL; j<min_n; ++j ) {
4903  transfer( v_+j*mm_, v_+min_m+j*mm_, v+j*mm );
4904  }
4905 
4906  std::swap( v_, v );
4907  deallocate( v );
4908  capacity_ = mm*n;
4909  }
4910  else if( mm*n > capacity_ ) {
4911  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
4912  std::swap( v_, v );
4913  deallocate( v );
4914  capacity_ = mm*n;
4915  }
4916 
4918  for( size_t j=0UL; j<n; ++j )
4919  for( size_t i=m; i<mm; ++i )
4920  v_[i+j*mm] = Type();
4921  }
4922 
4923  m_ = m;
4924  mm_ = mm;
4925  n_ = n;
4926 }
4928 //*************************************************************************************************
4929 
4930 
4931 //*************************************************************************************************
4946 template< typename Type > // Data type of the matrix
4947 inline void DynamicMatrix<Type,true>::extend( size_t m, size_t n, bool preserve )
4948 {
4949  resize( m_+m, n_+n, preserve );
4950 }
4952 //*************************************************************************************************
4953 
4954 
4955 //*************************************************************************************************
4965 template< typename Type > // Data type of the matrix
4966 inline void DynamicMatrix<Type,true>::reserve( size_t elements )
4967 {
4968  if( elements > capacity_ )
4969  {
4970  // Allocating a new array
4971  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
4972 
4973  // Initializing the new array
4974  transfer( v_, v_+capacity_, tmp );
4975 
4977  for( size_t i=capacity_; i<elements; ++i )
4978  tmp[i] = Type();
4979  }
4980 
4981  // Replacing the old array
4982  std::swap( tmp, v_ );
4983  deallocate( tmp );
4984  capacity_ = elements;
4985  }
4986 }
4988 //*************************************************************************************************
4989 
4990 
4991 //*************************************************************************************************
5002 template< typename Type > // Data type of the matrix
5004 {
5005  if( ( mm_ * n_ ) < capacity_ ) {
5006  DynamicMatrix( *this ).swap( *this );
5007  }
5008 }
5010 //*************************************************************************************************
5011 
5012 
5013 //*************************************************************************************************
5020 template< typename Type > // Data type of the matrix
5021 inline void DynamicMatrix<Type,true>::swap( DynamicMatrix& m ) noexcept
5022 {
5023  std::swap( m_ , m.m_ );
5024  std::swap( mm_, m.mm_ );
5025  std::swap( n_ , m.n_ );
5027  std::swap( v_ , m.v_ );
5028 }
5030 //*************************************************************************************************
5031 
5032 
5033 //*************************************************************************************************
5043 template< typename Type > // Data type of the matrix
5044 inline size_t DynamicMatrix<Type,true>::addPadding( size_t values ) const noexcept
5045 {
5046  if( usePadding && IsVectorizable<Type>::value )
5047  return nextMultiple<size_t>( values, SIMDSIZE );
5048  else return values;
5049 }
5051 //*************************************************************************************************
5052 
5053 
5054 
5055 
5056 //=================================================================================================
5057 //
5058 // NUMERIC FUNCTIONS
5059 //
5060 //=================================================================================================
5061 
5062 //*************************************************************************************************
5068 template< typename Type > // Data type of the matrix
5070 {
5071  using std::swap;
5072 
5073  constexpr size_t block( BLOCK_SIZE );
5074 
5075  if( m_ == n_ )
5076  {
5077  for( size_t jj=0UL; jj<n_; jj+=block ) {
5078  const size_t jend( min( jj+block, n_ ) );
5079  for( size_t ii=0UL; ii<=jj; ii+=block ) {
5080  for( size_t j=jj; j<jend; ++j ) {
5081  const size_t iend( min( ii+block, m_, j ) );
5082  for( size_t i=ii; i<iend; ++i ) {
5083  swap( v_[i+j*mm_], v_[j+i*mm_] );
5084  }
5085  }
5086  }
5087  }
5088  }
5089  else
5090  {
5091  DynamicMatrix tmp( trans(*this) );
5092  this->swap( tmp );
5093  }
5094 
5095  return *this;
5096 }
5098 //*************************************************************************************************
5099 
5100 
5101 //*************************************************************************************************
5107 template< typename Type > // Data type of the matrix
5109 {
5110  constexpr size_t block( BLOCK_SIZE );
5111 
5112  if( m_ == n_ )
5113  {
5114  for( size_t jj=0UL; jj<n_; jj+=block ) {
5115  const size_t jend( min( jj+block, n_ ) );
5116  for( size_t ii=0UL; ii<jj; ii+=block ) {
5117  const size_t iend( min( ii+block, m_ ) );
5118  for( size_t j=jj; j<jend; ++j ) {
5119  for( size_t i=ii; i<iend; ++i ) {
5120  cswap( v_[i+j*mm_], v_[j+i*mm_] );
5121  }
5122  }
5123  }
5124  for( size_t j=jj; j<jend; ++j ) {
5125  for( size_t i=jj; i<j; ++i ) {
5126  cswap( v_[i+j*mm_], v_[j+i*mm_] );
5127  }
5128  conjugate( v_[j+j*mm_] );
5129  }
5130  }
5131  }
5132  else
5133  {
5134  DynamicMatrix tmp( ctrans(*this) );
5135  this->swap( tmp );
5136  }
5137 
5138  return *this;
5139 }
5141 //*************************************************************************************************
5142 
5143 
5144 //*************************************************************************************************
5162 template< typename Type > // Data type of the matrix
5163 template< typename Other > // Data type of the scalar value
5164 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::scale( const Other& scalar )
5165 {
5166  for( size_t j=0UL; j<n_; ++j )
5167  for( size_t i=0UL; i<m_; ++i )
5168  v_[i+j*mm_] *= scalar;
5169 
5170  return *this;
5171 }
5173 //*************************************************************************************************
5174 
5175 
5176 
5177 
5178 //=================================================================================================
5179 //
5180 // DEBUGGING FUNCTIONS
5181 //
5182 //=================================================================================================
5183 
5184 //*************************************************************************************************
5194 template< typename Type > // Data type of the matrix
5195 inline bool DynamicMatrix<Type,true>::isIntact() const noexcept
5196 {
5197  if( m_ * n_ > capacity_ )
5198  return false;
5199 
5201  for( size_t j=0UL; j<n_; ++j ) {
5202  for( size_t i=m_; i<mm_; ++i ) {
5203  if( v_[i+j*mm_] != Type() )
5204  return false;
5205  }
5206  }
5207  }
5208 
5209  return true;
5210 }
5212 //*************************************************************************************************
5213 
5214 
5215 
5216 
5217 //=================================================================================================
5218 //
5219 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5220 //
5221 //=================================================================================================
5222 
5223 //*************************************************************************************************
5234 template< typename Type > // Data type of the matrix
5235 template< typename Other > // Data type of the foreign expression
5236 inline bool DynamicMatrix<Type,true>::canAlias( const Other* alias ) const noexcept
5237 {
5238  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5239 }
5241 //*************************************************************************************************
5242 
5243 
5244 //*************************************************************************************************
5255 template< typename Type > // Data type of the matrix
5256 template< typename Other > // Data type of the foreign expression
5257 inline bool DynamicMatrix<Type,true>::isAliased( const Other* alias ) const noexcept
5258 {
5259  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5260 }
5262 //*************************************************************************************************
5263 
5264 
5265 //*************************************************************************************************
5275 template< typename Type > // Data type of the matrix
5276 inline bool DynamicMatrix<Type,true>::isAligned() const noexcept
5277 {
5278  return ( usePadding || rows() % SIMDSIZE == 0UL );
5279 }
5281 //*************************************************************************************************
5282 
5283 
5284 //*************************************************************************************************
5295 template< typename Type > // Data type of the matrix
5296 inline bool DynamicMatrix<Type,true>::canSMPAssign() const noexcept
5297 {
5298  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
5299 }
5301 //*************************************************************************************************
5302 
5303 
5304 //*************************************************************************************************
5319 template< typename Type > // Data type of the matrix
5321  DynamicMatrix<Type,true>::load( size_t i, size_t j ) const noexcept
5322 {
5323  if( usePadding )
5324  return loada( i, j );
5325  else
5326  return loadu( i, j );
5327 }
5329 //*************************************************************************************************
5330 
5331 
5332 //*************************************************************************************************
5347 template< typename Type > // Data type of the matrix
5349  DynamicMatrix<Type,true>::loada( size_t i, size_t j ) const noexcept
5350 {
5351  using blaze::loada;
5352 
5354 
5355  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5356  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5357  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5358  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5359  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5360 
5361  return loada( v_+i+j*mm_ );
5362 }
5364 //*************************************************************************************************
5365 
5366 
5367 //*************************************************************************************************
5382 template< typename Type > // Data type of the matrix
5384  DynamicMatrix<Type,true>::loadu( size_t i, size_t j ) const noexcept
5385 {
5386  using blaze::loadu;
5387 
5389 
5390  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5391  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5392  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5393 
5394  return loadu( v_+i+j*mm_ );
5395 }
5397 //*************************************************************************************************
5398 
5399 
5400 //*************************************************************************************************
5416 template< typename Type > // Data type of the matrix
5418  DynamicMatrix<Type,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5419 {
5420  if( usePadding )
5421  storea( i, j, value );
5422  else
5423  storeu( i, j, value );
5424 }
5426 //*************************************************************************************************
5427 
5428 
5429 //*************************************************************************************************
5445 template< typename Type > // Data type of the matrix
5447  DynamicMatrix<Type,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5448 {
5449  using blaze::storea;
5450 
5452 
5453  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5454  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5455  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5456  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5457  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5458 
5459  storea( v_+i+j*mm_, value );
5460 }
5462 //*************************************************************************************************
5463 
5464 
5465 //*************************************************************************************************
5481 template< typename Type > // Data type of the matrix
5483  DynamicMatrix<Type,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5484 {
5485  using blaze::storeu;
5486 
5488 
5489  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5490  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5491  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5492 
5493  storeu( v_+i+j*mm_, value );
5494 }
5496 //*************************************************************************************************
5497 
5498 
5499 //*************************************************************************************************
5516 template< typename Type > // Data type of the matrix
5518  DynamicMatrix<Type,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5519 {
5520  using blaze::stream;
5521 
5523 
5524  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5525  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5526  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5527  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5528  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5529 
5530  stream( v_+i+j*mm_, value );
5531 }
5533 //*************************************************************************************************
5534 
5535 
5536 //*************************************************************************************************
5548 template< typename Type > // Data type of the matrix
5549 template< typename MT > // Type of the right-hand side dense matrix
5552 {
5553  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5554  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5555 
5556  const size_t ipos( m_ & size_t(-2) );
5557  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5558 
5559  for( size_t j=0UL; j<n_; ++j ) {
5560  for( size_t i=0UL; i<ipos; i+=2UL ) {
5561  v_[i +j*mm_] = (~rhs)(i ,j);
5562  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
5563  }
5564  if( ipos < m_ ) {
5565  v_[ipos+j*mm_] = (~rhs)(ipos,j);
5566  }
5567  }
5568 }
5570 //*************************************************************************************************
5571 
5572 
5573 //*************************************************************************************************
5585 template< typename Type > // Data type of the matrix
5586 template< typename MT > // Type of the right-hand side dense matrix
5589 {
5591 
5592  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5593  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5594 
5595  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5596 
5597  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5598  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5599 
5600  if( usePadding && useStreaming &&
5601  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
5602  {
5603  for( size_t j=0UL; j<n_; ++j )
5604  {
5605  size_t i( 0UL );
5606  Iterator left( begin(j) );
5607  ConstIterator_<MT> right( (~rhs).begin(j) );
5608 
5609  for( ; i<ipos; i+=SIMDSIZE ) {
5610  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5611  }
5612  for( ; remainder && i<m_; ++i ) {
5613  *left = *right; ++left; ++right;
5614  }
5615  }
5616  }
5617  else
5618  {
5619  for( size_t j=0UL; j<n_; ++j )
5620  {
5621  size_t i( 0UL );
5622  Iterator left( begin(j) );
5623  ConstIterator_<MT> right( (~rhs).begin(j) );
5624 
5625  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5626  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5627  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5628  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5629  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5630  }
5631  for( ; i<ipos; i+=SIMDSIZE ) {
5632  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5633  }
5634  for( ; remainder && i<m_; ++i ) {
5635  *left = *right; ++left; ++right;
5636  }
5637  }
5638  }
5639 }
5641 //*************************************************************************************************
5642 
5643 
5644 //*************************************************************************************************
5656 template< typename Type > // Data type of the matrix
5657 template< typename MT > // Type of the right-hand side dense matrix
5659 {
5661 
5662  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5663  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5664 
5665  constexpr size_t block( BLOCK_SIZE );
5666 
5667  for( size_t jj=0UL; jj<n_; jj+=block ) {
5668  const size_t jend( min( n_, jj+block ) );
5669  for( size_t ii=0UL; ii<m_; ii+=block ) {
5670  const size_t iend( min( m_, ii+block ) );
5671  for( size_t j=jj; j<jend; ++j ) {
5672  for( size_t i=ii; i<iend; ++i ) {
5673  v_[i+j*mm_] = (~rhs)(i,j);
5674  }
5675  }
5676  }
5677  }
5678 }
5680 //*************************************************************************************************
5681 
5682 
5683 //*************************************************************************************************
5695 template< typename Type > // Data type of the matrix
5696 template< typename MT > // Type of the right-hand side sparse matrix
5698 {
5699  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5700  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5701 
5702  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5703  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5704  v_[element->index()+j*mm_] = element->value();
5705 }
5707 //*************************************************************************************************
5708 
5709 
5710 //*************************************************************************************************
5722 template< typename Type > // Data type of the matrix
5723 template< typename MT > // Type of the right-hand side sparse matrix
5725 {
5727 
5728  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5729  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5730 
5731  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5732  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5733  v_[i+element->index()*mm_] = element->value();
5734 }
5736 //*************************************************************************************************
5737 
5738 
5739 //*************************************************************************************************
5751 template< typename Type > // Data type of the matrix
5752 template< typename MT > // Type of the right-hand side dense matrix
5753 inline DisableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5755 {
5756  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5757  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5758 
5759  for( size_t j=0UL; j<n_; ++j )
5760  {
5761  if( IsDiagonal<MT>::value )
5762  {
5763  v_[j+j*mm_] += (~rhs)(j,j);
5764  }
5765  else
5766  {
5767  const size_t ibegin( ( IsLower<MT>::value )
5768  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5769  :( 0UL ) );
5770  const size_t iend ( ( IsUpper<MT>::value )
5771  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5772  :( m_ ) );
5773  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5774 
5775  size_t i( ibegin );
5776 
5777  for( ; (i+2UL) <= iend; i+=2UL ) {
5778  v_[i +j*mm_] += (~rhs)(i ,j);
5779  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
5780  }
5781  if( i < iend ) {
5782  v_[i+j*mm_] += (~rhs)(i,j);
5783  }
5784  }
5785  }
5786 }
5788 //*************************************************************************************************
5789 
5790 
5791 //*************************************************************************************************
5803 template< typename Type > // Data type of the matrix
5804 template< typename MT > // Type of the right-hand side dense matrix
5805 inline EnableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5807 {
5810 
5811  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5812  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5813 
5814  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5815 
5816  for( size_t j=0UL; j<n_; ++j )
5817  {
5818  const size_t ibegin( ( IsLower<MT>::value )
5819  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5820  :( 0UL ) );
5821  const size_t iend ( ( IsUpper<MT>::value )
5822  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5823  :( m_ ) );
5824  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5825 
5826  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5827  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5828 
5829  size_t i( ibegin );
5830  Iterator left( begin(j) + ibegin );
5831  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
5832 
5833  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5834  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5835  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5836  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5837  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5838  }
5839  for( ; i<ipos; i+=SIMDSIZE ) {
5840  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5841  }
5842  for( ; remainder && i<iend; ++i ) {
5843  *left += *right; ++left; ++right;
5844  }
5845  }
5846 }
5848 //*************************************************************************************************
5849 
5850 
5851 //*************************************************************************************************
5863 template< typename Type > // Data type of the matrix
5864 template< typename MT > // Type of the right-hand side dense matrix
5866 {
5868 
5869  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5870  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5871 
5872  constexpr size_t block( BLOCK_SIZE );
5873 
5874  for( size_t jj=0UL; jj<n_; jj+=block ) {
5875  const size_t jend( min( n_, jj+block ) );
5876  for( size_t ii=0UL; ii<m_; ii+=block )
5877  {
5878  if( IsLower<MT>::value && ii < jj ) continue;
5879  if( IsUpper<MT>::value && ii > jj ) break;
5880 
5881  for( size_t j=jj; j<jend; ++j )
5882  {
5883  const size_t ibegin( ( IsLower<MT>::value )
5884  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5885  :( ii ) );
5886  const size_t iend ( ( IsUpper<MT>::value )
5887  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5888  :( min( m_, ii+block ) ) );
5889  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5890 
5891  for( size_t i=ibegin; i<iend; ++i ) {
5892  v_[i+j*mm_] += (~rhs)(i,j);
5893  }
5894  }
5895  }
5896  }
5897 }
5899 //*************************************************************************************************
5900 
5901 
5902 //*************************************************************************************************
5914 template< typename Type > // Data type of the matrix
5915 template< typename MT > // Type of the right-hand side sparse matrix
5917 {
5918  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5919  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5920 
5921  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5922  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5923  v_[element->index()+j*mm_] += element->value();
5924 }
5926 //*************************************************************************************************
5927 
5928 
5929 //*************************************************************************************************
5941 template< typename Type > // Data type of the matrix
5942 template< typename MT > // Type of the right-hand side sparse matrix
5944 {
5946 
5947  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5948  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5949 
5950  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5951  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5952  v_[i+element->index()*mm_] += element->value();
5953 }
5955 //*************************************************************************************************
5956 
5957 
5958 //*************************************************************************************************
5970 template< typename Type > // Data type of the matrix
5971 template< typename MT > // Type of the right-hand side dense matrix
5972 inline DisableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5974 {
5975  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5976  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5977 
5978  for( size_t j=0UL; j<n_; ++j )
5979  {
5980  if( IsDiagonal<MT>::value )
5981  {
5982  v_[j+j*mm_] -= (~rhs)(j,j);
5983  }
5984  else
5985  {
5986  const size_t ibegin( ( IsLower<MT>::value )
5987  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5988  :( 0UL ) );
5989  const size_t iend ( ( IsUpper<MT>::value )
5990  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5991  :( m_ ) );
5992  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5993 
5994  size_t i( ibegin );
5995 
5996  for( ; (i+2UL) <= iend; i+=2UL ) {
5997  v_[i +j*mm_] -= (~rhs)(i ,j);
5998  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
5999  }
6000  if( i < iend ) {
6001  v_[i+j*mm_] -= (~rhs)(i,j);
6002  }
6003  }
6004  }
6005 }
6007 //*************************************************************************************************
6008 
6009 
6010 //*************************************************************************************************
6022 template< typename Type > // Data type of the matrix
6023 template< typename MT > // Type of the right-hand side dense matrix
6024 inline EnableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
6026 {
6029 
6030  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6031  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6032 
6033  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
6034 
6035  for( size_t j=0UL; j<n_; ++j )
6036  {
6037  const size_t ibegin( ( IsLower<MT>::value )
6038  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
6039  :( 0UL ) );
6040  const size_t iend ( ( IsUpper<MT>::value )
6041  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6042  :( m_ ) );
6043  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6044 
6045  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
6046  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6047 
6048  size_t i( ibegin );
6049  Iterator left( begin(j) + ibegin );
6050  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
6051 
6052  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6053  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6054  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6055  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6056  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6057  }
6058  for( ; i<ipos; i+=SIMDSIZE ) {
6059  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6060  }
6061  for( ; remainder && i<iend; ++i ) {
6062  *left -= *right; ++left; ++right;
6063  }
6064  }
6065 }
6067 //*************************************************************************************************
6068 
6069 
6070 //*************************************************************************************************
6082 template< typename Type > // Data type of the matrix
6083 template< typename MT > // Type of the right-hand side dense matrix
6085 {
6087 
6088  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6089  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6090 
6091  constexpr size_t block( BLOCK_SIZE );
6092 
6093  for( size_t jj=0UL; jj<n_; jj+=block ) {
6094  const size_t jend( min( n_, jj+block ) );
6095  for( size_t ii=0UL; ii<m_; ii+=block )
6096  {
6097  if( IsLower<MT>::value && ii < jj ) continue;
6098  if( IsUpper<MT>::value && ii > jj ) break;
6099 
6100  for( size_t j=jj; j<jend; ++j )
6101  {
6102  const size_t ibegin( ( IsLower<MT>::value )
6103  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
6104  :( ii ) );
6105  const size_t iend ( ( IsUpper<MT>::value )
6106  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
6107  :( min( m_, ii+block ) ) );
6108  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6109 
6110  for( size_t i=ibegin; i<iend; ++i ) {
6111  v_[i+j*mm_] -= (~rhs)(i,j);
6112  }
6113  }
6114  }
6115  }
6116 }
6118 //*************************************************************************************************
6119 
6120 
6121 //*************************************************************************************************
6133 template< typename Type > // Data type of the matrix
6134 template< typename MT > // Type of the right-hand side sparse matrix
6136 {
6137  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6138  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6139 
6140  for( size_t j=0UL; j<(~rhs).columns(); ++j )
6141  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6142  v_[element->index()+j*mm_] -= element->value();
6143 }
6145 //*************************************************************************************************
6146 
6147 
6148 //*************************************************************************************************
6160 template< typename Type > // Data type of the matrix
6161 template< typename MT > // Type of the right-hand side sparse matrix
6163 {
6165 
6166  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6167  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6168 
6169  for( size_t i=0UL; i<(~rhs).rows(); ++i )
6170  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6171  v_[i+element->index()*mm_] -= element->value();
6172 }
6174 //*************************************************************************************************
6175 
6176 
6177 //*************************************************************************************************
6189 template< typename Type > // Data type of the matrix
6190 template< typename MT > // Type of the right-hand side dense matrix
6191 inline DisableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
6193 {
6194  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6195  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6196 
6197  const size_t ipos( m_ & size_t(-2) );
6198  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
6199 
6200  for( size_t j=0UL; j<n_; ++j ) {
6201  for( size_t i=0UL; (i+2UL) <= ipos; i+=2UL ) {
6202  v_[i +j*mm_] *= (~rhs)(i ,j);
6203  v_[i+1+j*mm_] *= (~rhs)(i+1,j);
6204  }
6205  if( ipos < m_ ) {
6206  v_[ipos+j*mm_] *= (~rhs)(ipos,j);
6207  }
6208  }
6209 }
6211 //*************************************************************************************************
6212 
6213 
6214 //*************************************************************************************************
6226 template< typename Type > // Data type of the matrix
6227 template< typename MT > // Type of the right-hand side dense matrix
6228 inline EnableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
6230 {
6232 
6233  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6234  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6235 
6236  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
6237 
6238  for( size_t j=0UL; j<n_; ++j )
6239  {
6240  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
6241  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6242 
6243  size_t i( 0UL );
6244  Iterator left( begin(j) );
6245  ConstIterator_<MT> right( (~rhs).begin(j) );
6246 
6247  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6248  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6249  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6250  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6251  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6252  }
6253  for( ; i<ipos; i+=SIMDSIZE ) {
6254  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6255  }
6256  for( ; remainder && i<m_; ++i ) {
6257  *left *= *right; ++left; ++right;
6258  }
6259  }
6260 }
6262 //*************************************************************************************************
6263 
6264 
6265 //*************************************************************************************************
6277 template< typename Type > // Data type of the matrix
6278 template< typename MT > // Type of the right-hand side dense matrix
6280 {
6282 
6283  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6284  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6285 
6286  constexpr size_t block( BLOCK_SIZE );
6287 
6288  for( size_t jj=0UL; jj<n_; jj+=block ) {
6289  const size_t jend( min( n_, jj+block ) );
6290  for( size_t ii=0UL; ii<m_; ii+=block ) {
6291  const size_t iend( min( m_, ii+block ) );
6292  for( size_t j=jj; j<jend; ++j ) {
6293  for( size_t i=ii; i<iend; ++i ) {
6294  v_[i+j*mm_] *= (~rhs)(i,j);
6295  }
6296  }
6297  }
6298  }
6299 }
6301 //*************************************************************************************************
6302 
6303 
6304 //*************************************************************************************************
6316 template< typename Type > // Data type of the matrix
6317 template< typename MT > // Type of the right-hand side sparse matrix
6319 {
6320  using blaze::reset;
6321 
6322  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6323  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6324 
6325  for( size_t j=0UL; j<n_; ++j )
6326  {
6327  size_t i( 0UL );
6328 
6329  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
6330  for( ; i<element->index(); ++i )
6331  reset( v_[i+j*mm_] );
6332  v_[i+j*mm_] *= element->value();
6333  ++i;
6334  }
6335 
6336  for( ; i<m_; ++i ) {
6337  reset( v_[i+j*mm_] );
6338  }
6339  }
6340 }
6342 //*************************************************************************************************
6343 
6344 
6345 //*************************************************************************************************
6357 template< typename Type > // Data type of the matrix
6358 template< typename MT > // Type of the right-hand side sparse matrix
6360 {
6361  using blaze::reset;
6362 
6364 
6365  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6366  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6367 
6368  for( size_t i=0UL; i<m_; ++i )
6369  {
6370  size_t j( 0UL );
6371 
6372  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
6373  for( ; j<element->index(); ++j )
6374  reset( v_[i+j*mm_] );
6375  v_[i+j*mm_] *= element->value();
6376  ++j;
6377  }
6378 
6379  for( ; j<n_; ++j ) {
6380  reset( v_[i+j*mm_] );
6381  }
6382  }
6383 }
6385 //*************************************************************************************************
6386 
6387 
6388 
6389 
6390 
6391 
6392 
6393 
6394 //=================================================================================================
6395 //
6396 // DYNAMICMATRIX OPERATORS
6397 //
6398 //=================================================================================================
6399 
6400 //*************************************************************************************************
6403 template< typename Type, bool SO >
6404 inline void reset( DynamicMatrix<Type,SO>& m );
6405 
6406 template< typename Type, bool SO >
6407 inline void reset( DynamicMatrix<Type,SO>& m, size_t i );
6408 
6409 template< typename Type, bool SO >
6410 inline void clear( DynamicMatrix<Type,SO>& m );
6411 
6412 template< bool RF, typename Type, bool SO >
6413 inline bool isDefault( const DynamicMatrix<Type,SO>& m );
6414 
6415 template< typename Type, bool SO >
6416 inline bool isIntact( const DynamicMatrix<Type,SO>& m ) noexcept;
6417 
6418 template< typename Type, bool SO >
6419 inline void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) noexcept;
6421 //*************************************************************************************************
6422 
6423 
6424 //*************************************************************************************************
6431 template< typename Type // Data type of the matrix
6432  , bool SO > // Storage order
6434 {
6435  m.reset();
6436 }
6437 //*************************************************************************************************
6438 
6439 
6440 //*************************************************************************************************
6453 template< typename Type // Data type of the matrix
6454  , bool SO > // Storage order
6455 inline void reset( DynamicMatrix<Type,SO>& m, size_t i )
6456 {
6457  m.reset( i );
6458 }
6459 //*************************************************************************************************
6460 
6461 
6462 //*************************************************************************************************
6469 template< typename Type // Data type of the matrix
6470  , bool SO > // Storage order
6472 {
6473  m.clear();
6474 }
6475 //*************************************************************************************************
6476 
6477 
6478 //*************************************************************************************************
6503 template< bool RF // Relaxation flag
6504  , typename Type // Data type of the matrix
6505  , bool SO > // Storage order
6506 inline bool isDefault( const DynamicMatrix<Type,SO>& m )
6507 {
6508  return ( m.rows() == 0UL && m.columns() == 0UL );
6509 }
6510 //*************************************************************************************************
6511 
6512 
6513 //*************************************************************************************************
6531 template< typename Type // Data type of the matrix
6532  , bool SO > // Storage order
6533 inline bool isIntact( const DynamicMatrix<Type,SO>& m ) noexcept
6534 {
6535  return m.isIntact();
6536 }
6537 //*************************************************************************************************
6538 
6539 
6540 //*************************************************************************************************
6548 template< typename Type // Data type of the matrix
6549  , bool SO > // Storage order
6551 {
6552  a.swap( b );
6553 }
6554 //*************************************************************************************************
6555 
6556 
6557 
6558 
6559 //=================================================================================================
6560 //
6561 // HASCONSTDATAACCESS SPECIALIZATIONS
6562 //
6563 //=================================================================================================
6564 
6565 //*************************************************************************************************
6567 template< typename T, bool SO >
6568 struct HasConstDataAccess< DynamicMatrix<T,SO> >
6569  : public TrueType
6570 {};
6572 //*************************************************************************************************
6573 
6574 
6575 
6576 
6577 //=================================================================================================
6578 //
6579 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6580 //
6581 //=================================================================================================
6582 
6583 //*************************************************************************************************
6585 template< typename T, bool SO >
6586 struct HasMutableDataAccess< DynamicMatrix<T,SO> >
6587  : public TrueType
6588 {};
6590 //*************************************************************************************************
6591 
6592 
6593 
6594 
6595 //=================================================================================================
6596 //
6597 // ISALIGNED SPECIALIZATIONS
6598 //
6599 //=================================================================================================
6600 
6601 //*************************************************************************************************
6603 template< typename T, bool SO >
6604 struct IsAligned< DynamicMatrix<T,SO> >
6605  : public BoolConstant<usePadding>
6606 {};
6608 //*************************************************************************************************
6609 
6610 
6611 
6612 
6613 //=================================================================================================
6614 //
6615 // ISPADDED SPECIALIZATIONS
6616 //
6617 //=================================================================================================
6618 
6619 //*************************************************************************************************
6621 template< typename T, bool SO >
6622 struct IsPadded< DynamicMatrix<T,SO> >
6623  : public BoolConstant<usePadding>
6624 {};
6626 //*************************************************************************************************
6627 
6628 
6629 
6630 
6631 //=================================================================================================
6632 //
6633 // ISRESIZABLE SPECIALIZATIONS
6634 //
6635 //=================================================================================================
6636 
6637 //*************************************************************************************************
6639 template< typename T, bool SO >
6640 struct IsResizable< DynamicMatrix<T,SO> >
6641  : public TrueType
6642 {};
6644 //*************************************************************************************************
6645 
6646 
6647 
6648 
6649 //=================================================================================================
6650 //
6651 // ISSHRINKABLE SPECIALIZATIONS
6652 //
6653 //=================================================================================================
6654 
6655 //*************************************************************************************************
6657 template< typename T, bool SO >
6658 struct IsShrinkable< DynamicMatrix<T,SO> >
6659  : public TrueType
6660 {};
6662 //*************************************************************************************************
6663 
6664 
6665 
6666 
6667 //=================================================================================================
6668 //
6669 // ADDTRAIT SPECIALIZATIONS
6670 //
6671 //=================================================================================================
6672 
6673 //*************************************************************************************************
6675 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6676 struct AddTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
6677 {
6678  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6679 };
6680 
6681 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6682 struct AddTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6683 {
6684  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6685 };
6686 
6687 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6688 struct AddTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6689 {
6690  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
6691 };
6692 
6693 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6694 struct AddTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6695 {
6696  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
6697 };
6698 
6699 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6700 struct AddTrait< DynamicMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6701 {
6702  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6703 };
6704 
6705 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6706 struct AddTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6707 {
6708  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6709 };
6710 
6711 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6712 struct AddTrait< HybridMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6713 {
6714  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6715 };
6716 
6717 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6718 struct AddTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6719 {
6720  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6721 };
6722 
6723 template< typename T1, bool SO, typename T2 >
6724 struct AddTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6725 {
6726  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6727 };
6728 
6729 template< typename T1, bool SO1, typename T2, bool SO2 >
6730 struct AddTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6731 {
6732  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6733 };
6735 //*************************************************************************************************
6736 
6737 
6738 
6739 
6740 //=================================================================================================
6741 //
6742 // SUBTRAIT SPECIALIZATIONS
6743 //
6744 //=================================================================================================
6745 
6746 //*************************************************************************************************
6748 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6749 struct SubTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
6750 {
6751  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6752 };
6753 
6754 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6755 struct SubTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6756 {
6757  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6758 };
6759 
6760 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6761 struct SubTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6762 {
6763  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6764 };
6765 
6766 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6767 struct SubTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6768 {
6769  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6770 };
6771 
6772 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6773 struct SubTrait< DynamicMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6774 {
6775  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6776 };
6777 
6778 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6779 struct SubTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6780 {
6781  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6782 };
6783 
6784 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6785 struct SubTrait< HybridMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6786 {
6787  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6788 };
6789 
6790 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6791 struct SubTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6792 {
6793  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6794 };
6795 
6796 template< typename T1, bool SO, typename T2 >
6797 struct SubTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6798 {
6799  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6800 };
6801 
6802 template< typename T1, bool SO1, typename T2, bool SO2 >
6803 struct SubTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6804 {
6805  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6806 };
6808 //*************************************************************************************************
6809 
6810 
6811 
6812 
6813 //=================================================================================================
6814 //
6815 // SCHURTRAIT SPECIALIZATIONS
6816 //
6817 //=================================================================================================
6818 
6819 //*************************************************************************************************
6821 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6822 struct SchurTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
6823 {
6824  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6825 };
6826 
6827 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6828 struct SchurTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6829 {
6830  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, false >;
6831 };
6832 
6833 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6834 struct SchurTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6835 {
6836  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, SO >;
6837 };
6838 
6839 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6840 struct SchurTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6841 {
6842  using Type = StaticMatrix< MultTrait_<T1,T2>, M, N, false >;
6843 };
6844 
6845 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6846 struct SchurTrait< DynamicMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6847 {
6848  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6849 };
6850 
6851 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6852 struct SchurTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6853 {
6854  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, false >;
6855 };
6856 
6857 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6858 struct SchurTrait< HybridMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6859 {
6860  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6861 };
6862 
6863 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6864 struct SchurTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6865 {
6866  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, false >;
6867 };
6868 
6869 template< typename T1, bool SO, typename T2 >
6870 struct SchurTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6871 {
6872  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6873 };
6874 
6875 template< typename T1, bool SO1, typename T2, bool SO2 >
6876 struct SchurTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6877 {
6878  using Type = DynamicMatrix< MultTrait_<T1,T2>, false >;
6879 };
6881 //*************************************************************************************************
6882 
6883 
6884 
6885 
6886 //=================================================================================================
6887 //
6888 // MULTTRAIT SPECIALIZATIONS
6889 //
6890 //=================================================================================================
6891 
6892 //*************************************************************************************************
6894 template< typename T1, bool SO, typename T2 >
6895 struct MultTrait< DynamicMatrix<T1,SO>, T2, EnableIf_<IsNumeric<T2> > >
6896 {
6897  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6898 };
6899 
6900 template< typename T1, typename T2, bool SO >
6901 struct MultTrait< T1, DynamicMatrix<T2,SO>, EnableIf_<IsNumeric<T1> > >
6902 {
6903  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6904 };
6905 
6906 template< typename T1, bool SO, typename T2, size_t N >
6907 struct MultTrait< DynamicMatrix<T1,SO>, StaticVector<T2,N,false> >
6908 {
6909  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6910 };
6911 
6912 template< typename T1, size_t N, typename T2, bool SO >
6913 struct MultTrait< StaticVector<T1,N,true>, DynamicMatrix<T2,SO> >
6914 {
6915  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6916 };
6917 
6918 template< typename T1, bool SO, typename T2, size_t N >
6919 struct MultTrait< DynamicMatrix<T1,SO>, HybridVector<T2,N,false> >
6920 {
6921  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6922 };
6923 
6924 template< typename T1, size_t N, typename T2, bool SO >
6925 struct MultTrait< HybridVector<T1,N,true>, DynamicMatrix<T2,SO> >
6926 {
6927  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6928 };
6929 
6930 template< typename T1, bool SO, typename T2 >
6931 struct MultTrait< DynamicMatrix<T1,SO>, DynamicVector<T2,false> >
6932 {
6933  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6934 };
6935 
6936 template< typename T1, typename T2, bool SO >
6937 struct MultTrait< DynamicVector<T1,true>, DynamicMatrix<T2,SO> >
6938 {
6939  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6940 };
6941 
6942 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6943 struct MultTrait< DynamicMatrix<T1,SO>, CustomVector<T2,AF,PF,false> >
6944 {
6945  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6946 };
6947 
6948 template< typename T1, bool AF, bool PF, typename T2, bool SO >
6949 struct MultTrait< CustomVector<T1,AF,PF,true>, DynamicMatrix<T2,SO> >
6950 {
6951  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6952 };
6953 
6954 template< typename T1, bool SO, typename T2 >
6955 struct MultTrait< DynamicMatrix<T1,SO>, CompressedVector<T2,false> >
6956 {
6957  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6958 };
6959 
6960 template< typename T1, typename T2, bool SO >
6961 struct MultTrait< CompressedVector<T1,true>, DynamicMatrix<T2,SO> >
6962 {
6963  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6964 };
6965 
6966 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6967 struct MultTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6968 {
6969  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6970 };
6971 
6972 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6973 struct MultTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6974 {
6975  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6976 };
6977 
6978 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6979 struct MultTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6980 {
6981  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6982 };
6983 
6984 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6985 struct MultTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6986 {
6987  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6988 };
6989 
6990 template< typename T1, bool SO1, typename T2, bool SO2 >
6991 struct MultTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6992 {
6993  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6994 };
6996 //*************************************************************************************************
6997 
6998 
6999 
7000 
7001 //=================================================================================================
7002 //
7003 // DIVTRAIT SPECIALIZATIONS
7004 //
7005 //=================================================================================================
7006 
7007 //*************************************************************************************************
7009 template< typename T1, bool SO, typename T2 >
7010 struct DivTrait< DynamicMatrix<T1,SO>, T2, EnableIf_<IsNumeric<T2> > >
7011 {
7012  using Type = DynamicMatrix< DivTrait_<T1,T2>, SO >;
7013 };
7015 //*************************************************************************************************
7016 
7017 
7018 
7019 
7020 //=================================================================================================
7021 //
7022 // UNARYMAPTRAIT SPECIALIZATIONS
7023 //
7024 //=================================================================================================
7025 
7026 //*************************************************************************************************
7028 template< typename T, bool SO, typename OP >
7029 struct UnaryMapTrait< DynamicMatrix<T,SO>, OP >
7030 {
7031  using Type = DynamicMatrix< UnaryMapTrait_<T,OP>, SO >;
7032 };
7034 //*************************************************************************************************
7035 
7036 
7037 
7038 
7039 //=================================================================================================
7040 //
7041 // BINARYMAPTRAIT SPECIALIZATIONS
7042 //
7043 //=================================================================================================
7044 
7045 //*************************************************************************************************
7047 template< typename T1, bool SO, typename T2, size_t M, size_t N, typename OP >
7048 struct BinaryMapTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO>, OP >
7049 {
7050  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
7051 };
7052 
7053 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2, typename OP >
7054 struct BinaryMapTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2>, OP >
7055 {
7056  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
7057 };
7058 
7059 template< typename T1, size_t M, size_t N, bool SO, typename T2, typename OP >
7060 struct BinaryMapTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO>, OP >
7061 {
7062  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
7063 };
7064 
7065 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2, typename OP >
7066 struct BinaryMapTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2>, OP >
7067 {
7068  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
7069 };
7070 
7071 template< typename T1, bool SO, typename T2, size_t M, size_t N, typename OP >
7072 struct BinaryMapTrait< DynamicMatrix<T1,SO>, HybridMatrix<T2,M,N,SO>, OP >
7073 {
7074  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
7075 };
7076 
7077 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2, typename OP >
7078 struct BinaryMapTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2>, OP >
7079 {
7080  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
7081 };
7082 
7083 template< typename T1, size_t M, size_t N, bool SO, typename T2, typename OP >
7084 struct BinaryMapTrait< HybridMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO>, OP >
7085 {
7086  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, SO >;
7087 };
7088 
7089 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2, typename OP >
7090 struct BinaryMapTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2>, OP >
7091 {
7092  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, M, N, false >;
7093 };
7094 
7095 template< typename T1, bool SO, typename T2, typename OP >
7096 struct BinaryMapTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO>, OP >
7097 {
7098  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, SO >;
7099 };
7100 
7101 template< typename T1, bool SO1, typename T2, bool SO2, typename OP >
7102 struct BinaryMapTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2>, OP >
7103 {
7104  using Type = DynamicMatrix< BinaryMapTrait_<T1,T2,OP>, false >;
7105 };
7107 //*************************************************************************************************
7108 
7109 
7110 
7111 
7112 //=================================================================================================
7113 //
7114 // HIGHTYPE SPECIALIZATIONS
7115 //
7116 //=================================================================================================
7117 
7118 //*************************************************************************************************
7120 template< typename T1, bool SO, typename T2 >
7121 struct HighType< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
7122 {
7124 };
7126 //*************************************************************************************************
7127 
7128 
7129 
7130 
7131 //=================================================================================================
7132 //
7133 // LOWTYPE SPECIALIZATIONS
7134 //
7135 //=================================================================================================
7136 
7137 //*************************************************************************************************
7139 template< typename T1, bool SO, typename T2 >
7140 struct LowType< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
7141 {
7143 };
7145 //*************************************************************************************************
7146 
7147 
7148 
7149 
7150 //=================================================================================================
7151 //
7152 // SUBMATRIXTRAIT SPECIALIZATIONS
7153 //
7154 //=================================================================================================
7155 
7156 //*************************************************************************************************
7158 template< typename T, bool SO >
7159 struct SubmatrixTrait< DynamicMatrix<T,SO> >
7160 {
7161  using Type = DynamicMatrix<T,SO>;
7162 };
7164 //*************************************************************************************************
7165 
7166 
7167 
7168 
7169 //=================================================================================================
7170 //
7171 // ROWTRAIT SPECIALIZATIONS
7172 //
7173 //=================================================================================================
7174 
7175 //*************************************************************************************************
7177 template< typename T, bool SO >
7178 struct RowTrait< DynamicMatrix<T,SO> >
7179 {
7180  using Type = DynamicVector<T,true>;
7181 };
7183 //*************************************************************************************************
7184 
7185 
7186 
7187 
7188 //=================================================================================================
7189 //
7190 // COLUMNTRAIT SPECIALIZATIONS
7191 //
7192 //=================================================================================================
7193 
7194 //*************************************************************************************************
7196 template< typename T, bool SO >
7197 struct ColumnTrait< DynamicMatrix<T,SO> >
7198 {
7199  using Type = DynamicVector<T,false>;
7200 };
7202 //*************************************************************************************************
7203 
7204 } // namespace blaze
7205 
7206 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:135
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:513
size_t addPadding(size_t value) const noexcept
Add the necessary amount of padding to the given value.
Definition: DynamicMatrix.h:1953
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
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:2384
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:171
Header file for mathematical functions.
Header file for the Schur product trait.
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: DynamicMatrix.h:2178
void reserve(size_t elements)
Setting the minimum capacity of the matrix.
Definition: DynamicMatrix.h:1878
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:1582
Header file for the UNUSED_PARAMETER function template.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
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:2222
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
Header file for the row trait.
Type *BLAZE_RESTRICT v_
The dynamically allocated matrix elements.
Definition: DynamicMatrix.h:516
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:128
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:2285
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:127
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:164
Header file for the IsSparseMatrix type trait.
DynamicMatrix & operator=(const Type &rhs)
Homogenous assignment to all matrix elements.
Definition: DynamicMatrix.h:1201
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: DynamicMatrix.h:1802
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:265
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:554
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:1411
Header file for the IsSame and IsStrictlySame type traits.
Base template for the SchurTrait class.
Definition: SchurTrait.h:124
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:2319
Availability of a SIMD multiplication for the given data types.Depending on the available instruction...
Definition: HasSIMDMult.h:172
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:316
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
Type ElementType
Type of the matrix elements.
Definition: DynamicMatrix.h:222
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1762
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:171
#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:1177
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:140
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
Type & Reference
Reference to a non-constant matrix value.
Definition: DynamicMatrix.h:227
Efficient implementation of an arbitrary sized vector.The DynamicVector class template is the represe...
Definition: DynamicVector.h:183
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:212
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:1393
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:343
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1809
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:133
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:2419
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:78
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: DynamicMatrix.h:2197
Constraint on the data type.
~DynamicMatrix()
The destructor for DynamicMatrix.
Definition: DynamicMatrix.h:858
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:155
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DynamicMatrix.h:1615
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: DynamicMatrix.h:223
Base template for the RowTrait class.
Definition: RowTrait.h:127
Headerfile for the generic max algorithm.
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:112
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.
Header file for the unary map trait.
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:112
DynamicMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: DynamicMatrix.h:2015
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
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1359
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:5924
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: DynamicMatrix.h:1914
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: DynamicMatrix.h:2160
Header file for the IsShrinkable type trait.
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:102
#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
Type * Pointer
Pointer to a non-constant matrix value.
Definition: DynamicMatrix.h:229
Header file for the HasSIMDAdd type trait.
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
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:1860
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:1715
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:1596
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:580
Header file for the IsPadded type trait.
const Type & ConstReference
Reference to a constant matrix value.
Definition: DynamicMatrix.h:228
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:2348
Header file for the IsVectorizable type trait.
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: DynamicMatrix.h:986
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: DynamicMatrix.h:886
Compile time check for shrinkable data types.This type trait tests whether the given data type is a s...
Definition: IsShrinkable.h:75
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:514
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
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
Header file for the HasSIMDMult type trait.
Header file for the binary map trait.
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:1357
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:139
Base template for the MultTrait class.
Definition: MultTrait.h:139
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: DynamicMatrix.h:1067
Header file for the addition trait.
void clear()
Clearing the matrix.
Definition: DynamicMatrix.h:1759
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:1111
Constraint on the data type.
Headerfile for the generic transfer algorithm.
size_t m_
The current number of rows of the matrix.
Definition: DynamicMatrix.h:512
Header file for the reset shim.
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:2140
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:101
Constraint on the data type.
void swap(DynamicMatrix &m) noexcept
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:1931
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.
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: DynamicMatrix.h:232
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: DynamicMatrix.h:1665
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
Base template for the DivTrait class.
Definition: DivTrait.h:139
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
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
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:790
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:2250
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: DynamicMatrix.h:1133
DynamicMatrix< Type, SO > This
Type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:217
Initializer list type of the Blaze library.
bool isIntact() const noexcept
Returns whether the invariants of the dynamic matrix are intact.
Definition: DynamicMatrix.h:2100
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:123
size_t capacity_
The maximum capacity of the matrix.
Definition: DynamicMatrix.h:515
Header file for the IntegralConstant class template.
Resize mechanism to obtain a DynamicMatrix with different fixed dimensions.
Definition: DynamicMatrix.h:250
Compile time evaluation of the number of rows of a matrix.The Rows type trait evaluates the number of...
Definition: Rows.h:75
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
Rebind mechanism to obtain a DynamicMatrix with different data/element type.
Definition: DynamicMatrix.h:240
DenseIterator< const Type, usePadding > ConstIterator
Iterator over constant elements.
Definition: DynamicMatrix.h:233
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
Base template for the SubTrait class.
Definition: SubTrait.h:139
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:1375
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:1629
Header file for the CTransExprTrait class template.
OutputIterator transfer(InputIterator first, InputIterator last, OutputIterator dest)
Transfers the elements from the given source range to the destination range.
Definition: Transfer.h:70
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: DynamicMatrix.h:931
Base template for the BinaryMapTrait class.
Definition: BinaryMapTrait.h:119
Header file for the IsResizable type trait.
Base template for the UnaryMapTrait class.
Definition: UnaryMapTrait.h:117
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
const Type & ReturnType
Return type for expression template evaluations.
Definition: DynamicMatrix.h:224
DynamicMatrix & transpose()
In-place transpose of the matrix.
Definition: DynamicMatrix.h:1977
Header file for the HighType type trait.
Header file for the TrueType type/value trait base class.
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: DynamicMatrix.h:230