DynamicMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_DENSE_DYNAMICMATRIX_H_
36 #define _BLAZE_MATH_DENSE_DYNAMICMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <utility>
45 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
53 #include <blaze/math/Forward.h>
54 #include <blaze/math/Functions.h>
56 #include <blaze/math/shims/Clear.h>
59 #include <blaze/math/SIMD.h>
86 #include <blaze/system/Blocking.h>
87 #include <blaze/system/CacheSize.h>
88 #include <blaze/system/Inline.h>
90 #include <blaze/system/Restrict.h>
93 #include <blaze/util/Algorithm.h>
95 #include <blaze/util/Assert.h>
101 #include <blaze/util/DisableIf.h>
102 #include <blaze/util/EnableIf.h>
104 #include <blaze/util/Memory.h>
105 #include <blaze/util/Template.h>
106 #include <blaze/util/TrueType.h>
107 #include <blaze/util/Types.h>
111 #include <blaze/util/Unused.h>
112 
113 
114 namespace blaze {
115 
116 //=================================================================================================
117 //
118 // CLASS DEFINITION
119 //
120 //=================================================================================================
121 
122 //*************************************************************************************************
201 template< typename Type // Data type of the matrix
202  , bool SO = defaultStorageOrder > // Storage order
203 class DynamicMatrix : public DenseMatrix< DynamicMatrix<Type,SO>, SO >
204 {
205  public:
206  //**Type definitions****************************************************************************
209  typedef This ResultType;
212  typedef Type ElementType;
214  typedef const Type& ReturnType;
215  typedef const This& CompositeType;
216 
217  typedef Type& Reference;
218  typedef const Type& ConstReference;
219  typedef Type* Pointer;
220  typedef const Type* ConstPointer;
221 
224  //**********************************************************************************************
225 
226  //**Rebind struct definition********************************************************************
229  template< typename ET > // Data type of the other matrix
230  struct Rebind {
232  };
233  //**********************************************************************************************
234 
235  //**Compilation flags***************************************************************************
237 
241  enum : bool { simdEnabled = IsVectorizable<Type>::value };
242 
244 
247  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
248  //**********************************************************************************************
249 
250  //**Constructors********************************************************************************
253  explicit inline DynamicMatrix() noexcept;
254  explicit inline DynamicMatrix( size_t m, size_t n );
255  explicit inline DynamicMatrix( size_t m, size_t n, const Type& init );
256  explicit inline DynamicMatrix( initializer_list< initializer_list<Type> > list );
257 
258  template< typename Other >
259  explicit inline DynamicMatrix( size_t m, size_t n, const Other* array );
260 
261  template< typename Other, size_t M, size_t N >
262  explicit inline DynamicMatrix( const Other (&array)[M][N] );
263 
264  inline DynamicMatrix( const DynamicMatrix& m );
265  inline DynamicMatrix( DynamicMatrix&& m ) noexcept;
266  template< typename MT, bool SO2 > inline DynamicMatrix( const Matrix<MT,SO2>& m );
268  //**********************************************************************************************
269 
270  //**Destructor**********************************************************************************
273  inline ~DynamicMatrix();
275  //**********************************************************************************************
276 
277  //**Data access functions***********************************************************************
280  inline Reference operator()( size_t i, size_t j ) noexcept;
281  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
282  inline Reference at( size_t i, size_t j );
283  inline ConstReference at( size_t i, size_t j ) const;
284  inline Pointer data () noexcept;
285  inline ConstPointer data () const noexcept;
286  inline Pointer data ( size_t i ) noexcept;
287  inline ConstPointer data ( size_t i ) const noexcept;
288  inline Iterator begin ( size_t i ) noexcept;
289  inline ConstIterator begin ( size_t i ) const noexcept;
290  inline ConstIterator cbegin( size_t i ) const noexcept;
291  inline Iterator end ( size_t i ) noexcept;
292  inline ConstIterator end ( size_t i ) const noexcept;
293  inline ConstIterator cend ( size_t i ) const noexcept;
295  //**********************************************************************************************
296 
297  //**Assignment operators************************************************************************
300  inline DynamicMatrix& operator=( const Type& rhs );
301  inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list );
302 
303  template< typename Other, size_t M, size_t N >
304  inline DynamicMatrix& operator=( const Other (&array)[M][N] );
305 
306  inline DynamicMatrix& operator=( const DynamicMatrix& rhs );
307  inline DynamicMatrix& operator=( DynamicMatrix&& rhs ) noexcept;
308 
309  template< typename MT, bool SO2 > inline DynamicMatrix& operator= ( const Matrix<MT,SO2>& rhs );
310  template< typename MT, bool SO2 > inline DynamicMatrix& operator+=( const Matrix<MT,SO2>& rhs );
311  template< typename MT, bool SO2 > inline DynamicMatrix& operator-=( const Matrix<MT,SO2>& rhs );
312  template< typename MT, bool SO2 > inline DynamicMatrix& operator*=( const Matrix<MT,SO2>& rhs );
313 
314  template< typename Other >
315  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator*=( Other rhs );
316 
317  template< typename Other >
318  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator/=( Other rhs );
320  //**********************************************************************************************
321 
322  //**Utility functions***************************************************************************
325  inline size_t rows() const noexcept;
326  inline size_t columns() const noexcept;
327  inline size_t spacing() const noexcept;
328  inline size_t capacity() const noexcept;
329  inline size_t capacity( size_t i ) const noexcept;
330  inline size_t nonZeros() const;
331  inline size_t nonZeros( size_t i ) const;
332  inline void reset();
333  inline void reset( size_t i );
334  inline void clear();
335  void resize ( size_t m, size_t n, bool preserve=true );
336  inline void extend ( size_t m, size_t n, bool preserve=true );
337  inline void reserve( size_t elements );
338  inline DynamicMatrix& transpose();
339  inline DynamicMatrix& ctranspose();
340  template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
341  inline void swap( DynamicMatrix& m ) noexcept;
343  //**********************************************************************************************
344 
345  private:
346  //**********************************************************************************************
348  template< typename MT >
350  struct VectorizedAssign {
351  enum : bool { value = useOptimizedKernels &&
352  simdEnabled && MT::simdEnabled &&
353  AreSIMDCombinable< Type, ElementType_<MT> >::value };
354  };
356  //**********************************************************************************************
357 
358  //**********************************************************************************************
360  template< typename MT >
362  struct VectorizedAddAssign {
363  enum : bool { value = useOptimizedKernels &&
364  simdEnabled && MT::simdEnabled &&
365  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
366  HasSIMDAdd< Type, ElementType_<MT> >::value &&
367  !IsDiagonal<MT>::value };
368  };
370  //**********************************************************************************************
371 
372  //**********************************************************************************************
374  template< typename MT >
376  struct VectorizedSubAssign {
377  enum : bool { value = useOptimizedKernels &&
378  simdEnabled && MT::simdEnabled &&
379  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
380  HasSIMDSub< Type, ElementType_<MT> >::value &&
381  !IsDiagonal<MT>::value };
382  };
384  //**********************************************************************************************
385 
386  //**********************************************************************************************
388  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
389  //**********************************************************************************************
390 
391  public:
392  //**Debugging functions*************************************************************************
395  inline bool isIntact() const noexcept;
397  //**********************************************************************************************
398 
399  //**Expression template evaluation functions****************************************************
402  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
403  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
404 
405  inline bool isAligned () const noexcept;
406  inline bool canSMPAssign() const noexcept;
407 
408  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
409  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
410  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
411 
412  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
413  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
414  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
415  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
416 
417  template< typename MT >
418  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
419 
420  template< typename MT >
421  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
422 
423  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
424  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
425  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
426 
427  template< typename MT >
428  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
429 
430  template< typename MT >
431  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
432 
433  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
434  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
435  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
436 
437  template< typename MT >
438  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
439 
440  template< typename MT >
441  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
442 
443  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
444  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
445  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
447  //**********************************************************************************************
448 
449  private:
450  //**Utility functions***************************************************************************
453  inline size_t adjustColumns( size_t minColumns ) const noexcept;
455  //**********************************************************************************************
456 
457  //**Member variables****************************************************************************
460  size_t m_;
461  size_t n_;
462  size_t nn_;
463  size_t capacity_;
465 
475  //**********************************************************************************************
476 
477  //**Compile time checks*************************************************************************
484  //**********************************************************************************************
485 };
486 //*************************************************************************************************
487 
488 
489 
490 
491 //=================================================================================================
492 //
493 // CONSTRUCTORS
494 //
495 //=================================================================================================
496 
497 //*************************************************************************************************
500 template< typename Type // Data type of the matrix
501  , bool SO > // Storage order
502 inline DynamicMatrix<Type,SO>::DynamicMatrix() noexcept
503  : m_ ( 0UL ) // The current number of rows of the matrix
504  , n_ ( 0UL ) // The current number of columns of the matrix
505  , nn_ ( 0UL ) // The alignment adjusted number of columns
506  , capacity_( 0UL ) // The maximum capacity of the matrix
507  , v_ ( nullptr ) // The matrix elements
508 {}
509 //*************************************************************************************************
510 
511 
512 //*************************************************************************************************
521 template< typename Type // Data type of the matrix
522  , bool SO > // Storage order
523 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n )
524  : m_ ( m ) // The current number of rows of the matrix
525  , n_ ( n ) // The current number of columns of the matrix
526  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
527  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
528  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
529 {
531  for( size_t i=0UL; i<m_; ++i ) {
532  for( size_t j=n_; j<nn_; ++j ) {
533  v_[i*nn_+j] = Type();
534  }
535  }
536  }
537 
538  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
539 }
540 //*************************************************************************************************
541 
542 
543 //*************************************************************************************************
552 template< typename Type // Data type of the matrix
553  , bool SO > // Storage order
554 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, const Type& init )
555  : m_ ( m ) // The current number of rows of the matrix
556  , n_ ( n ) // The current number of columns of the matrix
557  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
558  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
559  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
560 {
561  for( size_t i=0UL; i<m; ++i ) {
562  for( size_t j=0UL; j<n_; ++j )
563  v_[i*nn_+j] = init;
564 
566  for( size_t j=n_; j<nn_; ++j )
567  v_[i*nn_+j] = Type();
568  }
569  }
570 
571  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
572 }
573 //*************************************************************************************************
574 
575 
576 //*************************************************************************************************
596 template< typename Type // Data type of the matrix
597  , bool SO > // Storage order
599  : m_ ( list.size() ) // The current number of rows of the matrix
600  , n_ ( determineColumns( list ) ) // The current number of columns of the matrix
601  , nn_ ( adjustColumns( n_ ) ) // The alignment adjusted number of columns
602  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
603  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
604 {
605  size_t i( 0UL );
606 
607  for( const auto& rowList : list ) {
608  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ), v_+(i+1UL)*nn_, Type() );
609  ++i;
610  }
611 
612  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
613 }
614 //*************************************************************************************************
615 
616 
617 //*************************************************************************************************
640 template< typename Type // Data type of the matrix
641  , bool SO > // Storage order
642 template< typename Other > // Data type of the initialization array
643 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, const Other* array )
644  : m_ ( m ) // The current number of rows of the matrix
645  , n_ ( n ) // The current number of columns of the matrix
646  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
647  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
648  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
649 {
650  for( size_t i=0UL; i<m; ++i ) {
651  for( size_t j=0UL; j<n; ++j )
652  v_[i*nn_+j] = array[i*n+j];
653 
655  for( size_t j=n; j<nn_; ++j )
656  v_[i*nn_+j] = Type();
657  }
658  }
659 
660  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
661 }
662 //*************************************************************************************************
663 
664 
665 //*************************************************************************************************
686 template< typename Type // Data type of the matrix
687  , bool SO > // Storage order
688 template< typename Other // Data type of the initialization array
689  , size_t M // Number of rows of the initialization array
690  , size_t N > // Number of columns of the initialization array
691 inline DynamicMatrix<Type,SO>::DynamicMatrix( const Other (&array)[M][N] )
692  : m_ ( M ) // The current number of rows of the matrix
693  , n_ ( N ) // The current number of columns of the matrix
694  , nn_ ( adjustColumns( N ) ) // The alignment adjusted number of columns
695  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
696  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
697 {
698  for( size_t i=0UL; i<M; ++i ) {
699  for( size_t j=0UL; j<N; ++j )
700  v_[i*nn_+j] = array[i][j];
701 
703  for( size_t j=N; j<nn_; ++j )
704  v_[i*nn_+j] = Type();
705  }
706  }
707 
708  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
709 }
710 //*************************************************************************************************
711 
712 
713 //*************************************************************************************************
721 template< typename Type // Data type of the matrix
722  , bool SO > // Storage order
724  : m_ ( m.m_ ) // The current number of rows of the matrix
725  , n_ ( m.n_ ) // The current number of columns of the matrix
726  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
727  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
728  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
729 {
730  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
731 
732  for( size_t i=0UL; i<capacity_; ++i )
733  v_[i] = m.v_[i];
734 
735  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
736 }
737 //*************************************************************************************************
738 
739 
740 //*************************************************************************************************
745 template< typename Type // Data type of the matrix
746  , bool SO > // Storage order
748  : m_ ( m.m_ ) // The current number of rows of the matrix
749  , n_ ( m.n_ ) // The current number of columns of the matrix
750  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
751  , capacity_( m.capacity_ ) // The maximum capacity of the matrix
752  , v_ ( m.v_ ) // The matrix elements
753 {
754  m.m_ = 0UL;
755  m.n_ = 0UL;
756  m.nn_ = 0UL;
757  m.capacity_ = 0UL;
758  m.v_ = nullptr;
759 }
760 //*************************************************************************************************
761 
762 
763 //*************************************************************************************************
768 template< typename Type // Data type of the matrix
769  , bool SO > // Storage order
770 template< typename MT // Type of the foreign matrix
771  , bool SO2 > // Storage order of the foreign matrix
773  : m_ ( (~m).rows() ) // The current number of rows of the matrix
774  , n_ ( (~m).columns() ) // The current number of columns of the matrix
775  , nn_ ( adjustColumns( n_ ) ) // The alignment adjusted number of columns
776  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
777  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
778 {
779  for( size_t i=0UL; i<m_; ++i ) {
780  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : n_ );
781  j<( IsVectorizable<Type>::value ? nn_ : n_ ); ++j ) {
782  v_[i*nn_+j] = Type();
783  }
784  }
785 
786  smpAssign( *this, ~m );
787 
788  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
789 }
790 //*************************************************************************************************
791 
792 
793 
794 
795 //=================================================================================================
796 //
797 // DESTRUCTOR
798 //
799 //=================================================================================================
800 
801 //*************************************************************************************************
804 template< typename Type // Data type of the matrix
805  , bool SO > // Storage order
807 {
808  deallocate( v_ );
809 }
810 //*************************************************************************************************
811 
812 
813 
814 
815 //=================================================================================================
816 //
817 // DATA ACCESS FUNCTIONS
818 //
819 //=================================================================================================
820 
821 //*************************************************************************************************
831 template< typename Type // Data type of the matrix
832  , bool SO > // Storage order
833 inline typename DynamicMatrix<Type,SO>::Reference
834  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) noexcept
835 {
836  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
837  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
838  return v_[i*nn_+j];
839 }
840 //*************************************************************************************************
841 
842 
843 //*************************************************************************************************
853 template< typename Type // Data type of the matrix
854  , bool SO > // Storage order
856  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) const noexcept
857 {
858  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
859  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
860  return v_[i*nn_+j];
861 }
862 //*************************************************************************************************
863 
864 
865 //*************************************************************************************************
876 template< typename Type // Data type of the matrix
877  , bool SO > // Storage order
878 inline typename DynamicMatrix<Type,SO>::Reference
879  DynamicMatrix<Type,SO>::at( size_t i, size_t j )
880 {
881  if( i >= m_ ) {
882  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
883  }
884  if( j >= n_ ) {
885  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
886  }
887  return (*this)(i,j);
888 }
889 //*************************************************************************************************
890 
891 
892 //*************************************************************************************************
903 template< typename Type // Data type of the matrix
904  , bool SO > // Storage order
906  DynamicMatrix<Type,SO>::at( size_t i, size_t j ) const
907 {
908  if( i >= m_ ) {
909  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
910  }
911  if( j >= n_ ) {
912  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
913  }
914  return (*this)(i,j);
915 }
916 //*************************************************************************************************
917 
918 
919 //*************************************************************************************************
931 template< typename Type // Data type of the matrix
932  , bool SO > // Storage order
933 inline typename DynamicMatrix<Type,SO>::Pointer
935 {
936  return v_;
937 }
938 //*************************************************************************************************
939 
940 
941 //*************************************************************************************************
953 template< typename Type // Data type of the matrix
954  , bool SO > // Storage order
957 {
958  return v_;
959 }
960 //*************************************************************************************************
961 
962 
963 //*************************************************************************************************
971 template< typename Type // Data type of the matrix
972  , bool SO > // Storage order
973 inline typename DynamicMatrix<Type,SO>::Pointer
974  DynamicMatrix<Type,SO>::data( size_t i ) noexcept
975 {
976  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
977  return v_ + i*nn_;
978 }
979 //*************************************************************************************************
980 
981 
982 //*************************************************************************************************
990 template< typename Type // Data type of the matrix
991  , bool SO > // Storage order
993  DynamicMatrix<Type,SO>::data( size_t i ) const noexcept
994 {
995  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
996  return v_ + i*nn_;
997 }
998 //*************************************************************************************************
999 
1000 
1001 //*************************************************************************************************
1012 template< typename Type // Data type of the matrix
1013  , bool SO > // Storage order
1014 inline typename DynamicMatrix<Type,SO>::Iterator
1015  DynamicMatrix<Type,SO>::begin( size_t i ) noexcept
1016 {
1017  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1018  return Iterator( v_ + i*nn_ );
1019 }
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1034 template< typename Type // Data type of the matrix
1035  , bool SO > // Storage order
1037  DynamicMatrix<Type,SO>::begin( size_t i ) const noexcept
1038 {
1039  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1040  return ConstIterator( v_ + i*nn_ );
1041 }
1042 //*************************************************************************************************
1043 
1044 
1045 //*************************************************************************************************
1056 template< typename Type // Data type of the matrix
1057  , bool SO > // Storage order
1059  DynamicMatrix<Type,SO>::cbegin( size_t i ) const noexcept
1060 {
1061  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1062  return ConstIterator( v_ + i*nn_ );
1063 }
1064 //*************************************************************************************************
1065 
1066 
1067 //*************************************************************************************************
1078 template< typename Type // Data type of the matrix
1079  , bool SO > // Storage order
1080 inline typename DynamicMatrix<Type,SO>::Iterator
1081  DynamicMatrix<Type,SO>::end( size_t i ) noexcept
1082 {
1083  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1084  return Iterator( v_ + i*nn_ + n_ );
1085 }
1086 //*************************************************************************************************
1087 
1088 
1089 //*************************************************************************************************
1100 template< typename Type // Data type of the matrix
1101  , bool SO > // Storage order
1103  DynamicMatrix<Type,SO>::end( size_t i ) const noexcept
1104 {
1105  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1106  return ConstIterator( v_ + i*nn_ + n_ );
1107 }
1108 //*************************************************************************************************
1109 
1110 
1111 //*************************************************************************************************
1122 template< typename Type // Data type of the matrix
1123  , bool SO > // Storage order
1125  DynamicMatrix<Type,SO>::cend( size_t i ) const noexcept
1126 {
1127  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1128  return ConstIterator( v_ + i*nn_ + n_ );
1129 }
1130 //*************************************************************************************************
1131 
1132 
1133 
1134 
1135 //=================================================================================================
1136 //
1137 // ASSIGNMENT OPERATORS
1138 //
1139 //=================================================================================================
1140 
1141 //*************************************************************************************************
1147 template< typename Type // Data type of the matrix
1148  , bool SO > // Storage order
1150 {
1151  for( size_t i=0UL; i<m_; ++i )
1152  for( size_t j=0UL; j<n_; ++j )
1153  v_[i*nn_+j] = rhs;
1154 
1155  return *this;
1156 }
1157 //*************************************************************************************************
1158 
1159 
1160 //*************************************************************************************************
1181 template< typename Type // Data type of the matrix
1182  , bool SO > // Storage order
1183 inline DynamicMatrix<Type,SO>&
1185 {
1186  resize( list.size(), determineColumns( list ), false );
1187 
1188  size_t i( 0UL );
1189 
1190  for( const auto& rowList : list ) {
1191  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ), v_+(i+1UL)*nn_, Type() );
1192  ++i;
1193  }
1194 
1195  return *this;
1196 }
1197 //*************************************************************************************************
1198 
1199 
1200 //*************************************************************************************************
1221 template< typename Type // Data type of the matrix
1222  , bool SO > // Storage order
1223 template< typename Other // Data type of the initialization array
1224  , size_t M // Number of rows of the initialization array
1225  , size_t N > // Number of columns of the initialization array
1226 inline DynamicMatrix<Type,SO>& DynamicMatrix<Type,SO>::operator=( const Other (&array)[M][N] )
1227 {
1228  resize( M, N, false );
1229 
1230  for( size_t i=0UL; i<M; ++i )
1231  for( size_t j=0UL; j<N; ++j )
1232  v_[i*nn_+j] = array[i][j];
1233 
1234  return *this;
1235 }
1236 //*************************************************************************************************
1237 
1238 
1239 //*************************************************************************************************
1248 template< typename Type // Data type of the matrix
1249  , bool SO > // Storage order
1251 {
1252  if( &rhs == this ) return *this;
1253 
1254  resize( rhs.m_, rhs.n_, false );
1255  smpAssign( *this, ~rhs );
1256 
1257  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1258 
1259  return *this;
1260 }
1261 //*************************************************************************************************
1262 
1263 
1264 //*************************************************************************************************
1270 template< typename Type // Data type of the matrix
1271  , bool SO > // Storage order
1273 {
1274  deallocate( v_ );
1275 
1276  m_ = rhs.m_;
1277  n_ = rhs.n_;
1278  nn_ = rhs.nn_;
1279  capacity_ = rhs.capacity_;
1280  v_ = rhs.v_;
1281 
1282  rhs.m_ = 0UL;
1283  rhs.n_ = 0UL;
1284  rhs.nn_ = 0UL;
1285  rhs.capacity_ = 0UL;
1286  rhs.v_ = nullptr;
1287 
1288  return *this;
1289 }
1290 //*************************************************************************************************
1291 
1292 
1293 //*************************************************************************************************
1302 template< typename Type // Data type of the matrix
1303  , bool SO > // Storage order
1304 template< typename MT // Type of the right-hand side matrix
1305  , bool SO2 > // Storage order of the right-hand side matrix
1307 {
1308  typedef TransExprTrait_<This> TT;
1309  typedef CTransExprTrait_<This> CT;
1310  typedef InvExprTrait_<This> IT;
1311 
1312  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1313  transpose();
1314  }
1315  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1316  ctranspose();
1317  }
1318  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1319  DynamicMatrix tmp( ~rhs );
1320  swap( tmp );
1321  }
1322  else {
1323  resize( (~rhs).rows(), (~rhs).columns(), false );
1325  reset();
1326  smpAssign( *this, ~rhs );
1327  }
1328 
1329  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1330 
1331  return *this;
1332 }
1333 //*************************************************************************************************
1334 
1335 
1336 //*************************************************************************************************
1346 template< typename Type // Data type of the matrix
1347  , bool SO > // Storage order
1348 template< typename MT // Type of the right-hand side matrix
1349  , bool SO2 > // Storage order of the right-hand side matrix
1351 {
1352  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1353  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1354  }
1355 
1356  if( (~rhs).canAlias( this ) ) {
1357  const ResultType_<MT> tmp( ~rhs );
1358  smpAddAssign( *this, tmp );
1359  }
1360  else {
1361  smpAddAssign( *this, ~rhs );
1362  }
1363 
1364  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1365 
1366  return *this;
1367 }
1368 //*************************************************************************************************
1369 
1370 
1371 //*************************************************************************************************
1381 template< typename Type // Data type of the matrix
1382  , bool SO > // Storage order
1383 template< typename MT // Type of the right-hand side matrix
1384  , bool SO2 > // Storage order of the right-hand side matrix
1386 {
1387  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1388  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1389  }
1390 
1391  if( (~rhs).canAlias( this ) ) {
1392  const ResultType_<MT> tmp( ~rhs );
1393  smpSubAssign( *this, tmp );
1394  }
1395  else {
1396  smpSubAssign( *this, ~rhs );
1397  }
1398 
1399  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1400 
1401  return *this;
1402 }
1403 //*************************************************************************************************
1404 
1405 
1406 //*************************************************************************************************
1416 template< typename Type // Data type of the matrix
1417  , bool SO > // Storage order
1418 template< typename MT // Type of the right-hand side matrix
1419  , bool SO2 > // Storage order of the right-hand side matrix
1421 {
1422  if( (~rhs).rows() != n_ ) {
1423  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1424  }
1425 
1426  DynamicMatrix tmp( *this * (~rhs) );
1427  swap( tmp );
1428 
1429  return *this;
1430 }
1431 //*************************************************************************************************
1432 
1433 
1434 //*************************************************************************************************
1441 template< typename Type // Data type of the matrix
1442  , bool SO > // Storage order
1443 template< typename Other > // Data type of the right-hand side scalar
1446 {
1447  smpAssign( *this, (*this) * rhs );
1448 
1449  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1450 
1451  return *this;
1452 }
1453 //*************************************************************************************************
1454 
1455 
1456 //*************************************************************************************************
1463 template< typename Type // Data type of the matrix
1464  , bool SO > // Storage order
1465 template< typename Other > // Data type of the right-hand side scalar
1466 inline EnableIf_<IsNumeric<Other>, DynamicMatrix<Type,SO> >&
1468 {
1469  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1470 
1471  smpAssign( *this, (*this) / rhs );
1472 
1473  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1474 
1475  return *this;
1476 }
1477 //*************************************************************************************************
1478 
1479 
1480 
1481 
1482 //=================================================================================================
1483 //
1484 // UTILITY FUNCTIONS
1485 //
1486 //=================================================================================================
1487 
1488 //*************************************************************************************************
1493 template< typename Type // Data type of the matrix
1494  , bool SO > // Storage order
1495 inline size_t DynamicMatrix<Type,SO>::rows() const noexcept
1496 {
1497  return m_;
1498 }
1499 //*************************************************************************************************
1500 
1501 
1502 //*************************************************************************************************
1507 template< typename Type // Data type of the matrix
1508  , bool SO > // Storage order
1509 inline size_t DynamicMatrix<Type,SO>::columns() const noexcept
1510 {
1511  return n_;
1512 }
1513 //*************************************************************************************************
1514 
1515 
1516 //*************************************************************************************************
1526 template< typename Type // Data type of the matrix
1527  , bool SO > // Storage order
1528 inline size_t DynamicMatrix<Type,SO>::spacing() const noexcept
1529 {
1530  return nn_;
1531 }
1532 //*************************************************************************************************
1533 
1534 
1535 //*************************************************************************************************
1540 template< typename Type // Data type of the matrix
1541  , bool SO > // Storage order
1542 inline size_t DynamicMatrix<Type,SO>::capacity() const noexcept
1543 {
1544  return capacity_;
1545 }
1546 //*************************************************************************************************
1547 
1548 
1549 //*************************************************************************************************
1560 template< typename Type // Data type of the matrix
1561  , bool SO > // Storage order
1562 inline size_t DynamicMatrix<Type,SO>::capacity( size_t i ) const noexcept
1563 {
1564  UNUSED_PARAMETER( i );
1565  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1566  return nn_;
1567 }
1568 //*************************************************************************************************
1569 
1570 
1571 //*************************************************************************************************
1576 template< typename Type // Data type of the matrix
1577  , bool SO > // Storage order
1579 {
1580  size_t nonzeros( 0UL );
1581 
1582  for( size_t i=0UL; i<m_; ++i )
1583  for( size_t j=0UL; j<n_; ++j )
1584  if( !isDefault( v_[i*nn_+j] ) )
1585  ++nonzeros;
1586 
1587  return nonzeros;
1588 }
1589 //*************************************************************************************************
1590 
1591 
1592 //*************************************************************************************************
1603 template< typename Type // Data type of the matrix
1604  , bool SO > // Storage order
1605 inline size_t DynamicMatrix<Type,SO>::nonZeros( size_t i ) const
1606 {
1607  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1608 
1609  const size_t jend( i*nn_ + n_ );
1610  size_t nonzeros( 0UL );
1611 
1612  for( size_t j=i*nn_; j<jend; ++j )
1613  if( !isDefault( v_[j] ) )
1614  ++nonzeros;
1615 
1616  return nonzeros;
1617 }
1618 //*************************************************************************************************
1619 
1620 
1621 //*************************************************************************************************
1626 template< typename Type // Data type of the matrix
1627  , bool SO > // Storage order
1629 {
1630  using blaze::clear;
1631 
1632  for( size_t i=0UL; i<m_; ++i )
1633  for( size_t j=0UL; j<n_; ++j )
1634  clear( v_[i*nn_+j] );
1635 }
1636 //*************************************************************************************************
1637 
1638 
1639 //*************************************************************************************************
1650 template< typename Type // Data type of the matrix
1651  , bool SO > // Storage order
1652 inline void DynamicMatrix<Type,SO>::reset( size_t i )
1653 {
1654  using blaze::clear;
1655 
1656  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1657  for( size_t j=0UL; j<n_; ++j )
1658  clear( v_[i*nn_+j] );
1659 }
1660 //*************************************************************************************************
1661 
1662 
1663 //*************************************************************************************************
1670 template< typename Type // Data type of the matrix
1671  , bool SO > // Storage order
1673 {
1674  resize( 0UL, 0UL, false );
1675 }
1676 //*************************************************************************************************
1677 
1678 
1679 //*************************************************************************************************
1713 template< typename Type // Data type of the matrix
1714  , bool SO > // Storage order
1715 void DynamicMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1716 {
1717  using blaze::min;
1718 
1719  if( m == m_ && n == n_ ) return;
1720 
1721  const size_t nn( adjustColumns( n ) );
1722 
1723  if( preserve )
1724  {
1725  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1726  const size_t min_m( min( m, m_ ) );
1727  const size_t min_n( min( n, n_ ) );
1728 
1729  for( size_t i=0UL; i<min_m; ++i ) {
1730  transfer( v_+i*nn_, v_+i*nn_+min_n, v+i*nn );
1731  }
1732 
1733  std::swap( v_, v );
1734  deallocate( v );
1735  capacity_ = m*nn;
1736  }
1737  else if( m*nn > capacity_ ) {
1738  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1739  std::swap( v_, v );
1740  deallocate( v );
1741  capacity_ = m*nn;
1742  }
1743 
1745  for( size_t i=0UL; i<m; ++i )
1746  for( size_t j=n; j<nn; ++j )
1747  v_[i*nn+j] = Type();
1748  }
1749 
1750  m_ = m;
1751  n_ = n;
1752  nn_ = nn;
1753 }
1754 //*************************************************************************************************
1755 
1756 
1757 //*************************************************************************************************
1771 template< typename Type // Data type of the matrix
1772  , bool SO > // Storage order
1773 inline void DynamicMatrix<Type,SO>::extend( size_t m, size_t n, bool preserve )
1774 {
1775  resize( m_+m, n_+n, preserve );
1776 }
1777 //*************************************************************************************************
1778 
1779 
1780 //*************************************************************************************************
1789 template< typename Type // Data type of the matrix
1790  , bool SO > // Storage order
1791 inline void DynamicMatrix<Type,SO>::reserve( size_t elements )
1792 {
1793  if( elements > capacity_ )
1794  {
1795  // Allocating a new array
1796  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
1797 
1798  // Initializing the new array
1799  transfer( v_, v_+capacity_, tmp );
1800 
1802  for( size_t i=capacity_; i<elements; ++i )
1803  tmp[i] = Type();
1804  }
1805 
1806  // Replacing the old array
1807  std::swap( tmp, v_ );
1808  deallocate( tmp );
1809  capacity_ = elements;
1810  }
1811 }
1812 //*************************************************************************************************
1813 
1814 
1815 //*************************************************************************************************
1820 template< typename Type // Data type of the matrix
1821  , bool SO > // Storage order
1823 {
1824  using std::swap;
1825 
1826  const size_t block( BLOCK_SIZE );
1827 
1828  if( m_ == n_ )
1829  {
1830  for( size_t ii=0UL; ii<m_; ii+=block ) {
1831  const size_t iend( min( ii+block, m_ ) );
1832  for( size_t jj=0UL; jj<=ii; jj+=block ) {
1833  for( size_t i=ii; i<iend; ++i ) {
1834  const size_t jend( min( jj+block, n_, i ) );
1835  for( size_t j=jj; j<jend; ++j ) {
1836  swap( v_[i*nn_+j], v_[j*nn_+i] );
1837  }
1838  }
1839  }
1840  }
1841  }
1842  else
1843  {
1844  DynamicMatrix tmp( trans(*this) );
1845  this->swap( tmp );
1846  }
1847 
1848  return *this;
1849 }
1850 //*************************************************************************************************
1851 
1852 
1853 //*************************************************************************************************
1858 template< typename Type // Data type of the matrix
1859  , bool SO > // Storage order
1861 {
1862  const size_t block( BLOCK_SIZE );
1863 
1864  if( m_ == n_ )
1865  {
1866  for( size_t ii=0UL; ii<m_; ii+=block ) {
1867  const size_t iend( min( ii+block, m_ ) );
1868  for( size_t jj=0UL; jj<ii; jj+=block ) {
1869  const size_t jend( min( jj+block, n_ ) );
1870  for( size_t i=ii; i<iend; ++i ) {
1871  for( size_t j=jj; j<jend; ++j ) {
1872  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1873  }
1874  }
1875  }
1876  for( size_t i=ii; i<iend; ++i ) {
1877  for( size_t j=ii; j<i; ++j ) {
1878  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1879  }
1880  conjugate( v_[i*nn_+i] );
1881  }
1882  }
1883  }
1884  else
1885  {
1886  DynamicMatrix tmp( ctrans(*this) );
1887  swap( tmp );
1888  }
1889 
1890  return *this;
1891 }
1892 //*************************************************************************************************
1893 
1894 
1895 //*************************************************************************************************
1901 template< typename Type // Data type of the matrix
1902  , bool SO > // Storage order
1903 template< typename Other > // Data type of the scalar value
1905 {
1906  for( size_t i=0UL; i<m_; ++i )
1907  for( size_t j=0UL; j<n_; ++j )
1908  v_[i*nn_+j] *= scalar;
1909 
1910  return *this;
1911 }
1912 //*************************************************************************************************
1913 
1914 
1915 //*************************************************************************************************
1921 template< typename Type // Data type of the matrix
1922  , bool SO > // Storage order
1924 {
1925  std::swap( m_ , m.m_ );
1926  std::swap( n_ , m.n_ );
1927  std::swap( nn_, m.nn_ );
1928  std::swap( capacity_, m.capacity_ );
1929  std::swap( v_ , m.v_ );
1930 }
1931 //*************************************************************************************************
1932 
1933 
1934 //*************************************************************************************************
1940 template< typename Type // Data type of the matrix
1941  , bool SO > // Storage order
1942 inline size_t DynamicMatrix<Type,SO>::adjustColumns( size_t minColumns ) const noexcept
1943 {
1945  return nextMultiple<size_t>( minColumns, SIMDSIZE );
1946  else return minColumns;
1947 }
1948 //*************************************************************************************************
1949 
1950 
1951 
1952 
1953 //=================================================================================================
1954 //
1955 // DEBUGGING FUNCTIONS
1956 //
1957 //=================================================================================================
1958 
1959 //*************************************************************************************************
1968 template< typename Type // Data type of the matrix
1969  , bool SO > // Storage order
1970 inline bool DynamicMatrix<Type,SO>::isIntact() const noexcept
1971 {
1972  if( m_ * n_ > capacity_ )
1973  return false;
1974 
1976  for( size_t i=0UL; i<m_; ++i ) {
1977  for( size_t j=n_; j<nn_; ++j ) {
1978  if( v_[i*nn_+j] != Type() )
1979  return false;
1980  }
1981  }
1982  }
1983 
1984  return true;
1985 }
1986 //*************************************************************************************************
1987 
1988 
1989 
1990 
1991 //=================================================================================================
1992 //
1993 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1994 //
1995 //=================================================================================================
1996 
1997 //*************************************************************************************************
2007 template< typename Type // Data type of the matrix
2008  , bool SO > // Storage order
2009 template< typename Other > // Data type of the foreign expression
2010 inline bool DynamicMatrix<Type,SO>::canAlias( const Other* alias ) const noexcept
2011 {
2012  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2013 }
2014 //*************************************************************************************************
2015 
2016 
2017 //*************************************************************************************************
2027 template< typename Type // Data type of the matrix
2028  , bool SO > // Storage order
2029 template< typename Other > // Data type of the foreign expression
2030 inline bool DynamicMatrix<Type,SO>::isAliased( const Other* alias ) const noexcept
2031 {
2032  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2033 }
2034 //*************************************************************************************************
2035 
2036 
2037 //*************************************************************************************************
2046 template< typename Type // Data type of the matrix
2047  , bool SO > // Storage order
2048 inline bool DynamicMatrix<Type,SO>::isAligned() const noexcept
2049 {
2050  return ( usePadding || columns() % SIMDSIZE == 0UL );
2051 }
2052 //*************************************************************************************************
2053 
2054 
2055 //*************************************************************************************************
2065 template< typename Type // Data type of the matrix
2066  , bool SO > // Storage order
2067 inline bool DynamicMatrix<Type,SO>::canSMPAssign() const noexcept
2068 {
2069  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2070 }
2071 //*************************************************************************************************
2072 
2073 
2074 //*************************************************************************************************
2089 template< typename Type // Data type of the matrix
2090  , bool SO > // Storage order
2092  DynamicMatrix<Type,SO>::load( size_t i, size_t j ) const noexcept
2093 {
2094  if( usePadding )
2095  return loada( i, j );
2096  else
2097  return loadu( i, j );
2098 }
2099 //*************************************************************************************************
2100 
2101 
2102 //*************************************************************************************************
2117 template< typename Type // Data type of the matrix
2118  , bool SO > // Storage order
2120  DynamicMatrix<Type,SO>::loada( size_t i, size_t j ) const noexcept
2121 {
2122  using blaze::loada;
2123 
2125 
2126  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2127  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2128  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2129  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2130  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2131 
2132  return loada( v_+i*nn_+j );
2133 }
2134 //*************************************************************************************************
2135 
2136 
2137 //*************************************************************************************************
2152 template< typename Type // Data type of the matrix
2153  , bool SO > // Storage order
2155  DynamicMatrix<Type,SO>::loadu( size_t i, size_t j ) const noexcept
2156 {
2157  using blaze::loadu;
2158 
2160 
2161  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2162  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2163  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2164 
2165  return loadu( v_+i*nn_+j );
2166 }
2167 //*************************************************************************************************
2168 
2169 
2170 //*************************************************************************************************
2186 template< typename Type // Data type of the matrix
2187  , bool SO > // Storage order
2189  DynamicMatrix<Type,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2190 {
2191  if( usePadding )
2192  storea( i, j, value );
2193  else
2194  storeu( i, j, value );
2195 }
2196 //*************************************************************************************************
2197 
2198 
2199 //*************************************************************************************************
2215 template< typename Type // Data type of the matrix
2216  , bool SO > // Storage order
2218  DynamicMatrix<Type,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2219 {
2220  using blaze::storea;
2221 
2223 
2224  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2225  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2226  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2227  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2228  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2229 
2230  storea( v_+i*nn_+j, value );
2231 }
2232 //*************************************************************************************************
2233 
2234 
2235 //*************************************************************************************************
2251 template< typename Type // Data type of the matrix
2252  , bool SO > // Storage order
2254  DynamicMatrix<Type,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2255 {
2256  using blaze::storeu;
2257 
2259 
2260  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2261  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2262  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2263 
2264  storeu( v_+i*nn_+j, value );
2265 }
2266 //*************************************************************************************************
2267 
2268 
2269 //*************************************************************************************************
2286 template< typename Type // Data type of the matrix
2287  , bool SO > // Storage order
2289  DynamicMatrix<Type,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2290 {
2291  using blaze::stream;
2292 
2294 
2295  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2296  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2297  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2298  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2299  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2300 
2301  stream( v_+i*nn_+j, value );
2302 }
2303 //*************************************************************************************************
2304 
2305 
2306 //*************************************************************************************************
2317 template< typename Type // Data type of the matrix
2318  , bool SO > // Storage order
2319 template< typename MT > // Type of the right-hand side dense matrix
2322 {
2323  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2324  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2325 
2326  const size_t jpos( n_ & size_t(-2) );
2327  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2328 
2329  for( size_t i=0UL; i<m_; ++i ) {
2330  for( size_t j=0UL; j<jpos; j+=2UL ) {
2331  v_[i*nn_+j ] = (~rhs)(i,j );
2332  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
2333  }
2334  if( jpos < n_ ) {
2335  v_[i*nn_+jpos] = (~rhs)(i,jpos);
2336  }
2337  }
2338 }
2339 //*************************************************************************************************
2340 
2341 
2342 //*************************************************************************************************
2353 template< typename Type // Data type of the matrix
2354  , bool SO > // Storage order
2355 template< typename MT > // Type of the right-hand side dense matrix
2358 {
2360 
2361  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2362  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2363 
2364  const bool remainder( !usePadding || !IsPadded<MT>::value );
2365 
2366  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2367  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2368 
2369  if( usePadding && useStreaming &&
2370  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
2371  {
2372  for( size_t i=0UL; i<m_; ++i )
2373  {
2374  size_t j( 0UL );
2375  Iterator left( begin(i) );
2376  ConstIterator_<MT> right( (~rhs).begin(i) );
2377 
2378  for( ; j<jpos; j+=SIMDSIZE, left+=SIMDSIZE, right+=SIMDSIZE ) {
2379  left.stream( right.load() );
2380  }
2381  for( ; remainder && j<n_; ++j, ++left, ++right ) {
2382  *left = *right;
2383  }
2384  }
2385  }
2386  else
2387  {
2388  for( size_t i=0UL; i<m_; ++i )
2389  {
2390  size_t j( 0UL );
2391  Iterator left( begin(i) );
2392  ConstIterator_<MT> right( (~rhs).begin(i) );
2393 
2394  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2395  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2396  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2397  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2398  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2399  }
2400  for( ; j<jpos; j+=SIMDSIZE ) {
2401  left.store( right.load() ); left+=SIMDSIZE, right+=SIMDSIZE;
2402  }
2403  for( ; remainder && j<n_; ++j ) {
2404  *left = *right; ++left; ++right;
2405  }
2406  }
2407  }
2408 }
2409 //*************************************************************************************************
2410 
2411 
2412 //*************************************************************************************************
2423 template< typename Type // Data type of the matrix
2424  , bool SO > // Storage order
2425 template< typename MT > // Type of the right-hand side dense matrix
2427 {
2429 
2430  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2431  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2432 
2433  const size_t block( BLOCK_SIZE );
2434 
2435  for( size_t ii=0UL; ii<m_; ii+=block ) {
2436  const size_t iend( min( m_, ii+block ) );
2437  for( size_t jj=0UL; jj<n_; jj+=block ) {
2438  const size_t jend( min( n_, jj+block ) );
2439  for( size_t i=ii; i<iend; ++i ) {
2440  for( size_t j=jj; j<jend; ++j ) {
2441  v_[i*nn_+j] = (~rhs)(i,j);
2442  }
2443  }
2444  }
2445  }
2446 }
2447 //*************************************************************************************************
2448 
2449 
2450 //*************************************************************************************************
2461 template< typename Type // Data type of the matrix
2462  , bool SO > // Storage order
2463 template< typename MT > // Type of the right-hand side sparse matrix
2465 {
2466  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2467  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2468 
2469  for( size_t i=0UL; i<m_; ++i )
2470  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2471  v_[i*nn_+element->index()] = element->value();
2472 }
2473 //*************************************************************************************************
2474 
2475 
2476 //*************************************************************************************************
2487 template< typename Type // Data type of the matrix
2488  , bool SO > // Storage order
2489 template< typename MT > // Type of the right-hand side sparse matrix
2491 {
2493 
2494  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2495  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2496 
2497  for( size_t j=0UL; j<n_; ++j )
2498  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2499  v_[element->index()*nn_+j] = element->value();
2500 }
2501 //*************************************************************************************************
2502 
2503 
2504 //*************************************************************************************************
2515 template< typename Type // Data type of the matrix
2516  , bool SO > // Storage order
2517 template< typename MT > // Type of the right-hand side dense matrix
2518 inline DisableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2520 {
2521  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2522  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2523 
2524  for( size_t i=0UL; i<m_; ++i )
2525  {
2526  if( IsDiagonal<MT>::value )
2527  {
2528  v_[i*nn_+i] += (~rhs)(i,i);
2529  }
2530  else
2531  {
2532  const size_t jbegin( ( IsUpper<MT>::value )
2533  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2534  :( 0UL ) );
2535  const size_t jend ( ( IsLower<MT>::value )
2536  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2537  :( n_ ) );
2538  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2539 
2540  size_t j( jbegin );
2541 
2542  for( ; (j+2UL) <= jend; j+=2UL ) {
2543  v_[i*nn_+j ] += (~rhs)(i,j );
2544  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
2545  }
2546  if( j < jend ) {
2547  v_[i*nn_+j] += (~rhs)(i,j);
2548  }
2549  }
2550  }
2551 }
2552 //*************************************************************************************************
2553 
2554 
2555 //*************************************************************************************************
2566 template< typename Type // Data type of the matrix
2567  , bool SO > // Storage order
2568 template< typename MT > // Type of the right-hand side dense matrix
2569 inline EnableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2571 {
2574 
2575  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2576  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2577 
2578  const bool remainder( !usePadding || !IsPadded<MT>::value );
2579 
2580  for( size_t i=0UL; i<m_; ++i )
2581  {
2582  const size_t jbegin( ( IsUpper<MT>::value )
2583  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2584  :( 0UL ) );
2585  const size_t jend ( ( IsLower<MT>::value )
2586  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2587  :( n_ ) );
2588  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2589 
2590  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2591  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2592 
2593  size_t j( jbegin );
2594  Iterator left( begin(i) + jbegin );
2595  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2596 
2597  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2598  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2599  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2600  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2601  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2602  }
2603  for( ; j<jpos; j+=SIMDSIZE ) {
2604  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2605  }
2606  for( ; remainder && j<jend; ++j ) {
2607  *left += *right; ++left; ++right;
2608  }
2609  }
2610 }
2611 //*************************************************************************************************
2612 
2613 
2614 //*************************************************************************************************
2625 template< typename Type // Data type of the matrix
2626  , bool SO > // Storage order
2627 template< typename MT > // Type of the right-hand side dense matrix
2629 {
2631 
2632  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2633  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2634 
2635  const size_t block( BLOCK_SIZE );
2636 
2637  for( size_t ii=0UL; ii<m_; ii+=block ) {
2638  const size_t iend( min( m_, ii+block ) );
2639  for( size_t jj=0UL; jj<n_; jj+=block )
2640  {
2641  if( IsLower<MT>::value && ii < jj ) break;
2642  if( IsUpper<MT>::value && ii > jj ) continue;
2643 
2644  for( size_t i=ii; i<iend; ++i )
2645  {
2646  const size_t jbegin( ( IsUpper<MT>::value )
2647  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2648  :( jj ) );
2649  const size_t jend ( ( IsLower<MT>::value )
2650  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2651  :( min( n_, jj+block ) ) );
2652  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2653 
2654  for( size_t j=jbegin; j<jend; ++j ) {
2655  v_[i*nn_+j] += (~rhs)(i,j);
2656  }
2657  }
2658  }
2659  }
2660 }
2661 //*************************************************************************************************
2662 
2663 
2664 //*************************************************************************************************
2675 template< typename Type // Data type of the matrix
2676  , bool SO > // Storage order
2677 template< typename MT > // Type of the right-hand side sparse matrix
2679 {
2680  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2681  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2682 
2683  for( size_t i=0UL; i<m_; ++i )
2684  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2685  v_[i*nn_+element->index()] += element->value();
2686 }
2687 //*************************************************************************************************
2688 
2689 
2690 //*************************************************************************************************
2701 template< typename Type // Data type of the matrix
2702  , bool SO > // Storage order
2703 template< typename MT > // Type of the right-hand side sparse matrix
2705 {
2707 
2708  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2709  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2710 
2711  for( size_t j=0UL; j<n_; ++j )
2712  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2713  v_[element->index()*nn_+j] += element->value();
2714 }
2715 //*************************************************************************************************
2716 
2717 
2718 //*************************************************************************************************
2729 template< typename Type // Data type of the matrix
2730  , bool SO > // Storage order
2731 template< typename MT > // Type of the right-hand side dense matrix
2732 inline DisableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
2734 {
2735  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2736  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2737 
2738  for( size_t i=0UL; i<m_; ++i )
2739  {
2740  if( IsDiagonal<MT>::value )
2741  {
2742  v_[i*nn_+i] -= (~rhs)(i,i);
2743  }
2744  else
2745  {
2746  const size_t jbegin( ( IsUpper<MT>::value )
2747  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2748  :( 0UL ) );
2749  const size_t jend ( ( IsLower<MT>::value )
2750  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2751  :( n_ ) );
2752  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2753 
2754  size_t j( jbegin );
2755 
2756  for( ; (j+2UL) <= jend; j+=2UL ) {
2757  v_[i*nn_+j ] -= (~rhs)(i,j );
2758  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
2759  }
2760  if( j < jend ) {
2761  v_[i*nn_+j] -= (~rhs)(i,j);
2762  }
2763  }
2764  }
2765 }
2766 //*************************************************************************************************
2767 
2768 
2769 //*************************************************************************************************
2780 template< typename Type // Data type of the matrix
2781  , bool SO > // Storage order
2782 template< typename MT > // Type of the right-hand side dense matrix
2783 inline EnableIf_<typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
2785 {
2788 
2789  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2790  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2791 
2792  const bool remainder( !usePadding || !IsPadded<MT>::value );
2793 
2794  for( size_t i=0UL; i<m_; ++i )
2795  {
2796  const size_t jbegin( ( IsUpper<MT>::value )
2797  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2798  :( 0UL ) );
2799  const size_t jend ( ( IsLower<MT>::value )
2800  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2801  :( n_ ) );
2802  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2803 
2804  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2805  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2806 
2807  size_t j( jbegin );
2808  Iterator left( begin(i) + jbegin );
2809  ConstIterator_<MT> right( (~rhs).begin(i) + jbegin );
2810 
2811  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2812  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2813  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2814  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2815  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2816  }
2817  for( ; j<jpos; j+=SIMDSIZE ) {
2818  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2819  }
2820  for( ; remainder && j<jend; ++j ) {
2821  *left -= *right; ++left; ++right;
2822  }
2823  }
2824 }
2825 //*************************************************************************************************
2826 
2827 
2828 //*************************************************************************************************
2839 template< typename Type // Data type of the matrix
2840  , bool SO > // Storage order
2841 template< typename MT > // Type of the right-hand side dense matrix
2843 {
2845 
2846  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2847  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2848 
2849  const size_t block( BLOCK_SIZE );
2850 
2851  for( size_t ii=0UL; ii<m_; ii+=block ) {
2852  const size_t iend( min( m_, ii+block ) );
2853  for( size_t jj=0UL; jj<n_; jj+=block )
2854  {
2855  if( IsLower<MT>::value && ii < jj ) break;
2856  if( IsUpper<MT>::value && ii > jj ) continue;
2857 
2858  for( size_t i=ii; i<iend; ++i )
2859  {
2860  const size_t jbegin( ( IsUpper<MT>::value )
2861  ?( max( ( IsStrictlyUpper<MT>::value ? i+1UL : i ), jj ) )
2862  :( jj ) );
2863  const size_t jend ( ( IsLower<MT>::value )
2864  ?( min( ( IsStrictlyLower<MT>::value ? i : i+1UL ), n_, jj+block ) )
2865  :( min( n_, jj+block ) ) );
2866  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2867 
2868  for( size_t j=jbegin; j<jend; ++j ) {
2869  v_[i*nn_+j] -= (~rhs)(i,j);
2870  }
2871  }
2872  }
2873  }
2874 }
2875 //*************************************************************************************************
2876 
2877 
2878 //*************************************************************************************************
2889 template< typename Type // Data type of the matrix
2890  , bool SO > // Storage order
2891 template< typename MT > // Type of the right-hand side sparse matrix
2893 {
2894  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2895  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2896 
2897  for( size_t i=0UL; i<m_; ++i )
2898  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2899  v_[i*nn_+element->index()] -= element->value();
2900 }
2901 //*************************************************************************************************
2902 
2903 
2904 //*************************************************************************************************
2915 template< typename Type // Data type of the matrix
2916  , bool SO > // Storage order
2917 template< typename MT > // Type of the right-hand side sparse matrix
2919 {
2921 
2922  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2923  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2924 
2925  for( size_t j=0UL; j<n_; ++j )
2926  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2927  v_[element->index()*nn_+j] -= element->value();
2928 }
2929 //*************************************************************************************************
2930 
2931 
2932 
2933 
2934 
2935 
2936 
2937 
2938 //=================================================================================================
2939 //
2940 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2941 //
2942 //=================================================================================================
2943 
2944 //*************************************************************************************************
2952 template< typename Type > // Data type of the matrix
2953 class DynamicMatrix<Type,true> : public DenseMatrix< DynamicMatrix<Type,true>, true >
2954 {
2955  public:
2956  //**Type definitions****************************************************************************
2957  typedef DynamicMatrix<Type,true> This;
2959  typedef This ResultType;
2962  typedef Type ElementType;
2964  typedef const Type& ReturnType;
2965  typedef const This& CompositeType;
2966 
2967  typedef Type& Reference;
2968  typedef const Type& ConstReference;
2969  typedef Type* Pointer;
2970  typedef const Type* ConstPointer;
2971 
2974  //**********************************************************************************************
2975 
2976  //**Rebind struct definition********************************************************************
2979  template< typename ET > // Data type of the other matrix
2980  struct Rebind {
2981  typedef DynamicMatrix<ET,true> Other;
2982  };
2983  //**********************************************************************************************
2984 
2985  //**Compilation flags***************************************************************************
2987 
2991  enum : bool { simdEnabled = IsVectorizable<Type>::value };
2992 
2994 
2997  enum : bool { smpAssignable = !IsSMPAssignable<Type>::value };
2998  //**********************************************************************************************
2999 
3000  //**Constructors********************************************************************************
3003  explicit inline DynamicMatrix() noexcept;
3004  explicit inline DynamicMatrix( size_t m, size_t n );
3005  explicit inline DynamicMatrix( size_t m, size_t n, const Type& init );
3006  explicit inline DynamicMatrix( initializer_list< initializer_list<Type> > list );
3007 
3008  template< typename Other > explicit inline DynamicMatrix( size_t m, size_t n, const Other* array );
3009 
3010  template< typename Other, size_t M, size_t N >
3011  explicit inline DynamicMatrix( const Other (&array)[M][N] );
3012 
3013  inline DynamicMatrix( const DynamicMatrix& m );
3014  inline DynamicMatrix( DynamicMatrix&& m );
3015  template< typename MT, bool SO > inline DynamicMatrix( const Matrix<MT,SO>& m );
3017  //**********************************************************************************************
3018 
3019  //**Destructor**********************************************************************************
3022  inline ~DynamicMatrix();
3024  //**********************************************************************************************
3025 
3026  //**Data access functions***********************************************************************
3029  inline Reference operator()( size_t i, size_t j ) noexcept;
3030  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3031  inline Reference at( size_t i, size_t j );
3032  inline ConstReference at( size_t i, size_t j ) const;
3033  inline Pointer data () noexcept;
3034  inline ConstPointer data () const noexcept;
3035  inline Pointer data ( size_t j ) noexcept;
3036  inline ConstPointer data ( size_t j ) const noexcept;
3037  inline Iterator begin ( size_t j ) noexcept;
3038  inline ConstIterator begin ( size_t j ) const noexcept;
3039  inline ConstIterator cbegin( size_t j ) const noexcept;
3040  inline Iterator end ( size_t j ) noexcept;
3041  inline ConstIterator end ( size_t j ) const noexcept;
3042  inline ConstIterator cend ( size_t j ) const noexcept;
3044  //**********************************************************************************************
3045 
3046  //**Assignment operators************************************************************************
3049  inline DynamicMatrix& operator=( const Type& rhs );
3050  inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list );
3051 
3052  template< typename Other, size_t M, size_t N >
3053  inline DynamicMatrix& operator=( const Other (&array)[M][N] );
3054 
3055  inline DynamicMatrix& operator=( const DynamicMatrix& rhs );
3056  inline DynamicMatrix& operator=( DynamicMatrix&& rhs );
3057 
3058  template< typename MT, bool SO > inline DynamicMatrix& operator= ( const Matrix<MT,SO>& rhs );
3059  template< typename MT, bool SO > inline DynamicMatrix& operator+=( const Matrix<MT,SO>& rhs );
3060  template< typename MT, bool SO > inline DynamicMatrix& operator-=( const Matrix<MT,SO>& rhs );
3061  template< typename MT, bool SO > inline DynamicMatrix& operator*=( const Matrix<MT,SO>& rhs );
3062 
3063  template< typename Other >
3064  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator*=( Other rhs );
3065 
3066  template< typename Other >
3067  inline EnableIf_<IsNumeric<Other>, DynamicMatrix >& operator/=( Other rhs );
3069  //**********************************************************************************************
3070 
3071  //**Utility functions***************************************************************************
3074  inline size_t rows() const noexcept;
3075  inline size_t columns() const noexcept;
3076  inline size_t spacing() const noexcept;
3077  inline size_t capacity() const noexcept;
3078  inline size_t capacity( size_t j ) const noexcept;
3079  inline size_t nonZeros() const;
3080  inline size_t nonZeros( size_t j ) const;
3081  inline void reset();
3082  inline void reset( size_t j );
3083  inline void clear();
3084  void resize ( size_t m, size_t n, bool preserve=true );
3085  inline void extend ( size_t m, size_t n, bool preserve=true );
3086  inline void reserve( size_t elements );
3087  inline DynamicMatrix& transpose();
3088  inline DynamicMatrix& ctranspose();
3089  template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
3090  inline void swap( DynamicMatrix& m ) noexcept;
3092  //**********************************************************************************************
3093 
3094  private:
3095  //**********************************************************************************************
3097  template< typename MT >
3098  struct VectorizedAssign {
3099  enum : bool { value = useOptimizedKernels &&
3100  simdEnabled && MT::simdEnabled &&
3101  AreSIMDCombinable< Type, ElementType_<MT> >::value };
3102  };
3103  //**********************************************************************************************
3104 
3105  //**********************************************************************************************
3107  template< typename MT >
3108  struct VectorizedAddAssign {
3109  enum : bool { value = useOptimizedKernels &&
3110  simdEnabled && MT::simdEnabled &&
3111  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3112  HasSIMDAdd< Type, ElementType_<MT> >::value &&
3113  !IsDiagonal<MT>::value };
3114  };
3115  //**********************************************************************************************
3116 
3117  //**********************************************************************************************
3119  template< typename MT >
3120  struct VectorizedSubAssign {
3121  enum : bool { value = useOptimizedKernels &&
3122  simdEnabled && MT::simdEnabled &&
3123  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3124  HasSIMDSub< Type, ElementType_<MT> >::value &&
3125  !IsDiagonal<MT>::value };
3126  };
3127  //**********************************************************************************************
3128 
3129  //**********************************************************************************************
3131  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3132  //**********************************************************************************************
3133 
3134  public:
3135  //**Debugging functions*************************************************************************
3138  inline bool isIntact() const noexcept;
3140  //**********************************************************************************************
3141 
3142  //**Expression template evaluation functions****************************************************
3145  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3146  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3147 
3148  inline bool isAligned () const noexcept;
3149  inline bool canSMPAssign() const noexcept;
3150 
3151  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3152  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3153  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3154 
3155  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3156  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3157  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3158  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3159 
3160  template< typename MT >
3161  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3162 
3163  template< typename MT >
3164  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,true>& rhs );
3165 
3166  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3167  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3168  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3169 
3170  template< typename MT >
3171  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3172 
3173  template< typename MT >
3174  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,true>& rhs );
3175 
3176  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3177  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3178  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3179 
3180  template< typename MT >
3181  inline DisableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3182 
3183  template< typename MT >
3184  inline EnableIf_<VectorizedSubAssign<MT> > subAssign ( const DenseMatrix<MT,true>& rhs );
3185 
3186  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3187  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3188  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3190  //**********************************************************************************************
3191 
3192  private:
3193  //**Utility functions***************************************************************************
3196  inline size_t adjustRows( size_t minRows ) const noexcept;
3198  //**********************************************************************************************
3199 
3200  //**Member variables****************************************************************************
3203  size_t m_;
3204  size_t mm_;
3205  size_t n_;
3206  size_t capacity_;
3207  Type* BLAZE_RESTRICT v_;
3208 
3211  //**********************************************************************************************
3212 
3213  //**Compile time checks*************************************************************************
3218  //**********************************************************************************************
3219 };
3221 //*************************************************************************************************
3222 
3223 
3224 
3225 
3226 //=================================================================================================
3227 //
3228 // CONSTRUCTORS
3229 //
3230 //=================================================================================================
3231 
3232 //*************************************************************************************************
3236 template< typename Type > // Data type of the matrix
3237 inline DynamicMatrix<Type,true>::DynamicMatrix() noexcept
3238  : m_ ( 0UL ) // The current number of rows of the matrix
3239  , mm_ ( 0UL ) // The alignment adjusted number of rows
3240  , n_ ( 0UL ) // The current number of columns of the matrix
3241  , capacity_( 0UL ) // The maximum capacity of the matrix
3242  , v_ ( nullptr ) // The matrix elements
3243 {}
3245 //*************************************************************************************************
3246 
3247 
3248 //*************************************************************************************************
3258 template< typename Type > // Data type of the matrix
3259 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n )
3260  : m_ ( m ) // The current number of rows of the matrix
3261  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
3262  , n_ ( n ) // The current number of columns of the matrix
3263  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3264  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3265 {
3266  if( IsVectorizable<Type>::value ) {
3267  for( size_t j=0UL; j<n_; ++j ) {
3268  for( size_t i=m_; i<mm_; ++i ) {
3269  v_[i+j*mm_] = Type();
3270  }
3271  }
3272  }
3273 
3274  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3275 }
3277 //*************************************************************************************************
3278 
3279 
3280 //*************************************************************************************************
3290 template< typename Type > // Data type of the matrix
3291 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, const Type& init )
3292  : m_ ( m ) // The current number of rows of the matrix
3293  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
3294  , n_ ( n ) // The current number of columns of the matrix
3295  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3296  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3297 {
3298  for( size_t j=0UL; j<n_; ++j ) {
3299  for( size_t i=0UL; i<m_; ++i )
3300  v_[i+j*mm_] = init;
3301 
3302  if( IsVectorizable<Type>::value ) {
3303  for( size_t i=m_; i<mm_; ++i )
3304  v_[i+j*mm_] = Type();
3305  }
3306  }
3307 
3308  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3309 }
3311 //*************************************************************************************************
3312 
3313 
3314 //*************************************************************************************************
3335 template< typename Type > // Data type of the matrix
3336 inline DynamicMatrix<Type,true>::DynamicMatrix( initializer_list< initializer_list<Type> > list )
3337  : m_ ( list.size() ) // The current number of rows of the matrix
3338  , mm_ ( adjustRows( m_ ) ) // The alignment adjusted number of rows
3339  , n_ ( determineColumns( list ) ) // The current number of columns of the matrix
3340  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3341  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3342 {
3343  size_t i( 0UL );
3344 
3345  for( const auto& rowList : list ) {
3346  size_t j( 0UL );
3347  for( const auto& element : rowList ) {
3348  v_[i+j*mm_] = element;
3349  ++j;
3350  }
3351  for( ; j<n_; ++j ) {
3352  v_[i+j*mm_] = Type();
3353  }
3354  ++i;
3355  }
3356 
3357  BLAZE_INTERNAL_ASSERT( i == m_, "Invalid number of elements detected" );
3358 
3359  if( IsVectorizable<Type>::value ) {
3360  for( ; i<mm_; ++i ) {
3361  for( size_t j=0UL; j<n_; ++j ) {
3362  v_[i+j*mm_] = Type();
3363  }
3364  }
3365  }
3366 
3367  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3368 }
3370 //*************************************************************************************************
3371 
3372 
3373 //*************************************************************************************************
3397 template< typename Type > // Data type of the matrix
3398 template< typename Other > // Data type of the initialization array
3399 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, const Other* array )
3400  : m_ ( m ) // The current number of rows of the matrix
3401  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
3402  , n_ ( n ) // The current number of columns of the matrix
3403  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3404  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3405 {
3406  for( size_t j=0UL; j<n; ++j ) {
3407  for( size_t i=0UL; i<m; ++i )
3408  v_[i+j*mm_] = array[i+j*m];
3409 
3410  if( IsVectorizable<Type>::value ) {
3411  for( size_t i=m; i<mm_; ++i )
3412  v_[i+j*mm_] = Type();
3413  }
3414  }
3415 
3416  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3417 }
3419 //*************************************************************************************************
3420 
3421 
3422 //*************************************************************************************************
3444 template< typename Type > // Data type of the matrix
3445 template< typename Other // Data type of the initialization array
3446  , size_t M // Number of rows of the initialization array
3447  , size_t N > // Number of columns of the initialization array
3448 inline DynamicMatrix<Type,true>::DynamicMatrix( const Other (&array)[M][N] )
3449  : m_ ( M ) // The current number of rows of the matrix
3450  , mm_ ( adjustRows( M ) ) // The alignment adjusted number of rows
3451  , n_ ( N ) // The current number of columns of the matrix
3452  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3453  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3454 {
3455  for( size_t j=0UL; j<N; ++j ) {
3456  for( size_t i=0UL; i<M; ++i )
3457  v_[i+j*mm_] = array[i][j];
3458 
3459  if( IsVectorizable<Type>::value ) {
3460  for( size_t i=M; i<mm_; ++i )
3461  v_[i+j*mm_] = Type();
3462  }
3463  }
3464 
3465  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3466 }
3468 //*************************************************************************************************
3469 
3470 
3471 //*************************************************************************************************
3480 template< typename Type > // Data type of the matrix
3481 inline DynamicMatrix<Type,true>::DynamicMatrix( const DynamicMatrix& m )
3482  : m_ ( m.m_ ) // The current number of rows of the matrix
3483  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
3484  , n_ ( m.n_ ) // The current number of columns of the matrix
3485  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3486  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3487 {
3488  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
3489 
3490  for( size_t i=0UL; i<capacity_; ++i )
3491  v_[i] = m.v_[i];
3492 
3493  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3494 }
3496 //*************************************************************************************************
3497 
3498 
3499 //*************************************************************************************************
3505 template< typename Type > // Data type of the matrix
3506 inline DynamicMatrix<Type,true>::DynamicMatrix( DynamicMatrix&& m )
3507  : m_ ( m.m_ ) // The current number of rows of the matrix
3508  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
3509  , n_ ( m.n_ ) // The current number of columns of the matrix
3510  , capacity_( m.capacity_ ) // The maximum capacity of the matrix
3511  , v_ ( m.v_ ) // The matrix elements
3512 {
3513  m.m_ = 0UL;
3514  m.mm_ = 0UL;
3515  m.n_ = 0UL;
3516  m.capacity_ = 0UL;
3517  m.v_ = nullptr;
3518 }
3520 //*************************************************************************************************
3521 
3522 
3523 //*************************************************************************************************
3529 template< typename Type > // Data type of the matrix
3530 template< typename MT // Type of the foreign matrix
3531  , bool SO > // Storage order of the foreign matrix
3532 inline DynamicMatrix<Type,true>::DynamicMatrix( const Matrix<MT,SO>& m )
3533  : m_ ( (~m).rows() ) // The current number of rows of the matrix
3534  , mm_ ( adjustRows( m_ ) ) // The alignment adjusted number of rows
3535  , n_ ( (~m).columns() ) // The current number of columns of the matrix
3536  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3537  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3538 {
3539  for( size_t j=0UL; j<n_; ++j ) {
3540  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : m_ );
3541  i<( IsVectorizable<Type>::value ? mm_ : m_ ); ++i ) {
3542  v_[i+j*mm_] = Type();
3543  }
3544  }
3545 
3546  smpAssign( *this, ~m );
3547 
3548  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3549 }
3551 //*************************************************************************************************
3552 
3553 
3554 
3555 
3556 //=================================================================================================
3557 //
3558 // DESTRUCTOR
3559 //
3560 //=================================================================================================
3561 
3562 //*************************************************************************************************
3566 template< typename Type > // Data type of the matrix
3568 {
3569  deallocate( v_ );
3570 }
3572 //*************************************************************************************************
3573 
3574 
3575 
3576 
3577 //=================================================================================================
3578 //
3579 // DATA ACCESS FUNCTIONS
3580 //
3581 //=================================================================================================
3582 
3583 //*************************************************************************************************
3594 template< typename Type > // Data type of the matrix
3596  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) noexcept
3597 {
3598  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3599  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3600  return v_[i+j*mm_];
3601 }
3603 //*************************************************************************************************
3604 
3605 
3606 //*************************************************************************************************
3617 template< typename Type > // Data type of the matrix
3619  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) const noexcept
3620 {
3621  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3622  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3623  return v_[i+j*mm_];
3624 }
3626 //*************************************************************************************************
3627 
3628 
3629 //*************************************************************************************************
3641 template< typename Type > // Data type of the matrix
3643  DynamicMatrix<Type,true>::at( size_t i, size_t j )
3644 {
3645  if( i >= m_ ) {
3646  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3647  }
3648  if( j >= n_ ) {
3649  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3650  }
3651  return (*this)(i,j);
3652 }
3654 //*************************************************************************************************
3655 
3656 
3657 //*************************************************************************************************
3669 template< typename Type > // Data type of the matrix
3671  DynamicMatrix<Type,true>::at( size_t i, size_t j ) const
3672 {
3673  if( i >= m_ ) {
3674  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3675  }
3676  if( j >= n_ ) {
3677  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3678  }
3679  return (*this)(i,j);
3680 }
3682 //*************************************************************************************************
3683 
3684 
3685 //*************************************************************************************************
3697 template< typename Type > // Data type of the matrix
3698 inline typename DynamicMatrix<Type,true>::Pointer
3700 {
3701  return v_;
3702 }
3704 //*************************************************************************************************
3705 
3706 
3707 //*************************************************************************************************
3719 template< typename Type > // Data type of the matrix
3720 inline typename DynamicMatrix<Type,true>::ConstPointer
3721  DynamicMatrix<Type,true>::data() const noexcept
3722 {
3723  return v_;
3724 }
3726 //*************************************************************************************************
3727 
3728 
3729 //*************************************************************************************************
3738 template< typename Type > // Data type of the matrix
3739 inline typename DynamicMatrix<Type,true>::Pointer
3740  DynamicMatrix<Type,true>::data( size_t j ) noexcept
3741 {
3742  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3743  return v_ + j*mm_;
3744 }
3746 //*************************************************************************************************
3747 
3748 
3749 //*************************************************************************************************
3758 template< typename Type > // Data type of the matrix
3759 inline typename DynamicMatrix<Type,true>::ConstPointer
3760  DynamicMatrix<Type,true>::data( size_t j ) const noexcept
3761 {
3762  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3763  return v_ + j*mm_;
3764 }
3766 //*************************************************************************************************
3767 
3768 
3769 //*************************************************************************************************
3776 template< typename Type > // Data type of the matrix
3777 inline typename DynamicMatrix<Type,true>::Iterator
3778  DynamicMatrix<Type,true>::begin( size_t j ) noexcept
3779 {
3780  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3781  return Iterator( v_ + j*mm_ );
3782 }
3784 //*************************************************************************************************
3785 
3786 
3787 //*************************************************************************************************
3794 template< typename Type > // Data type of the matrix
3796  DynamicMatrix<Type,true>::begin( size_t j ) const noexcept
3797 {
3798  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3799  return ConstIterator( v_ + j*mm_ );
3800 }
3802 //*************************************************************************************************
3803 
3804 
3805 //*************************************************************************************************
3812 template< typename Type > // Data type of the matrix
3814  DynamicMatrix<Type,true>::cbegin( size_t j ) const noexcept
3815 {
3816  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3817  return ConstIterator( v_ + j*mm_ );
3818 }
3820 //*************************************************************************************************
3821 
3822 
3823 //*************************************************************************************************
3830 template< typename Type > // Data type of the matrix
3831 inline typename DynamicMatrix<Type,true>::Iterator
3832  DynamicMatrix<Type,true>::end( size_t j ) noexcept
3833 {
3834  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3835  return Iterator( v_ + j*mm_ + m_ );
3836 }
3838 //*************************************************************************************************
3839 
3840 
3841 //*************************************************************************************************
3848 template< typename Type > // Data type of the matrix
3850  DynamicMatrix<Type,true>::end( size_t j ) const noexcept
3851 {
3852  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3853  return ConstIterator( v_ + j*mm_ + m_ );
3854 }
3856 //*************************************************************************************************
3857 
3858 
3859 //*************************************************************************************************
3866 template< typename Type > // Data type of the matrix
3868  DynamicMatrix<Type,true>::cend( size_t j ) const noexcept
3869 {
3870  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3871  return ConstIterator( v_ + j*mm_ + m_ );
3872 }
3874 //*************************************************************************************************
3875 
3876 
3877 
3878 
3879 //=================================================================================================
3880 //
3881 // ASSIGNMENT OPERATORS
3882 //
3883 //=================================================================================================
3884 
3885 //*************************************************************************************************
3892 template< typename Type > // Data type of the matrix
3893 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Type& rhs )
3894 {
3895  for( size_t j=0UL; j<n_; ++j )
3896  for( size_t i=0UL; i<m_; ++i )
3897  v_[i+j*mm_] = rhs;
3898 
3899  return *this;
3900 }
3902 //*************************************************************************************************
3903 
3904 
3905 //*************************************************************************************************
3927 template< typename Type > // Data type of the matrix
3928 inline DynamicMatrix<Type,true>&
3929  DynamicMatrix<Type,true>::operator=( initializer_list< initializer_list<Type> > list )
3930 {
3931  resize( list.size(), determineColumns( list ), false );
3932 
3933  size_t i( 0UL );
3934 
3935  for( const auto& rowList : list ) {
3936  size_t j( 0UL );
3937  for( const auto& element : rowList ) {
3938  v_[i+j*mm_] = element;
3939  ++j;
3940  }
3941  for( ; j<n_; ++j ) {
3942  v_[i+j*mm_] = Type();
3943  }
3944  ++i;
3945  }
3946 
3947  return *this;
3948 }
3950 //*************************************************************************************************
3951 
3952 
3953 //*************************************************************************************************
3975 template< typename Type > // Data type of the matrix
3976 template< typename Other // Data type of the initialization array
3977  , size_t M // Number of rows of the initialization array
3978  , size_t N > // Number of columns of the initialization array
3979 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Other (&array)[M][N] )
3980 {
3981  resize( M, N, false );
3982 
3983  for( size_t j=0UL; j<N; ++j )
3984  for( size_t i=0UL; i<M; ++i )
3985  v_[i+j*mm_] = array[i][j];
3986 
3987  return *this;
3988 }
3990 //*************************************************************************************************
3991 
3992 
3993 //*************************************************************************************************
4003 template< typename Type > // Data type of the matrix
4004 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const DynamicMatrix& rhs )
4005 {
4006  if( &rhs == this ) return *this;
4007 
4008  resize( rhs.m_, rhs.n_, false );
4009  smpAssign( *this, ~rhs );
4010 
4011  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4012 
4013  return *this;
4014 }
4016 //*************************************************************************************************
4017 
4018 
4019 //*************************************************************************************************
4026 template< typename Type > // Data type of the matrix
4027 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( DynamicMatrix&& rhs )
4028 {
4029  deallocate( v_ );
4030 
4031  m_ = rhs.m_;
4032  mm_ = rhs.mm_;
4033  n_ = rhs.n_;
4034  capacity_ = rhs.capacity_;
4035  v_ = rhs.v_;
4036 
4037  rhs.m_ = 0UL;
4038  rhs.mm_ = 0UL;
4039  rhs.n_ = 0UL;
4040  rhs.capacity_ = 0UL;
4041  rhs.v_ = nullptr;
4042 
4043  return *this;
4044 }
4046 //*************************************************************************************************
4047 
4048 
4049 //*************************************************************************************************
4059 template< typename Type > // Data type of the matrix
4060 template< typename MT // Type of the right-hand side matrix
4061  , bool SO > // Storage order of the right-hand side matrix
4062 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Matrix<MT,SO>& rhs )
4063 {
4064  typedef TransExprTrait_<This> TT;
4065  typedef CTransExprTrait_<This> CT;
4066  typedef InvExprTrait_<This> IT;
4067 
4068  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4069  transpose();
4070  }
4071  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4072  ctranspose();
4073  }
4074  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4075  DynamicMatrix tmp( ~rhs );
4076  swap( tmp );
4077  }
4078  else {
4079  resize( (~rhs).rows(), (~rhs).columns(), false );
4080  if( IsSparseMatrix<MT>::value )
4081  reset();
4082  smpAssign( *this, ~rhs );
4083  }
4084 
4085  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4086 
4087  return *this;
4088 }
4090 //*************************************************************************************************
4091 
4092 
4093 //*************************************************************************************************
4104 template< typename Type > // Data type of the matrix
4105 template< typename MT // Type of the right-hand side matrix
4106  , bool SO > // Storage order of the right-hand side matrix
4107 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
4108 {
4109  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4110  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4111  }
4112 
4113  if( (~rhs).canAlias( this ) ) {
4114  const ResultType_<MT> tmp( ~rhs );
4115  smpAddAssign( *this, tmp );
4116  }
4117  else {
4118  smpAddAssign( *this, ~rhs );
4119  }
4120 
4121  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4122 
4123  return *this;
4124 }
4126 //*************************************************************************************************
4127 
4128 
4129 //*************************************************************************************************
4140 template< typename Type > // Data type of the matrix
4141 template< typename MT // Type of the right-hand side matrix
4142  , bool SO > // Storage order of the right-hand side matrix
4143 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
4144 {
4145  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4146  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4147  }
4148 
4149  if( (~rhs).canAlias( this ) ) {
4150  const ResultType_<MT> tmp( ~rhs );
4151  smpSubAssign( *this, tmp );
4152  }
4153  else {
4154  smpSubAssign( *this, ~rhs );
4155  }
4156 
4157  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4158 
4159  return *this;
4160 }
4162 //*************************************************************************************************
4163 
4164 
4165 //*************************************************************************************************
4176 template< typename Type > // Data type of the matrix
4177 template< typename MT // Type of the right-hand side matrix
4178  , bool SO > // Storage order of the right-hand side matrix
4179 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
4180 {
4181  if( (~rhs).rows() != n_ ) {
4182  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4183  }
4184 
4185  DynamicMatrix tmp( *this * (~rhs) );
4186  swap( tmp );
4187 
4188  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4189 
4190  return *this;
4191 }
4193 //*************************************************************************************************
4194 
4195 
4196 //*************************************************************************************************
4204 template< typename Type > // Data type of the matrix
4205 template< typename Other > // Data type of the right-hand side scalar
4206 inline EnableIf_<IsNumeric<Other>, DynamicMatrix<Type,true> >&
4208 {
4209  smpAssign( *this, (*this) * rhs );
4210 
4211  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4212 
4213  return *this;
4214 }
4216 //*************************************************************************************************
4217 
4218 
4219 //*************************************************************************************************
4227 template< typename Type > // Data type of the matrix
4228 template< typename Other > // Data type of the right-hand side scalar
4229 inline EnableIf_<IsNumeric<Other>, DynamicMatrix<Type,true> >&
4231 {
4232  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4233 
4234  smpAssign( *this, (*this) / rhs );
4235 
4236  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4237 
4238  return *this;
4239 }
4241 //*************************************************************************************************
4242 
4243 
4244 
4245 
4246 //=================================================================================================
4247 //
4248 // UTILITY FUNCTIONS
4249 //
4250 //=================================================================================================
4251 
4252 //*************************************************************************************************
4258 template< typename Type > // Data type of the matrix
4259 inline size_t DynamicMatrix<Type,true>::rows() const noexcept
4260 {
4261  return m_;
4262 }
4264 //*************************************************************************************************
4265 
4266 
4267 //*************************************************************************************************
4273 template< typename Type > // Data type of the matrix
4274 inline size_t DynamicMatrix<Type,true>::columns() const noexcept
4275 {
4276  return n_;
4277 }
4279 //*************************************************************************************************
4280 
4281 
4282 //*************************************************************************************************
4291 template< typename Type > // Data type of the matrix
4292 inline size_t DynamicMatrix<Type,true>::spacing() const noexcept
4293 {
4294  return mm_;
4295 }
4297 //*************************************************************************************************
4298 
4299 
4300 //*************************************************************************************************
4306 template< typename Type > // Data type of the matrix
4307 inline size_t DynamicMatrix<Type,true>::capacity() const noexcept
4308 {
4309  return capacity_;
4310 }
4312 //*************************************************************************************************
4313 
4314 
4315 //*************************************************************************************************
4322 template< typename Type > // Data type of the matrix
4323 inline size_t DynamicMatrix<Type,true>::capacity( size_t j ) const noexcept
4324 {
4325  UNUSED_PARAMETER( j );
4326  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4327  return mm_;
4328 }
4330 //*************************************************************************************************
4331 
4332 
4333 //*************************************************************************************************
4339 template< typename Type > // Data type of the matrix
4340 inline size_t DynamicMatrix<Type,true>::nonZeros() const
4341 {
4342  size_t nonzeros( 0UL );
4343 
4344  for( size_t j=0UL; j<n_; ++j )
4345  for( size_t i=0UL; i<m_; ++i )
4346  if( !isDefault( v_[i+j*mm_] ) )
4347  ++nonzeros;
4348 
4349  return nonzeros;
4350 }
4352 //*************************************************************************************************
4353 
4354 
4355 //*************************************************************************************************
4362 template< typename Type > // Data type of the matrix
4363 inline size_t DynamicMatrix<Type,true>::nonZeros( size_t j ) const
4364 {
4365  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4366 
4367  const size_t iend( j*mm_ + m_ );
4368  size_t nonzeros( 0UL );
4369 
4370  for( size_t i=j*mm_; i<iend; ++i )
4371  if( !isDefault( v_[i] ) )
4372  ++nonzeros;
4373 
4374  return nonzeros;
4375 }
4377 //*************************************************************************************************
4378 
4379 
4380 //*************************************************************************************************
4386 template< typename Type > // Data type of the matrix
4387 inline void DynamicMatrix<Type,true>::reset()
4388 {
4389  using blaze::clear;
4390 
4391  for( size_t j=0UL; j<n_; ++j )
4392  for( size_t i=0UL; i<m_; ++i )
4393  clear( v_[i+j*mm_] );
4394 }
4396 //*************************************************************************************************
4397 
4398 
4399 //*************************************************************************************************
4409 template< typename Type > // Data type of the matrix
4410 inline void DynamicMatrix<Type,true>::reset( size_t j )
4411 {
4412  using blaze::clear;
4413 
4414  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4415  for( size_t i=0UL; i<m_; ++i )
4416  clear( v_[i+j*mm_] );
4417 }
4419 //*************************************************************************************************
4420 
4421 
4422 //*************************************************************************************************
4430 template< typename Type > // Data type of the matrix
4431 inline void DynamicMatrix<Type,true>::clear()
4432 {
4433  resize( 0UL, 0UL, false );
4434 }
4436 //*************************************************************************************************
4437 
4438 
4439 //*************************************************************************************************
4474 template< typename Type > // Data type of the matrix
4475 void DynamicMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
4476 {
4477  using blaze::min;
4478 
4479  if( m == m_ && n == n_ ) return;
4480 
4481  const size_t mm( adjustRows( m ) );
4482 
4483  if( preserve )
4484  {
4485  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
4486  const size_t min_m( min( m, m_ ) );
4487  const size_t min_n( min( n, n_ ) );
4488 
4489  for( size_t j=0UL; j<min_n; ++j ) {
4490  transfer( v_+j*mm_, v_+min_m+j*mm_, v+j*mm );
4491  }
4492 
4493  std::swap( v_, v );
4494  deallocate( v );
4495  capacity_ = mm*n;
4496  }
4497  else if( mm*n > capacity_ ) {
4498  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
4499  std::swap( v_, v );
4500  deallocate( v );
4501  capacity_ = mm*n;
4502  }
4503 
4504  if( IsVectorizable<Type>::value ) {
4505  for( size_t j=0UL; j<n; ++j )
4506  for( size_t i=m; i<mm; ++i )
4507  v_[i+j*mm] = Type();
4508  }
4509 
4510  m_ = m;
4511  mm_ = mm;
4512  n_ = n;
4513 }
4515 //*************************************************************************************************
4516 
4517 
4518 //*************************************************************************************************
4533 template< typename Type > // Data type of the matrix
4534 inline void DynamicMatrix<Type,true>::extend( size_t m, size_t n, bool preserve )
4535 {
4536  resize( m_+m, n_+n, preserve );
4537 }
4539 //*************************************************************************************************
4540 
4541 
4542 //*************************************************************************************************
4552 template< typename Type > // Data type of the matrix
4553 inline void DynamicMatrix<Type,true>::reserve( size_t elements )
4554 {
4555  if( elements > capacity_ )
4556  {
4557  // Allocating a new array
4558  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
4559 
4560  // Initializing the new array
4561  transfer( v_, v_+capacity_, tmp );
4562 
4563  if( IsVectorizable<Type>::value ) {
4564  for( size_t i=capacity_; i<elements; ++i )
4565  tmp[i] = Type();
4566  }
4567 
4568  // Replacing the old array
4569  std::swap( tmp, v_ );
4570  deallocate( tmp );
4571  capacity_ = elements;
4572  }
4573 }
4575 //*************************************************************************************************
4576 
4577 
4578 //*************************************************************************************************
4584 template< typename Type > // Data type of the matrix
4585 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::transpose()
4586 {
4587  using std::swap;
4588 
4589  const size_t block( BLOCK_SIZE );
4590 
4591  if( m_ == n_ )
4592  {
4593  for( size_t jj=0UL; jj<n_; jj+=block ) {
4594  const size_t jend( min( jj+block, n_ ) );
4595  for( size_t ii=0UL; ii<=jj; ii+=block ) {
4596  for( size_t j=jj; j<jend; ++j ) {
4597  const size_t iend( min( ii+block, m_, j ) );
4598  for( size_t i=ii; i<iend; ++i ) {
4599  swap( v_[i+j*mm_], v_[j+i*mm_] );
4600  }
4601  }
4602  }
4603  }
4604  }
4605  else
4606  {
4607  DynamicMatrix tmp( trans(*this) );
4608  this->swap( tmp );
4609  }
4610 
4611  return *this;
4612 }
4614 //*************************************************************************************************
4615 
4616 
4617 //*************************************************************************************************
4623 template< typename Type > // Data type of the matrix
4624 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::ctranspose()
4625 {
4626  const size_t block( BLOCK_SIZE );
4627 
4628  if( m_ == n_ )
4629  {
4630  for( size_t jj=0UL; jj<n_; jj+=block ) {
4631  const size_t jend( min( jj+block, n_ ) );
4632  for( size_t ii=0UL; ii<jj; ii+=block ) {
4633  const size_t iend( min( ii+block, m_ ) );
4634  for( size_t j=jj; j<jend; ++j ) {
4635  for( size_t i=ii; i<iend; ++i ) {
4636  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4637  }
4638  }
4639  }
4640  for( size_t j=jj; j<jend; ++j ) {
4641  for( size_t i=jj; i<j; ++i ) {
4642  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4643  }
4644  conjugate( v_[j+j*mm_] );
4645  }
4646  }
4647  }
4648  else
4649  {
4650  DynamicMatrix tmp( ctrans(*this) );
4651  this->swap( tmp );
4652  }
4653 
4654  return *this;
4655 }
4657 //*************************************************************************************************
4658 
4659 
4660 //*************************************************************************************************
4667 template< typename Type > // Data type of the matrix
4668 template< typename Other > // Data type of the scalar value
4669 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::scale( const Other& scalar )
4670 {
4671  for( size_t j=0UL; j<n_; ++j )
4672  for( size_t i=0UL; i<m_; ++i )
4673  v_[i+j*mm_] *= scalar;
4674 
4675  return *this;
4676 }
4678 //*************************************************************************************************
4679 
4680 
4681 //*************************************************************************************************
4688 template< typename Type > // Data type of the matrix
4689 inline void DynamicMatrix<Type,true>::swap( DynamicMatrix& m ) noexcept
4690 {
4691  std::swap( m_ , m.m_ );
4692  std::swap( mm_, m.mm_ );
4693  std::swap( n_ , m.n_ );
4694  std::swap( capacity_, m.capacity_ );
4695  std::swap( v_ , m.v_ );
4696 }
4698 //*************************************************************************************************
4699 
4700 
4701 //*************************************************************************************************
4708 template< typename Type > // Data type of the matrix
4709 inline size_t DynamicMatrix<Type,true>::adjustRows( size_t minRows ) const noexcept
4710 {
4711  if( usePadding && IsVectorizable<Type>::value )
4712  return nextMultiple<size_t>( minRows, SIMDSIZE );
4713  else return minRows;
4714 }
4716 //*************************************************************************************************
4717 
4718 
4719 
4720 
4721 //=================================================================================================
4722 //
4723 // DEBUGGING FUNCTIONS
4724 //
4725 //=================================================================================================
4726 
4727 //*************************************************************************************************
4737 template< typename Type > // Data type of the matrix
4738 inline bool DynamicMatrix<Type,true>::isIntact() const noexcept
4739 {
4740  if( m_ * n_ > capacity_ )
4741  return false;
4742 
4743  if( IsVectorizable<Type>::value ) {
4744  for( size_t j=0UL; j<n_; ++j ) {
4745  for( size_t i=m_; i<mm_; ++i ) {
4746  if( v_[i+j*mm_] != Type() )
4747  return false;
4748  }
4749  }
4750  }
4751 
4752  return true;
4753 }
4755 //*************************************************************************************************
4756 
4757 
4758 
4759 
4760 //=================================================================================================
4761 //
4762 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4763 //
4764 //=================================================================================================
4765 
4766 //*************************************************************************************************
4777 template< typename Type > // Data type of the matrix
4778 template< typename Other > // Data type of the foreign expression
4779 inline bool DynamicMatrix<Type,true>::canAlias( const Other* alias ) const noexcept
4780 {
4781  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4782 }
4784 //*************************************************************************************************
4785 
4786 
4787 //*************************************************************************************************
4798 template< typename Type > // Data type of the matrix
4799 template< typename Other > // Data type of the foreign expression
4800 inline bool DynamicMatrix<Type,true>::isAliased( const Other* alias ) const noexcept
4801 {
4802  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4803 }
4805 //*************************************************************************************************
4806 
4807 
4808 //*************************************************************************************************
4818 template< typename Type > // Data type of the matrix
4819 inline bool DynamicMatrix<Type,true>::isAligned() const noexcept
4820 {
4821  return ( usePadding || rows() % SIMDSIZE == 0UL );
4822 }
4824 //*************************************************************************************************
4825 
4826 
4827 //*************************************************************************************************
4838 template< typename Type > // Data type of the matrix
4839 inline bool DynamicMatrix<Type,true>::canSMPAssign() const noexcept
4840 {
4841  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
4842 }
4844 //*************************************************************************************************
4845 
4846 
4847 //*************************************************************************************************
4862 template< typename Type > // Data type of the matrix
4863 BLAZE_ALWAYS_INLINE typename DynamicMatrix<Type,true>::SIMDType
4864  DynamicMatrix<Type,true>::load( size_t i, size_t j ) const noexcept
4865 {
4866  if( usePadding )
4867  return loada( i, j );
4868  else
4869  return loadu( i, j );
4870 }
4872 //*************************************************************************************************
4873 
4874 
4875 //*************************************************************************************************
4890 template< typename Type > // Data type of the matrix
4891 BLAZE_ALWAYS_INLINE typename DynamicMatrix<Type,true>::SIMDType
4892  DynamicMatrix<Type,true>::loada( size_t i, size_t j ) const noexcept
4893 {
4894  using blaze::loada;
4895 
4897 
4898  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4899  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
4900  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
4901  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4902  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
4903 
4904  return loada( v_+i+j*mm_ );
4905 }
4907 //*************************************************************************************************
4908 
4909 
4910 //*************************************************************************************************
4925 template< typename Type > // Data type of the matrix
4926 BLAZE_ALWAYS_INLINE typename DynamicMatrix<Type,true>::SIMDType
4927  DynamicMatrix<Type,true>::loadu( size_t i, size_t j ) const noexcept
4928 {
4929  using blaze::loadu;
4930 
4932 
4933  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4934  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
4935  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4936 
4937  return loadu( v_+i+j*mm_ );
4938 }
4940 //*************************************************************************************************
4941 
4942 
4943 //*************************************************************************************************
4959 template< typename Type > // Data type of the matrix
4961  DynamicMatrix<Type,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
4962 {
4963  if( usePadding )
4964  storea( i, j, value );
4965  else
4966  storeu( i, j, value );
4967 }
4969 //*************************************************************************************************
4970 
4971 
4972 //*************************************************************************************************
4988 template< typename Type > // Data type of the matrix
4990  DynamicMatrix<Type,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
4991 {
4992  using blaze::storea;
4993 
4995 
4996  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4997  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
4998  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
4999  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5000  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5001 
5002  storea( v_+i+j*mm_, value );
5003 }
5005 //*************************************************************************************************
5006 
5007 
5008 //*************************************************************************************************
5024 template< typename Type > // Data type of the matrix
5026  DynamicMatrix<Type,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5027 {
5028  using blaze::storeu;
5029 
5031 
5032  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5033  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5034  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5035 
5036  storeu( v_+i+j*mm_, value );
5037 }
5039 //*************************************************************************************************
5040 
5041 
5042 //*************************************************************************************************
5059 template< typename Type > // Data type of the matrix
5061  DynamicMatrix<Type,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5062 {
5063  using blaze::stream;
5064 
5066 
5067  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5068  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5069  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5070  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5071  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5072 
5073  stream( v_+i+j*mm_, value );
5074 }
5076 //*************************************************************************************************
5077 
5078 
5079 //*************************************************************************************************
5091 template< typename Type > // Data type of the matrix
5092 template< typename MT > // Type of the right-hand side dense matrix
5093 inline DisableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >
5094  DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
5095 {
5096  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5097  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5098 
5099  const size_t ipos( m_ & size_t(-2) );
5100  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5101 
5102  for( size_t j=0UL; j<n_; ++j ) {
5103  for( size_t i=0UL; i<ipos; i+=2UL ) {
5104  v_[i +j*mm_] = (~rhs)(i ,j);
5105  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
5106  }
5107  if( ipos < m_ ) {
5108  v_[ipos+j*mm_] = (~rhs)(ipos,j);
5109  }
5110  }
5111 }
5113 //*************************************************************************************************
5114 
5115 
5116 //*************************************************************************************************
5128 template< typename Type > // Data type of the matrix
5129 template< typename MT > // Type of the right-hand side dense matrix
5130 inline EnableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >
5131  DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
5132 {
5134 
5135  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5136  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5137 
5138  const bool remainder( !usePadding || !IsPadded<MT>::value );
5139 
5140  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5141  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5142 
5143  if( usePadding && useStreaming &&
5144  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
5145  {
5146  for( size_t j=0UL; j<n_; ++j )
5147  {
5148  size_t i( 0UL );
5149  Iterator left( begin(j) );
5150  ConstIterator_<MT> right( (~rhs).begin(j) );
5151 
5152  for( ; i<ipos; i+=SIMDSIZE ) {
5153  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5154  }
5155  for( ; remainder && i<m_; ++i ) {
5156  *left = *right; ++left; ++right;
5157  }
5158  }
5159  }
5160  else
5161  {
5162  for( size_t j=0UL; j<n_; ++j )
5163  {
5164  size_t i( 0UL );
5165  Iterator left( begin(j) );
5166  ConstIterator_<MT> right( (~rhs).begin(j) );
5167 
5168  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5169  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5170  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5171  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5172  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5173  }
5174  for( ; i<ipos; i+=SIMDSIZE ) {
5175  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5176  }
5177  for( ; remainder && i<m_; ++i ) {
5178  *left = *right; ++left; ++right;
5179  }
5180  }
5181  }
5182 }
5184 //*************************************************************************************************
5185 
5186 
5187 //*************************************************************************************************
5199 template< typename Type > // Data type of the matrix
5200 template< typename MT > // Type of the right-hand side dense matrix
5201 inline void DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,false>& rhs )
5202 {
5204 
5205  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5206  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5207 
5208  const size_t block( BLOCK_SIZE );
5209 
5210  for( size_t jj=0UL; jj<n_; jj+=block ) {
5211  const size_t jend( min( n_, jj+block ) );
5212  for( size_t ii=0UL; ii<m_; ii+=block ) {
5213  const size_t iend( min( m_, ii+block ) );
5214  for( size_t j=jj; j<jend; ++j ) {
5215  for( size_t i=ii; i<iend; ++i ) {
5216  v_[i+j*mm_] = (~rhs)(i,j);
5217  }
5218  }
5219  }
5220  }
5221 }
5223 //*************************************************************************************************
5224 
5225 
5226 //*************************************************************************************************
5238 template< typename Type > // Data type of the matrix
5239 template< typename MT > // Type of the right-hand side sparse matrix
5240 inline void DynamicMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
5241 {
5242  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5243  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5244 
5245  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5246  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5247  v_[element->index()+j*mm_] = element->value();
5248 }
5250 //*************************************************************************************************
5251 
5252 
5253 //*************************************************************************************************
5265 template< typename Type > // Data type of the matrix
5266 template< typename MT > // Type of the right-hand side sparse matrix
5267 inline void DynamicMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
5268 {
5270 
5271  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5272  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5273 
5274  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5275  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5276  v_[i+element->index()*mm_] = element->value();
5277 }
5279 //*************************************************************************************************
5280 
5281 
5282 //*************************************************************************************************
5294 template< typename Type > // Data type of the matrix
5295 template< typename MT > // Type of the right-hand side dense matrix
5296 inline DisableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5297  DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
5298 {
5299  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5300  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5301 
5302  for( size_t j=0UL; j<n_; ++j )
5303  {
5304  if( IsDiagonal<MT>::value )
5305  {
5306  v_[j+j*mm_] += (~rhs)(j,j);
5307  }
5308  else
5309  {
5310  const size_t ibegin( ( IsLower<MT>::value )
5311  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5312  :( 0UL ) );
5313  const size_t iend ( ( IsUpper<MT>::value )
5314  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5315  :( m_ ) );
5316  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5317 
5318  size_t i( ibegin );
5319 
5320  for( ; (i+2UL) <= iend; i+=2UL ) {
5321  v_[i +j*mm_] += (~rhs)(i ,j);
5322  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
5323  }
5324  if( i < iend ) {
5325  v_[i+j*mm_] += (~rhs)(i,j);
5326  }
5327  }
5328  }
5329 }
5331 //*************************************************************************************************
5332 
5333 
5334 //*************************************************************************************************
5346 template< typename Type > // Data type of the matrix
5347 template< typename MT > // Type of the right-hand side dense matrix
5348 inline EnableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5349  DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
5350 {
5353 
5354  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5355  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5356 
5357  const bool remainder( !usePadding || !IsPadded<MT>::value );
5358 
5359  for( size_t j=0UL; j<n_; ++j )
5360  {
5361  const size_t ibegin( ( IsLower<MT>::value )
5362  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5363  :( 0UL ) );
5364  const size_t iend ( ( IsUpper<MT>::value )
5365  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5366  :( m_ ) );
5367  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5368 
5369  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5370  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5371 
5372  size_t i( ibegin );
5373  Iterator left( begin(j) + ibegin );
5374  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
5375 
5376  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5377  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5378  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5379  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5380  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5381  }
5382  for( ; i<ipos; i+=SIMDSIZE ) {
5383  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5384  }
5385  for( ; remainder && i<iend; ++i ) {
5386  *left += *right; ++left; ++right;
5387  }
5388  }
5389 }
5391 //*************************************************************************************************
5392 
5393 
5394 //*************************************************************************************************
5406 template< typename Type > // Data type of the matrix
5407 template< typename MT > // Type of the right-hand side dense matrix
5408 inline void DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,false>& rhs )
5409 {
5411 
5412  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5413  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5414 
5415  const size_t block( BLOCK_SIZE );
5416 
5417  for( size_t jj=0UL; jj<n_; jj+=block ) {
5418  const size_t jend( min( n_, jj+block ) );
5419  for( size_t ii=0UL; ii<m_; ii+=block )
5420  {
5421  if( IsLower<MT>::value && ii < jj ) continue;
5422  if( IsUpper<MT>::value && ii > jj ) break;
5423 
5424  for( size_t j=jj; j<jend; ++j )
5425  {
5426  const size_t ibegin( ( IsLower<MT>::value )
5427  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5428  :( ii ) );
5429  const size_t iend ( ( IsUpper<MT>::value )
5430  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5431  :( min( m_, ii+block ) ) );
5432  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5433 
5434  for( size_t i=ibegin; i<iend; ++i ) {
5435  v_[i+j*mm_] += (~rhs)(i,j);
5436  }
5437  }
5438  }
5439  }
5440 }
5442 //*************************************************************************************************
5443 
5444 
5445 //*************************************************************************************************
5457 template< typename Type > // Data type of the matrix
5458 template< typename MT > // Type of the right-hand side sparse matrix
5459 inline void DynamicMatrix<Type,true>::addAssign( const SparseMatrix<MT,true>& rhs )
5460 {
5461  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5462  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5463 
5464  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5465  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5466  v_[element->index()+j*mm_] += element->value();
5467 }
5469 //*************************************************************************************************
5470 
5471 
5472 //*************************************************************************************************
5484 template< typename Type > // Data type of the matrix
5485 template< typename MT > // Type of the right-hand side sparse matrix
5486 inline void DynamicMatrix<Type,true>::addAssign( const SparseMatrix<MT,false>& rhs )
5487 {
5489 
5490  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5491  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5492 
5493  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5494  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5495  v_[i+element->index()*mm_] += element->value();
5496 }
5498 //*************************************************************************************************
5499 
5500 
5501 //*************************************************************************************************
5513 template< typename Type > // Data type of the matrix
5514 template< typename MT > // Type of the right-hand side dense matrix
5515 inline DisableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5516  DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
5517 {
5518  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5519  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5520 
5521  for( size_t j=0UL; j<n_; ++j )
5522  {
5523  if( IsDiagonal<MT>::value )
5524  {
5525  v_[j+j*mm_] -= (~rhs)(j,j);
5526  }
5527  else
5528  {
5529  const size_t ibegin( ( IsLower<MT>::value )
5530  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5531  :( 0UL ) );
5532  const size_t iend ( ( IsUpper<MT>::value )
5533  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5534  :( m_ ) );
5535  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5536 
5537  size_t i( ibegin );
5538 
5539  for( ; (i+2UL) <= iend; i+=2UL ) {
5540  v_[i +j*mm_] -= (~rhs)(i ,j);
5541  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
5542  }
5543  if( i < iend ) {
5544  v_[i+j*mm_] -= (~rhs)(i,j);
5545  }
5546  }
5547  }
5548 }
5550 //*************************************************************************************************
5551 
5552 
5553 //*************************************************************************************************
5565 template< typename Type > // Data type of the matrix
5566 template< typename MT > // Type of the right-hand side dense matrix
5567 inline EnableIf_<typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5568  DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
5569 {
5572 
5573  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5574  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5575 
5576  const bool remainder( !usePadding || !IsPadded<MT>::value );
5577 
5578  for( size_t j=0UL; j<n_; ++j )
5579  {
5580  const size_t ibegin( ( IsLower<MT>::value )
5581  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5582  :( 0UL ) );
5583  const size_t iend ( ( IsUpper<MT>::value )
5584  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5585  :( m_ ) );
5586  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5587 
5588  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5589  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5590 
5591  size_t i( ibegin );
5592  Iterator left( begin(j) + ibegin );
5593  ConstIterator_<MT> right( (~rhs).begin(j) + ibegin );
5594 
5595  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5596  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5597  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5598  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5599  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5600  }
5601  for( ; i<ipos; i+=SIMDSIZE ) {
5602  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5603  }
5604  for( ; remainder && i<iend; ++i ) {
5605  *left -= *right; ++left; ++right;
5606  }
5607  }
5608 }
5610 //*************************************************************************************************
5611 
5612 
5613 //*************************************************************************************************
5625 template< typename Type > // Data type of the matrix
5626 template< typename MT > // Type of the right-hand side dense matrix
5627 inline void DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,false>& rhs )
5628 {
5630 
5631  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5632  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5633 
5634  const size_t block( BLOCK_SIZE );
5635 
5636  for( size_t jj=0UL; jj<n_; jj+=block ) {
5637  const size_t jend( min( n_, jj+block ) );
5638  for( size_t ii=0UL; ii<m_; ii+=block )
5639  {
5640  if( IsLower<MT>::value && ii < jj ) continue;
5641  if( IsUpper<MT>::value && ii > jj ) break;
5642 
5643  for( size_t j=jj; j<jend; ++j )
5644  {
5645  const size_t ibegin( ( IsLower<MT>::value )
5646  ?( max( ( IsStrictlyLower<MT>::value ? j+1UL : j ), ii ) )
5647  :( ii ) );
5648  const size_t iend ( ( IsUpper<MT>::value )
5649  ?( min( ( IsStrictlyUpper<MT>::value ? j : j+1UL ), m_, ii+block ) )
5650  :( min( m_, ii+block ) ) );
5651  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5652 
5653  for( size_t i=ibegin; i<iend; ++i ) {
5654  v_[i+j*mm_] -= (~rhs)(i,j);
5655  }
5656  }
5657  }
5658  }
5659 }
5661 //*************************************************************************************************
5662 
5663 
5664 //*************************************************************************************************
5676 template< typename Type > // Data type of the matrix
5677 template< typename MT > // Type of the right-hand side sparse matrix
5678 inline void DynamicMatrix<Type,true>::subAssign( const SparseMatrix<MT,true>& rhs )
5679 {
5680  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5681  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5682 
5683  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5684  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5685  v_[element->index()+j*mm_] -= element->value();
5686 }
5688 //*************************************************************************************************
5689 
5690 
5691 //*************************************************************************************************
5703 template< typename Type > // Data type of the matrix
5704 template< typename MT > // Type of the right-hand side sparse matrix
5705 inline void DynamicMatrix<Type,true>::subAssign( const SparseMatrix<MT,false>& rhs )
5706 {
5708 
5709  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5710  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5711 
5712  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5713  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5714  v_[i+element->index()*mm_] -= element->value();
5715 }
5717 //*************************************************************************************************
5718 
5719 
5720 
5721 
5722 
5723 
5724 
5725 
5726 //=================================================================================================
5727 //
5728 // DYNAMICMATRIX OPERATORS
5729 //
5730 //=================================================================================================
5731 
5732 //*************************************************************************************************
5735 template< typename Type, bool SO >
5736 inline void reset( DynamicMatrix<Type,SO>& m );
5737 
5738 template< typename Type, bool SO >
5739 inline void reset( DynamicMatrix<Type,SO>& m, size_t i );
5740 
5741 template< typename Type, bool SO >
5742 inline void clear( DynamicMatrix<Type,SO>& m );
5743 
5744 template< typename Type, bool SO >
5745 inline bool isDefault( const DynamicMatrix<Type,SO>& m );
5746 
5747 template< typename Type, bool SO >
5748 inline bool isIntact( const DynamicMatrix<Type,SO>& m ) noexcept;
5749 
5750 template< typename Type, bool SO >
5751 inline void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) noexcept;
5753 //*************************************************************************************************
5754 
5755 
5756 //*************************************************************************************************
5763 template< typename Type // Data type of the matrix
5764  , bool SO > // Storage order
5766 {
5767  m.reset();
5768 }
5769 //*************************************************************************************************
5770 
5771 
5772 //*************************************************************************************************
5785 template< typename Type // Data type of the matrix
5786  , bool SO > // Storage order
5787 inline void reset( DynamicMatrix<Type,SO>& m, size_t i )
5788 {
5789  m.reset( i );
5790 }
5791 //*************************************************************************************************
5792 
5793 
5794 //*************************************************************************************************
5801 template< typename Type // Data type of the matrix
5802  , bool SO > // Storage order
5804 {
5805  m.clear();
5806 }
5807 //*************************************************************************************************
5808 
5809 
5810 //*************************************************************************************************
5828 template< typename Type // Data type of the matrix
5829  , bool SO > // Storage order
5830 inline bool isDefault( const DynamicMatrix<Type,SO>& m )
5831 {
5832  return ( m.rows() == 0UL && m.columns() == 0UL );
5833 }
5834 //*************************************************************************************************
5835 
5836 
5837 //*************************************************************************************************
5855 template< typename Type // Data type of the matrix
5856  , bool SO > // Storage order
5857 inline bool isIntact( const DynamicMatrix<Type,SO>& m ) noexcept
5858 {
5859  return m.isIntact();
5860 }
5861 //*************************************************************************************************
5862 
5863 
5864 //*************************************************************************************************
5872 template< typename Type // Data type of the matrix
5873  , bool SO > // Storage order
5875 {
5876  a.swap( b );
5877 }
5878 //*************************************************************************************************
5879 
5880 
5881 
5882 
5883 //=================================================================================================
5884 //
5885 // HASCONSTDATAACCESS SPECIALIZATIONS
5886 //
5887 //=================================================================================================
5888 
5889 //*************************************************************************************************
5891 template< typename T, bool SO >
5892 struct HasConstDataAccess< DynamicMatrix<T,SO> > : public TrueType
5893 {};
5895 //*************************************************************************************************
5896 
5897 
5898 
5899 
5900 //=================================================================================================
5901 //
5902 // HASMUTABLEDATAACCESS SPECIALIZATIONS
5903 //
5904 //=================================================================================================
5905 
5906 //*************************************************************************************************
5908 template< typename T, bool SO >
5909 struct HasMutableDataAccess< DynamicMatrix<T,SO> > : public TrueType
5910 {};
5912 //*************************************************************************************************
5913 
5914 
5915 
5916 
5917 //=================================================================================================
5918 //
5919 // ISALIGNED SPECIALIZATIONS
5920 //
5921 //=================================================================================================
5922 
5923 //*************************************************************************************************
5925 template< typename T, bool SO >
5926 struct IsAligned< DynamicMatrix<T,SO> > : public BoolConstant<usePadding>
5927 {};
5929 //*************************************************************************************************
5930 
5931 
5932 
5933 
5934 //=================================================================================================
5935 //
5936 // ISPADDED SPECIALIZATIONS
5937 //
5938 //=================================================================================================
5939 
5940 //*************************************************************************************************
5942 template< typename T, bool SO >
5943 struct IsPadded< DynamicMatrix<T,SO> > : public BoolConstant<usePadding>
5944 {};
5946 //*************************************************************************************************
5947 
5948 
5949 
5950 
5951 //=================================================================================================
5952 //
5953 // ISRESIZABLE SPECIALIZATIONS
5954 //
5955 //=================================================================================================
5956 
5957 //*************************************************************************************************
5959 template< typename T, bool SO >
5960 struct IsResizable< DynamicMatrix<T,SO> > : public TrueType
5961 {};
5963 //*************************************************************************************************
5964 
5965 
5966 
5967 
5968 //=================================================================================================
5969 //
5970 // ADDTRAIT SPECIALIZATIONS
5971 //
5972 //=================================================================================================
5973 
5974 //*************************************************************************************************
5976 template< typename T1, bool SO, typename T2, size_t M, size_t N >
5977 struct AddTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
5978 {
5979  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
5980 };
5981 
5982 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
5983 struct AddTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
5984 {
5985  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
5986 };
5987 
5988 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5989 struct AddTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
5990 {
5991  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, SO >;
5992 };
5993 
5994 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
5995 struct AddTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
5996 {
5997  using Type = StaticMatrix< AddTrait_<T1,T2>, M, N, false >;
5998 };
5999 
6000 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6001 struct AddTrait< DynamicMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6002 {
6003  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6004 };
6005 
6006 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6007 struct AddTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6008 {
6009  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6010 };
6011 
6012 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6013 struct AddTrait< HybridMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6014 {
6015  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, SO >;
6016 };
6017 
6018 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6019 struct AddTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6020 {
6021  using Type = HybridMatrix< AddTrait_<T1,T2>, M, N, false >;
6022 };
6023 
6024 template< typename T1, bool SO, typename T2 >
6025 struct AddTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6026 {
6027  using Type = DynamicMatrix< AddTrait_<T1,T2>, SO >;
6028 };
6029 
6030 template< typename T1, bool SO1, typename T2, bool SO2 >
6031 struct AddTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6032 {
6033  using Type = DynamicMatrix< AddTrait_<T1,T2>, false >;
6034 };
6036 //*************************************************************************************************
6037 
6038 
6039 
6040 
6041 //=================================================================================================
6042 //
6043 // SUBTRAIT SPECIALIZATIONS
6044 //
6045 //=================================================================================================
6046 
6047 //*************************************************************************************************
6049 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6050 struct SubTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
6051 {
6052  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6053 };
6054 
6055 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6056 struct SubTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6057 {
6058  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6059 };
6060 
6061 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6062 struct SubTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6063 {
6064  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, SO >;
6065 };
6066 
6067 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6068 struct SubTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6069 {
6070  using Type = StaticMatrix< SubTrait_<T1,T2>, M, N, false >;
6071 };
6072 
6073 template< typename T1, bool SO, typename T2, size_t M, size_t N >
6074 struct SubTrait< DynamicMatrix<T1,SO>, HybridMatrix<T2,M,N,SO> >
6075 {
6076  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6077 };
6078 
6079 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6080 struct SubTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6081 {
6082  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6083 };
6084 
6085 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6086 struct SubTrait< HybridMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
6087 {
6088  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, SO >;
6089 };
6090 
6091 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6092 struct SubTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6093 {
6094  using Type = HybridMatrix< SubTrait_<T1,T2>, M, N, false >;
6095 };
6096 
6097 template< typename T1, bool SO, typename T2 >
6098 struct SubTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6099 {
6100  using Type = DynamicMatrix< SubTrait_<T1,T2>, SO >;
6101 };
6102 
6103 template< typename T1, bool SO1, typename T2, bool SO2 >
6104 struct SubTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6105 {
6106  using Type = DynamicMatrix< SubTrait_<T1,T2>, false >;
6107 };
6109 //*************************************************************************************************
6110 
6111 
6112 
6113 
6114 //=================================================================================================
6115 //
6116 // MULTTRAIT SPECIALIZATIONS
6117 //
6118 //=================================================================================================
6119 
6120 //*************************************************************************************************
6122 template< typename T1, bool SO, typename T2 >
6123 struct MultTrait< DynamicMatrix<T1,SO>, T2, EnableIf_<IsNumeric<T2> > >
6124 {
6125  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6126 };
6127 
6128 template< typename T1, typename T2, bool SO >
6129 struct MultTrait< T1, DynamicMatrix<T2,SO>, EnableIf_<IsNumeric<T1> > >
6130 {
6131  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO >;
6132 };
6133 
6134 template< typename T1, bool SO, typename T2, size_t N >
6135 struct MultTrait< DynamicMatrix<T1,SO>, StaticVector<T2,N,false> >
6136 {
6137  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6138 };
6139 
6140 template< typename T1, size_t N, typename T2, bool SO >
6141 struct MultTrait< StaticVector<T1,N,true>, DynamicMatrix<T2,SO> >
6142 {
6143  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6144 };
6145 
6146 template< typename T1, bool SO, typename T2, size_t N >
6147 struct MultTrait< DynamicMatrix<T1,SO>, HybridVector<T2,N,false> >
6148 {
6149  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6150 };
6151 
6152 template< typename T1, size_t N, typename T2, bool SO >
6153 struct MultTrait< HybridVector<T1,N,true>, DynamicMatrix<T2,SO> >
6154 {
6155  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6156 };
6157 
6158 template< typename T1, bool SO, typename T2 >
6159 struct MultTrait< DynamicMatrix<T1,SO>, DynamicVector<T2,false> >
6160 {
6161  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6162 };
6163 
6164 template< typename T1, typename T2, bool SO >
6165 struct MultTrait< DynamicVector<T1,true>, DynamicMatrix<T2,SO> >
6166 {
6167  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6168 };
6169 
6170 template< typename T1, bool SO, typename T2, bool AF, bool PF >
6171 struct MultTrait< DynamicMatrix<T1,SO>, CustomVector<T2,AF,PF,false> >
6172 {
6173  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6174 };
6175 
6176 template< typename T1, bool AF, bool PF, typename T2, bool SO >
6177 struct MultTrait< CustomVector<T1,AF,PF,true>, DynamicMatrix<T2,SO> >
6178 {
6179  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6180 };
6181 
6182 template< typename T1, bool SO, typename T2 >
6183 struct MultTrait< DynamicMatrix<T1,SO>, CompressedVector<T2,false> >
6184 {
6185  using Type = DynamicVector< MultTrait_<T1,T2>, false >;
6186 };
6187 
6188 template< typename T1, typename T2, bool SO >
6189 struct MultTrait< CompressedVector<T1,true>, DynamicMatrix<T2,SO> >
6190 {
6191  using Type = DynamicVector< MultTrait_<T1,T2>, true >;
6192 };
6193 
6194 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6195 struct MultTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
6196 {
6197  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6198 };
6199 
6200 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6201 struct MultTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6202 {
6203  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6204 };
6205 
6206 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
6207 struct MultTrait< DynamicMatrix<T1,SO1>, HybridMatrix<T2,M,N,SO2> >
6208 {
6209  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6210 };
6211 
6212 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
6213 struct MultTrait< HybridMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
6214 {
6215  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6216 };
6217 
6218 template< typename T1, bool SO1, typename T2, bool SO2 >
6219 struct MultTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
6220 {
6221  using Type = DynamicMatrix< MultTrait_<T1,T2>, SO1 >;
6222 };
6224 //*************************************************************************************************
6225 
6226 
6227 
6228 
6229 //=================================================================================================
6230 //
6231 // DIVTRAIT SPECIALIZATIONS
6232 //
6233 //=================================================================================================
6234 
6235 //*************************************************************************************************
6237 template< typename T1, bool SO, typename T2 >
6238 struct DivTrait< DynamicMatrix<T1,SO>, T2, EnableIf_<IsNumeric<T2> > >
6239 {
6240  using Type = DynamicMatrix< DivTrait_<T1,T2>, SO >;
6241 };
6243 //*************************************************************************************************
6244 
6245 
6246 
6247 
6248 //=================================================================================================
6249 //
6250 // MATHTRAIT SPECIALIZATIONS
6251 //
6252 //=================================================================================================
6253 
6254 //*************************************************************************************************
6256 template< typename T1, bool SO, typename T2 >
6257 struct MathTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6258 {
6259  using HighType = DynamicMatrix< typename MathTrait<T1,T2>::HighType, SO >;
6260  using LowType = DynamicMatrix< typename MathTrait<T1,T2>::LowType , SO >;
6261 };
6263 //*************************************************************************************************
6264 
6265 
6266 
6267 
6268 //=================================================================================================
6269 //
6270 // SUBMATRIXTRAIT SPECIALIZATIONS
6271 //
6272 //=================================================================================================
6273 
6274 //*************************************************************************************************
6276 template< typename T1, bool SO >
6277 struct SubmatrixTrait< DynamicMatrix<T1,SO> >
6278 {
6279  using Type = DynamicMatrix<T1,SO>;
6280 };
6282 //*************************************************************************************************
6283 
6284 
6285 
6286 
6287 //=================================================================================================
6288 //
6289 // ROWTRAIT SPECIALIZATIONS
6290 //
6291 //=================================================================================================
6292 
6293 //*************************************************************************************************
6295 template< typename T1, bool SO >
6296 struct RowTrait< DynamicMatrix<T1,SO> >
6297 {
6298  using Type = DynamicVector<T1,true>;
6299 };
6301 //*************************************************************************************************
6302 
6303 
6304 
6305 
6306 //=================================================================================================
6307 //
6308 // COLUMNTRAIT SPECIALIZATIONS
6309 //
6310 //=================================================================================================
6311 
6312 //*************************************************************************************************
6314 template< typename T1, bool SO >
6315 struct ColumnTrait< DynamicMatrix<T1,SO> >
6316 {
6317  using Type = DynamicVector<T1,false>;
6318 };
6320 //*************************************************************************************************
6321 
6322 } // namespace blaze
6323 
6324 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:133
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
size_t n_
The current number of columns of the matrix.
Definition: DynamicMatrix.h:461
Header file for auxiliary alias declarations.
BLAZE_ALWAYS_INLINE void storeu(size_t i, size_t j, const SIMDType &value) noexcept
Unaligned store of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2254
Header file for kernel specific block sizes.
Header file for mathematical functions.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
void reserve(size_t elements)
Setting the minimum capacity of the matrix.
Definition: DynamicMatrix.h:1791
#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
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: DynamicMatrix.h:2030
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:2155
Header file for the alignment flag values.
Header file for the UNUSED_PARAMETER function template.
Header file for the subtraction trait.
Header file for basic type definitions.
Header file for the row trait.
bool isIntact() const noexcept
Returns whether the invariants of the dynamic matrix are intact.
Definition: DynamicMatrix.h:1970
Type *BLAZE_RESTRICT v_
The dynamically allocated matrix elements.
Definition: DynamicMatrix.h:464
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:160
Header file for the IsSparseMatrix type trait.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DynamicMatrix.h:1509
DynamicMatrix & operator=(const Type &rhs)
Homogenous assignment to all matrix elements.
Definition: DynamicMatrix.h:1149
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: DynamicMatrix.h:1715
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:258
const CTransExprTrait_< MT > ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatForEachExpr.h:1195
constexpr size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
DynamicMatrix() noexcept
The default constructor for DynamicMatrix.
Definition: DynamicMatrix.h:502
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
Header file for the IsSame and IsStrictlySame type traits.
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const SIMDType &value) noexcept
Store of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2189
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:188
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:315
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: DynamicMatrix.h:2067
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2805
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
OutputIterator transfer(InputIterator first, InputIterator last, OutputIterator dest)
Transfers the elements from the given source range to the destination range.
Definition: Algorithm.h:71
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1669
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:590
#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
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:2120
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member constant is set to true, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to false, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:138
DenseMatrix< This, SO > BaseType
Base type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:208
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
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:203
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: DynamicMatrix.h:2048
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1716
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:129
BLAZE_ALWAYS_INLINE void stream(size_t i, size_t j, const SIMDType &value) noexcept
Aligned, non-temporal store of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2289
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
const This & CompositeType
Data type for composite expression templates.
Definition: DynamicMatrix.h:215
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:109
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Constraint on the data type.
size_t capacity_
The current capacity of the pointer array.
Definition: CompressedMatrix.h:2807
~DynamicMatrix()
The destructor for DynamicMatrix.
Definition: DynamicMatrix.h:806
This ResultType
Result type for expression template evaluations.
Definition: DynamicMatrix.h:209
Header file for the std::initializer_list aliases.
Header file for the SparseMatrix base class.
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: DynamicMatrix.h:1578
EnableIf_< IsBuiltin< T >, T * > allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:150
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: DynamicMatrix.h:222
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:143
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:143
DynamicMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: DynamicMatrix.h:1860
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5148
constexpr bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
Type ElementType
Type of the matrix elements.
Definition: DynamicMatrix.h:212
Header file for all forward declarations of the math module.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Header file for the IsSMPAssignable type trait.
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:76
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:98
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
DynamicMatrix< Type, SO > This
Type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:207
Header file for the HasSIMDAdd type trait.
Header file for the DenseMatrix base class.
Header file for the DenseIterator class template.
const Type & ReturnType
Return type for expression template evaluations.
Definition: DynamicMatrix.h:214
Header file for all SIMD functionality.
Constraint on the data type.
#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
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:330
void extend(size_t m, size_t n, bool preserve=true)
Extending the size of the matrix.
Definition: DynamicMatrix.h:1773
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:1628
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DynamicMatrix.h:1528
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
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:538
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:254
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
Headerfile for generic algorithms.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
Header file for the IsPadded type trait.
DynamicMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DynamicMatrix.h:210
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: DynamicMatrix.h:2010
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: DynamicMatrix.h:213
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:2218
Header file for the IsVectorizable type trait.
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: DynamicMatrix.h:934
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: DynamicMatrix.h:834
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
Header file for the HasConstDataAccess type trait.
size_t nn_
The alignment adjusted number of columns.
Definition: DynamicMatrix.h:462
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
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2092
Type * Pointer
Pointer to a non-constant matrix value.
Definition: DynamicMatrix.h:219
#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
size_t adjustColumns(size_t minColumns) const noexcept
Adjusting the number columns of the matrix according to its data type Type.
Definition: DynamicMatrix.h:1942
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determine the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:80
Header file for run time assertion macros.
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: DynamicMatrix.h:1015
Header file for the addition trait.
void clear()
Clearing the matrix.
Definition: DynamicMatrix.h:1672
const SIMDType load() const noexcept
Load of the SIMD element at the current iterator position.
Definition: DenseIterator.h:403
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: DynamicMatrix.h:220
Header file for the division trait.
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
Constraint on the data type.
size_t m_
The current number of rows of the matrix.
Definition: DynamicMatrix.h:460
Header file for the cache size of the target architecture.
#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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2646
Header file for the column trait.
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:258
System settings for the restrict keyword.
Header file for the TransExprTrait class template.
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:89
Constraint on the data type.
void swap(DynamicMatrix &m) noexcept
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:1923
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.
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:100
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:225
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
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
Header file for the mathematical trait.
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric< T >::value)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
Type & Reference
Reference to a non-constant matrix value.
Definition: DynamicMatrix.h:217
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2806
Header file for the AreSIMDCombinable type trait.
constexpr bool usePadding
Configuration of the padding of dense vectors and matrices.This configuration switch enables/disables...
Definition: Optimizations.h:52
DenseIterator< const Type, usePadding > ConstIterator
Iterator over constant elements.
Definition: DynamicMatrix.h:223
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: DynamicMatrix.h:1081
const DMatTransExpr< MT,!SO > trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:950
Initializer list type of the Blaze library.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DynamicMatrix.h:1495
Header file for the alignment check function.
typename InvExprTrait< T >::Type InvExprTrait_
Auxiliary alias declaration for the InvExprTrait class template.The InvExprTrait_ alias declaration p...
Definition: InvExprTrait.h:134
size_t capacity_
The maximum capacity of the matrix.
Definition: DynamicMatrix.h:463
Header file for the IntegralConstant class template.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:78
Rebind mechanism to obtain a DynamicMatrix with different data/element type.
Definition: DynamicMatrix.h:230
size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: DynamicMatrix.h:1542
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2654
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1303
Header file for the IsUpper type trait.
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: DynamicMatrix.h:1125
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the CTransExprTrait class template.
void store(const SIMDType &value) const noexcept
Store of the SIMD element at the current iterator position.
Definition: DenseIterator.h:468
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: DynamicMatrix.h:879
Header file for the IsResizable type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
DynamicMatrix< ET, SO > Other
The type of the other DynamicMatrix.
Definition: DynamicMatrix.h:231
DynamicMatrix & transpose()
In-place transpose of the matrix.
Definition: DynamicMatrix.h:1822
const Type & ConstReference
Reference to a constant matrix value.
Definition: DynamicMatrix.h:218
DynamicMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: DynamicMatrix.h:211
Header file for the TrueType type/value trait base class.
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:564
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: DynamicMatrix.h:1059
constexpr bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56