Blaze  3.6
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>
55 #include <blaze/math/shims/Clear.h>
59 #include <blaze/math/shims/Reset.h>
60 #include <blaze/math/SIMD.h>
102 #include <blaze/system/Blocking.h>
103 #include <blaze/system/CacheSize.h>
104 #include <blaze/system/Inline.h>
106 #include <blaze/system/Restrict.h>
108 #include <blaze/system/Thresholds.h>
114 #include <blaze/util/Assert.h>
120 #include <blaze/util/DisableIf.h>
121 #include <blaze/util/EnableIf.h>
123 #include <blaze/util/MaybeUnused.h>
124 #include <blaze/util/Memory.h>
125 #include <blaze/util/Types.h>
130 
131 
132 namespace blaze {
133 
134 //=================================================================================================
135 //
136 // CLASS DEFINITION
137 //
138 //=================================================================================================
139 
140 //*************************************************************************************************
219 template< typename Type // Data type of the matrix
220  , bool SO = defaultStorageOrder > // Storage order
222  : public DenseMatrix< DynamicMatrix<Type,SO>, SO >
223 {
224  public:
225  //**Type definitions****************************************************************************
228  using ResultType = This;
231  using ElementType = Type;
233  using ReturnType = const Type&;
234  using CompositeType = const This&;
235 
236  using Reference = Type&;
237  using ConstReference = const Type&;
238  using Pointer = Type*;
239  using ConstPointer = const Type*;
240 
243  //**********************************************************************************************
244 
245  //**Rebind struct definition********************************************************************
248  template< typename NewType > // Data type of the other matrix
249  struct Rebind {
251  };
252  //**********************************************************************************************
253 
254  //**Resize struct definition********************************************************************
257  template< size_t NewM // Number of rows of the other matrix
258  , size_t NewN > // Number of columns of the other matrix
259  struct Resize {
261  };
262  //**********************************************************************************************
263 
264  //**Compilation flags***************************************************************************
266 
270  static constexpr bool simdEnabled = IsVectorizable_v<Type>;
271 
273 
276  static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
277  //**********************************************************************************************
278 
279  //**Constructors********************************************************************************
282  explicit inline DynamicMatrix() noexcept;
283  explicit inline DynamicMatrix( size_t m, size_t n );
284  explicit inline DynamicMatrix( size_t m, size_t n, const Type& init );
285  inline DynamicMatrix( initializer_list< initializer_list<Type> > list );
286 
287  template< typename Other >
288  explicit inline DynamicMatrix( size_t m, size_t n, const Other* array );
289 
290  template< typename Other, size_t Rows, size_t Cols >
291  explicit inline DynamicMatrix( const Other (&array)[Rows][Cols] );
292 
293  inline DynamicMatrix( const DynamicMatrix& m );
294  inline DynamicMatrix( DynamicMatrix&& m ) noexcept;
295  template< typename MT, bool SO2 > inline DynamicMatrix( const Matrix<MT,SO2>& m );
297  //**********************************************************************************************
298 
299  //**Destructor**********************************************************************************
302  inline ~DynamicMatrix();
304  //**********************************************************************************************
305 
306  //**Data access functions***********************************************************************
309  inline Reference operator()( size_t i, size_t j ) noexcept;
310  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
311  inline Reference at( size_t i, size_t j );
312  inline ConstReference at( size_t i, size_t j ) const;
313  inline Pointer data () noexcept;
314  inline ConstPointer data () const noexcept;
315  inline Pointer data ( size_t i ) noexcept;
316  inline ConstPointer data ( size_t i ) const noexcept;
317  inline Iterator begin ( size_t i ) noexcept;
318  inline ConstIterator begin ( size_t i ) const noexcept;
319  inline ConstIterator cbegin( size_t i ) const noexcept;
320  inline Iterator end ( size_t i ) noexcept;
321  inline ConstIterator end ( size_t i ) const noexcept;
322  inline ConstIterator cend ( size_t i ) const noexcept;
324  //**********************************************************************************************
325 
326  //**Assignment operators************************************************************************
329  inline DynamicMatrix& operator=( const Type& rhs );
330  inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list );
331 
332  template< typename Other, size_t Rows, size_t Cols >
333  inline DynamicMatrix& operator=( const Other (&array)[Rows][Cols] );
334 
335  inline DynamicMatrix& operator=( const DynamicMatrix& rhs );
336  inline DynamicMatrix& operator=( DynamicMatrix&& rhs ) noexcept;
337 
338  template< typename MT, bool SO2 > inline DynamicMatrix& operator= ( const Matrix<MT,SO2>& rhs );
339  template< typename MT, bool SO2 > inline DynamicMatrix& operator+=( const Matrix<MT,SO2>& rhs );
340  template< typename MT, bool SO2 > inline DynamicMatrix& operator-=( const Matrix<MT,SO2>& rhs );
341  template< typename MT, bool SO2 > inline DynamicMatrix& operator%=( const Matrix<MT,SO2>& rhs );
343  //**********************************************************************************************
344 
345  //**Utility functions***************************************************************************
348  inline size_t rows() const noexcept;
349  inline size_t columns() const noexcept;
350  inline size_t spacing() const noexcept;
351  inline size_t capacity() const noexcept;
352  inline size_t capacity( size_t i ) const noexcept;
353  inline size_t nonZeros() const;
354  inline size_t nonZeros( size_t i ) const;
355  inline void reset();
356  inline void reset( size_t i );
357  inline void clear();
358  void resize ( size_t m, size_t n, bool preserve=true );
359  inline void extend ( size_t m, size_t n, bool preserve=true );
360  inline void reserve( size_t elements );
361  inline void shrinkToFit();
362  inline void swap( DynamicMatrix& m ) noexcept;
364  //**********************************************************************************************
365 
366  //**Numeric functions***************************************************************************
369  inline DynamicMatrix& transpose();
370  inline DynamicMatrix& ctranspose();
371 
372  template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
374  //**********************************************************************************************
375 
376  private:
377  //**********************************************************************************************
379  template< typename MT >
381  static constexpr bool VectorizedAssign_v =
382  ( useOptimizedKernels &&
383  simdEnabled && MT::simdEnabled &&
384  IsSIMDCombinable_v< Type, ElementType_t<MT> > );
386  //**********************************************************************************************
387 
388  //**********************************************************************************************
390  template< typename MT >
392  static constexpr bool VectorizedAddAssign_v =
393  ( useOptimizedKernels &&
394  simdEnabled && MT::simdEnabled &&
395  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
396  HasSIMDAdd_v< Type, ElementType_t<MT> > &&
397  !IsDiagonal_v<MT> );
399  //**********************************************************************************************
400 
401  //**********************************************************************************************
403  template< typename MT >
405  static constexpr bool VectorizedSubAssign_v =
406  ( useOptimizedKernels &&
407  simdEnabled && MT::simdEnabled &&
408  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
409  HasSIMDSub_v< Type, ElementType_t<MT> > &&
410  !IsDiagonal_v<MT> );
412  //**********************************************************************************************
413 
414  //**********************************************************************************************
416  template< typename MT >
418  static constexpr bool VectorizedSchurAssign_v =
419  ( useOptimizedKernels &&
420  simdEnabled && MT::simdEnabled &&
421  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
422  HasSIMDMult_v< Type, ElementType_t<MT> > );
424  //**********************************************************************************************
425 
426  //**********************************************************************************************
428  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
429  //**********************************************************************************************
430 
431  public:
432  //**Debugging functions*************************************************************************
435  inline bool isIntact() const noexcept;
437  //**********************************************************************************************
438 
439  //**Expression template evaluation functions****************************************************
442  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
443  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
444 
445  inline bool isAligned () const noexcept;
446  inline bool canSMPAssign() const noexcept;
447 
448  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
449  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
450  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
451 
452  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
453  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
454  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
455  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
456 
457  template< typename MT >
458  inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
459 
460  template< typename MT >
461  inline auto assign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
462 
463  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
464  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
465  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
466 
467  template< typename MT >
468  inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
469 
470  template< typename MT >
471  inline auto addAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
472 
473  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
474  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
475  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
476 
477  template< typename MT >
478  inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
479 
480  template< typename MT >
481  inline auto subAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
482 
483  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
484  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
485  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
486 
487  template< typename MT >
488  inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
489 
490  template< typename MT >
491  inline auto schurAssign( const DenseMatrix<MT,SO>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
492 
493  template< typename MT > inline void schurAssign( const DenseMatrix<MT,!SO>& rhs );
494  template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
495  template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
497  //**********************************************************************************************
498 
499  private:
500  //**Utility functions***************************************************************************
503  inline size_t addPadding( size_t value ) const noexcept;
505  //**********************************************************************************************
506 
507  //**Member variables****************************************************************************
510  size_t m_;
511  size_t n_;
512  size_t nn_;
513  size_t capacity_;
515 
525  //**********************************************************************************************
526 
527  //**Compile time checks*************************************************************************
534  //**********************************************************************************************
535 };
536 //*************************************************************************************************
537 
538 
539 
540 
541 //=================================================================================================
542 //
543 // CONSTRUCTORS
544 //
545 //=================================================================================================
546 
547 //*************************************************************************************************
550 template< typename Type // Data type of the matrix
551  , bool SO > // Storage order
552 inline DynamicMatrix<Type,SO>::DynamicMatrix() noexcept
553  : m_ ( 0UL ) // The current number of rows of the matrix
554  , n_ ( 0UL ) // The current number of columns of the matrix
555  , nn_ ( 0UL ) // The alignment adjusted number of columns
556  , capacity_( 0UL ) // The maximum capacity of the matrix
557  , v_ ( nullptr ) // The matrix elements
558 {}
559 //*************************************************************************************************
560 
561 
562 //*************************************************************************************************
571 template< typename Type // Data type of the matrix
572  , bool SO > // Storage order
573 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n )
574  : m_ ( m ) // The current number of rows of the matrix
575  , n_ ( n ) // The current number of columns of the matrix
576  , nn_ ( addPadding( n ) ) // The alignment adjusted number of columns
577  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
578  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
579 {
580  if( IsVectorizable_v<Type> ) {
581  for( size_t i=0UL; i<m_; ++i ) {
582  for( size_t j=n_; j<nn_; ++j ) {
583  v_[i*nn_+j] = Type();
584  }
585  }
586  }
587 
588  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
589 }
590 //*************************************************************************************************
591 
592 
593 //*************************************************************************************************
602 template< typename Type // Data type of the matrix
603  , bool SO > // Storage order
604 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, const Type& init )
605  : DynamicMatrix( m, n )
606 {
607  for( size_t i=0UL; i<m; ++i ) {
608  for( size_t j=0UL; j<n_; ++j ) {
609  v_[i*nn_+j] = init;
610  }
611  }
612 
613  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
614 }
615 //*************************************************************************************************
616 
617 
618 //*************************************************************************************************
638 template< typename Type // Data type of the matrix
639  , bool SO > // Storage order
641  : DynamicMatrix( list.size(), determineColumns( list ) )
642 {
643  size_t i( 0UL );
644 
645  for( const auto& rowList : list ) {
646  std::fill( std::copy( rowList.begin(), rowList.end(), begin(i) ), end(i), Type() );
647  ++i;
648  }
649 
650  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
651 }
652 //*************************************************************************************************
653 
654 
655 //*************************************************************************************************
678 template< typename Type // Data type of the matrix
679  , bool SO > // Storage order
680 template< typename Other > // Data type of the initialization array
681 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, const Other* array )
682  : DynamicMatrix( m, n )
683 {
684  for( size_t i=0UL; i<m; ++i ) {
685  for( size_t j=0UL; j<n; ++j ) {
686  v_[i*nn_+j] = array[i*n+j];
687  }
688  }
689 
690  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
691 }
692 //*************************************************************************************************
693 
694 
695 //*************************************************************************************************
716 template< typename Type // Data type of the matrix
717  , bool SO > // Storage order
718 template< typename Other // Data type of the initialization array
719  , size_t Rows // Number of rows of the initialization array
720  , size_t Cols > // Number of columns of the initialization array
721 inline DynamicMatrix<Type,SO>::DynamicMatrix( const Other (&array)[Rows][Cols] )
722  : DynamicMatrix( Rows, Cols )
723 {
724  for( size_t i=0UL; i<Rows; ++i ) {
725  for( size_t j=0UL; j<Cols; ++j ) {
726  v_[i*nn_+j] = array[i][j];
727  }
728  }
729 
730  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
731 }
732 //*************************************************************************************************
733 
734 
735 //*************************************************************************************************
743 template< typename Type // Data type of the matrix
744  , bool SO > // Storage order
746  : DynamicMatrix( m.m_, m.n_ )
747 {
748  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
749 
750  smpAssign( *this, m );
751 
752  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
753 }
754 //*************************************************************************************************
755 
756 
757 //*************************************************************************************************
762 template< typename Type // Data type of the matrix
763  , bool SO > // Storage order
765  : m_ ( m.m_ ) // The current number of rows of the matrix
766  , n_ ( m.n_ ) // The current number of columns of the matrix
767  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
768  , capacity_( m.capacity_ ) // The maximum capacity of the matrix
769  , v_ ( m.v_ ) // The matrix elements
770 {
771  m.m_ = 0UL;
772  m.n_ = 0UL;
773  m.nn_ = 0UL;
774  m.capacity_ = 0UL;
775  m.v_ = nullptr;
776 }
777 //*************************************************************************************************
778 
779 
780 //*************************************************************************************************
785 template< typename Type // Data type of the matrix
786  , bool SO > // Storage order
787 template< typename MT // Type of the foreign matrix
788  , bool SO2 > // Storage order of the foreign matrix
790  : DynamicMatrix( (~m).rows(), (~m).columns() )
791 {
792  if( IsSparseMatrix_v<MT> ) {
793  reset();
794  }
795 
796  smpAssign( *this, ~m );
797 
798  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
799 }
800 //*************************************************************************************************
801 
802 
803 
804 
805 //=================================================================================================
806 //
807 // DESTRUCTOR
808 //
809 //=================================================================================================
810 
811 //*************************************************************************************************
814 template< typename Type // Data type of the matrix
815  , bool SO > // Storage order
817 {
818  deallocate( v_ );
819 }
820 //*************************************************************************************************
821 
822 
823 
824 
825 //=================================================================================================
826 //
827 // DATA ACCESS FUNCTIONS
828 //
829 //=================================================================================================
830 
831 //*************************************************************************************************
841 template< typename Type // Data type of the matrix
842  , bool SO > // Storage order
843 inline typename DynamicMatrix<Type,SO>::Reference
844  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) noexcept
845 {
846  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
847  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
848  return v_[i*nn_+j];
849 }
850 //*************************************************************************************************
851 
852 
853 //*************************************************************************************************
863 template< typename Type // Data type of the matrix
864  , bool SO > // Storage order
866  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) const noexcept
867 {
868  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
869  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
870  return v_[i*nn_+j];
871 }
872 //*************************************************************************************************
873 
874 
875 //*************************************************************************************************
886 template< typename Type // Data type of the matrix
887  , bool SO > // Storage order
888 inline typename DynamicMatrix<Type,SO>::Reference
889  DynamicMatrix<Type,SO>::at( size_t i, size_t j )
890 {
891  if( i >= m_ ) {
892  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
893  }
894  if( j >= n_ ) {
895  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
896  }
897  return (*this)(i,j);
898 }
899 //*************************************************************************************************
900 
901 
902 //*************************************************************************************************
913 template< typename Type // Data type of the matrix
914  , bool SO > // Storage order
916  DynamicMatrix<Type,SO>::at( size_t i, size_t j ) const
917 {
918  if( i >= m_ ) {
919  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
920  }
921  if( j >= n_ ) {
922  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
923  }
924  return (*this)(i,j);
925 }
926 //*************************************************************************************************
927 
928 
929 //*************************************************************************************************
941 template< typename Type // Data type of the matrix
942  , bool SO > // Storage order
943 inline typename DynamicMatrix<Type,SO>::Pointer
945 {
946  return v_;
947 }
948 //*************************************************************************************************
949 
950 
951 //*************************************************************************************************
963 template< typename Type // Data type of the matrix
964  , bool SO > // Storage order
967 {
968  return v_;
969 }
970 //*************************************************************************************************
971 
972 
973 //*************************************************************************************************
981 template< typename Type // Data type of the matrix
982  , bool SO > // Storage order
983 inline typename DynamicMatrix<Type,SO>::Pointer
984  DynamicMatrix<Type,SO>::data( size_t i ) noexcept
985 {
986  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
987  return v_ + i*nn_;
988 }
989 //*************************************************************************************************
990 
991 
992 //*************************************************************************************************
1000 template< typename Type // Data type of the matrix
1001  , bool SO > // Storage order
1003  DynamicMatrix<Type,SO>::data( size_t i ) const noexcept
1004 {
1005  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1006  return v_ + i*nn_;
1007 }
1008 //*************************************************************************************************
1009 
1010 
1011 //*************************************************************************************************
1022 template< typename Type // Data type of the matrix
1023  , bool SO > // Storage order
1024 inline typename DynamicMatrix<Type,SO>::Iterator
1025  DynamicMatrix<Type,SO>::begin( size_t i ) noexcept
1026 {
1027  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1028  return Iterator( v_ + i*nn_ );
1029 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1044 template< typename Type // Data type of the matrix
1045  , bool SO > // Storage order
1047  DynamicMatrix<Type,SO>::begin( size_t i ) const noexcept
1048 {
1049  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1050  return ConstIterator( v_ + i*nn_ );
1051 }
1052 //*************************************************************************************************
1053 
1054 
1055 //*************************************************************************************************
1066 template< typename Type // Data type of the matrix
1067  , bool SO > // Storage order
1069  DynamicMatrix<Type,SO>::cbegin( size_t i ) const noexcept
1070 {
1071  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1072  return ConstIterator( v_ + i*nn_ );
1073 }
1074 //*************************************************************************************************
1075 
1076 
1077 //*************************************************************************************************
1088 template< typename Type // Data type of the matrix
1089  , bool SO > // Storage order
1090 inline typename DynamicMatrix<Type,SO>::Iterator
1091  DynamicMatrix<Type,SO>::end( size_t i ) noexcept
1092 {
1093  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1094  return Iterator( v_ + i*nn_ + n_ );
1095 }
1096 //*************************************************************************************************
1097 
1098 
1099 //*************************************************************************************************
1110 template< typename Type // Data type of the matrix
1111  , bool SO > // Storage order
1113  DynamicMatrix<Type,SO>::end( size_t i ) const noexcept
1114 {
1115  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1116  return ConstIterator( v_ + i*nn_ + n_ );
1117 }
1118 //*************************************************************************************************
1119 
1120 
1121 //*************************************************************************************************
1132 template< typename Type // Data type of the matrix
1133  , bool SO > // Storage order
1135  DynamicMatrix<Type,SO>::cend( size_t i ) const noexcept
1136 {
1137  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
1138  return ConstIterator( v_ + i*nn_ + n_ );
1139 }
1140 //*************************************************************************************************
1141 
1142 
1143 
1144 
1145 //=================================================================================================
1146 //
1147 // ASSIGNMENT OPERATORS
1148 //
1149 //=================================================================================================
1150 
1151 //*************************************************************************************************
1157 template< typename Type // Data type of the matrix
1158  , bool SO > // Storage order
1160 {
1161  for( size_t i=0UL; i<m_; ++i )
1162  for( size_t j=0UL; j<n_; ++j )
1163  v_[i*nn_+j] = rhs;
1164 
1165  return *this;
1166 }
1167 //*************************************************************************************************
1168 
1169 
1170 //*************************************************************************************************
1191 template< typename Type // Data type of the matrix
1192  , bool SO > // Storage order
1193 inline DynamicMatrix<Type,SO>&
1195 {
1196  resize( list.size(), determineColumns( list ), false );
1197 
1198  size_t i( 0UL );
1199 
1200  for( const auto& rowList : list ) {
1201  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*nn_ ), v_+(i+1UL)*nn_, Type() );
1202  ++i;
1203  }
1204 
1205  return *this;
1206 }
1207 //*************************************************************************************************
1208 
1209 
1210 //*************************************************************************************************
1231 template< typename Type // Data type of the matrix
1232  , bool SO > // Storage order
1233 template< typename Other // Data type of the initialization array
1234  , size_t Rows // Number of rows of the initialization array
1235  , size_t Cols > // Number of columns of the initialization array
1236 inline DynamicMatrix<Type,SO>& DynamicMatrix<Type,SO>::operator=( const Other (&array)[Rows][Cols] )
1237 {
1238  resize( Rows, Cols, false );
1239 
1240  for( size_t i=0UL; i<Rows; ++i )
1241  for( size_t j=0UL; j<Cols; ++j )
1242  v_[i*nn_+j] = array[i][j];
1243 
1244  return *this;
1245 }
1246 //*************************************************************************************************
1247 
1248 
1249 //*************************************************************************************************
1258 template< typename Type // Data type of the matrix
1259  , bool SO > // Storage order
1261 {
1262  if( &rhs == this ) return *this;
1263 
1264  resize( rhs.m_, rhs.n_, false );
1265  smpAssign( *this, ~rhs );
1266 
1267  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1268 
1269  return *this;
1270 }
1271 //*************************************************************************************************
1272 
1273 
1274 //*************************************************************************************************
1280 template< typename Type // Data type of the matrix
1281  , bool SO > // Storage order
1283 {
1284  deallocate( v_ );
1285 
1286  m_ = rhs.m_;
1287  n_ = rhs.n_;
1288  nn_ = rhs.nn_;
1289  capacity_ = rhs.capacity_;
1290  v_ = rhs.v_;
1291 
1292  rhs.m_ = 0UL;
1293  rhs.n_ = 0UL;
1294  rhs.nn_ = 0UL;
1295  rhs.capacity_ = 0UL;
1296  rhs.v_ = nullptr;
1297 
1298  return *this;
1299 }
1300 //*************************************************************************************************
1301 
1302 
1303 //*************************************************************************************************
1312 template< typename Type // Data type of the matrix
1313  , bool SO > // Storage order
1314 template< typename MT // Type of the right-hand side matrix
1315  , bool SO2 > // Storage order of the right-hand side matrix
1317 {
1318  using TT = decltype( trans( *this ) );
1319  using CT = decltype( ctrans( *this ) );
1320  using IT = decltype( inv( *this ) );
1321 
1322  if( IsSame_v<MT,TT> && (~rhs).isAliased( this ) ) {
1323  transpose();
1324  }
1325  else if( IsSame_v<MT,CT> && (~rhs).isAliased( this ) ) {
1326  ctranspose();
1327  }
1328  else if( !IsSame_v<MT,IT> && (~rhs).canAlias( this ) ) {
1329  DynamicMatrix tmp( ~rhs );
1330  swap( tmp );
1331  }
1332  else {
1333  resize( (~rhs).rows(), (~rhs).columns(), false );
1334  if( IsSparseMatrix_v<MT> )
1335  reset();
1336  smpAssign( *this, ~rhs );
1337  }
1338 
1339  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1340 
1341  return *this;
1342 }
1343 //*************************************************************************************************
1344 
1345 
1346 //*************************************************************************************************
1356 template< typename Type // Data type of the matrix
1357  , bool SO > // Storage order
1358 template< typename MT // Type of the right-hand side matrix
1359  , bool SO2 > // Storage order of the right-hand side matrix
1361 {
1362  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1363  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1364  }
1365 
1366  if( (~rhs).canAlias( this ) ) {
1367  const ResultType_t<MT> tmp( ~rhs );
1368  smpAddAssign( *this, tmp );
1369  }
1370  else {
1371  smpAddAssign( *this, ~rhs );
1372  }
1373 
1374  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1375 
1376  return *this;
1377 }
1378 //*************************************************************************************************
1379 
1380 
1381 //*************************************************************************************************
1391 template< typename Type // Data type of the matrix
1392  , bool SO > // Storage order
1393 template< typename MT // Type of the right-hand side matrix
1394  , bool SO2 > // Storage order of the right-hand side matrix
1396 {
1397  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1398  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1399  }
1400 
1401  if( (~rhs).canAlias( this ) ) {
1402  const ResultType_t<MT> tmp( ~rhs );
1403  smpSubAssign( *this, tmp );
1404  }
1405  else {
1406  smpSubAssign( *this, ~rhs );
1407  }
1408 
1409  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1410 
1411  return *this;
1412 }
1413 //*************************************************************************************************
1414 
1415 
1416 //*************************************************************************************************
1426 template< typename Type // Data type of the matrix
1427  , bool SO > // Storage order
1428 template< typename MT // Type of the right-hand side matrix
1429  , bool SO2 > // Storage order of the right-hand side matrix
1431 {
1432  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1433  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1434  }
1435 
1436  if( (~rhs).canAlias( this ) ) {
1437  const ResultType_t<MT> tmp( ~rhs );
1438  smpSchurAssign( *this, tmp );
1439  }
1440  else {
1441  smpSchurAssign( *this, ~rhs );
1442  }
1443 
1444  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1445 
1446  return *this;
1447 }
1448 //*************************************************************************************************
1449 
1450 
1451 
1452 
1453 //=================================================================================================
1454 //
1455 // UTILITY FUNCTIONS
1456 //
1457 //=================================================================================================
1458 
1459 //*************************************************************************************************
1464 template< typename Type // Data type of the matrix
1465  , bool SO > // Storage order
1466 inline size_t DynamicMatrix<Type,SO>::rows() const noexcept
1467 {
1468  return m_;
1469 }
1470 //*************************************************************************************************
1471 
1472 
1473 //*************************************************************************************************
1478 template< typename Type // Data type of the matrix
1479  , bool SO > // Storage order
1480 inline size_t DynamicMatrix<Type,SO>::columns() const noexcept
1481 {
1482  return n_;
1483 }
1484 //*************************************************************************************************
1485 
1486 
1487 //*************************************************************************************************
1497 template< typename Type // Data type of the matrix
1498  , bool SO > // Storage order
1499 inline size_t DynamicMatrix<Type,SO>::spacing() const noexcept
1500 {
1501  return nn_;
1502 }
1503 //*************************************************************************************************
1504 
1505 
1506 //*************************************************************************************************
1511 template< typename Type // Data type of the matrix
1512  , bool SO > // Storage order
1513 inline size_t DynamicMatrix<Type,SO>::capacity() const noexcept
1514 {
1515  return capacity_;
1516 }
1517 //*************************************************************************************************
1518 
1519 
1520 //*************************************************************************************************
1531 template< typename Type // Data type of the matrix
1532  , bool SO > // Storage order
1533 inline size_t DynamicMatrix<Type,SO>::capacity( size_t i ) const noexcept
1534 {
1535  MAYBE_UNUSED( i );
1536  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1537  return nn_;
1538 }
1539 //*************************************************************************************************
1540 
1541 
1542 //*************************************************************************************************
1547 template< typename Type // Data type of the matrix
1548  , bool SO > // Storage order
1550 {
1551  size_t nonzeros( 0UL );
1552 
1553  for( size_t i=0UL; i<m_; ++i )
1554  for( size_t j=0UL; j<n_; ++j )
1555  if( !isDefault( v_[i*nn_+j] ) )
1556  ++nonzeros;
1557 
1558  return nonzeros;
1559 }
1560 //*************************************************************************************************
1561 
1562 
1563 //*************************************************************************************************
1574 template< typename Type // Data type of the matrix
1575  , bool SO > // Storage order
1576 inline size_t DynamicMatrix<Type,SO>::nonZeros( size_t i ) const
1577 {
1578  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1579 
1580  const size_t jend( i*nn_ + n_ );
1581  size_t nonzeros( 0UL );
1582 
1583  for( size_t j=i*nn_; j<jend; ++j )
1584  if( !isDefault( v_[j] ) )
1585  ++nonzeros;
1586 
1587  return nonzeros;
1588 }
1589 //*************************************************************************************************
1590 
1591 
1592 //*************************************************************************************************
1597 template< typename Type // Data type of the matrix
1598  , bool SO > // Storage order
1600 {
1601  using blaze::clear;
1602 
1603  for( size_t i=0UL; i<m_; ++i )
1604  for( size_t j=0UL; j<n_; ++j )
1605  clear( v_[i*nn_+j] );
1606 }
1607 //*************************************************************************************************
1608 
1609 
1610 //*************************************************************************************************
1621 template< typename Type // Data type of the matrix
1622  , bool SO > // Storage order
1623 inline void DynamicMatrix<Type,SO>::reset( size_t i )
1624 {
1625  using blaze::clear;
1626 
1627  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1628  for( size_t j=0UL; j<n_; ++j )
1629  clear( v_[i*nn_+j] );
1630 }
1631 //*************************************************************************************************
1632 
1633 
1634 //*************************************************************************************************
1641 template< typename Type // Data type of the matrix
1642  , bool SO > // Storage order
1644 {
1645  resize( 0UL, 0UL, false );
1646 }
1647 //*************************************************************************************************
1648 
1649 
1650 //*************************************************************************************************
1684 template< typename Type // Data type of the matrix
1685  , bool SO > // Storage order
1686 void DynamicMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1687 {
1688  using std::swap;
1689  using blaze::min;
1690 
1691  if( m == m_ && n == n_ ) return;
1692 
1693  const size_t nn( addPadding( n ) );
1694 
1695  if( preserve )
1696  {
1697  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1698  const size_t min_m( min( m, m_ ) );
1699  const size_t min_n( min( n, n_ ) );
1700 
1701  for( size_t i=0UL; i<min_m; ++i ) {
1702  transfer( v_+i*nn_, v_+i*nn_+min_n, v+i*nn );
1703  }
1704 
1705  swap( v_, v );
1706  deallocate( v );
1707  capacity_ = m*nn;
1708  }
1709  else if( m*nn > capacity_ ) {
1710  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1711  swap( v_, v );
1712  deallocate( v );
1713  capacity_ = m*nn;
1714  }
1715 
1716  if( IsVectorizable_v<Type> ) {
1717  for( size_t i=0UL; i<m; ++i )
1718  for( size_t j=n; j<nn; ++j )
1719  v_[i*nn+j] = Type();
1720  }
1721 
1722  m_ = m;
1723  n_ = n;
1724  nn_ = nn;
1725 }
1726 //*************************************************************************************************
1727 
1728 
1729 //*************************************************************************************************
1743 template< typename Type // Data type of the matrix
1744  , bool SO > // Storage order
1745 inline void DynamicMatrix<Type,SO>::extend( size_t m, size_t n, bool preserve )
1746 {
1747  resize( m_+m, n_+n, preserve );
1748 }
1749 //*************************************************************************************************
1750 
1751 
1752 //*************************************************************************************************
1761 template< typename Type // Data type of the matrix
1762  , bool SO > // Storage order
1764 {
1765  using std::swap;
1766 
1767  if( elements > capacity_ )
1768  {
1769  // Allocating a new array
1770  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
1771 
1772  // Initializing the new array
1773  transfer( v_, v_+capacity_, tmp );
1774 
1775  if( IsVectorizable_v<Type> ) {
1776  for( size_t i=capacity_; i<elements; ++i )
1777  tmp[i] = Type();
1778  }
1779 
1780  // Replacing the old array
1781  swap( tmp, v_ );
1782  deallocate( tmp );
1783  capacity_ = elements;
1784  }
1785 }
1786 //*************************************************************************************************
1787 
1788 
1789 //*************************************************************************************************
1799 template< typename Type // Data type of the matrix
1800  , bool SO > // Storage order
1802 {
1803  if( ( m_ * nn_ ) < capacity_ ) {
1804  DynamicMatrix( *this ).swap( *this );
1805  }
1806 }
1807 //*************************************************************************************************
1808 
1809 
1810 //*************************************************************************************************
1816 template< typename Type // Data type of the matrix
1817  , bool SO > // Storage order
1819 {
1820  using std::swap;
1821 
1822  swap( m_ , m.m_ );
1823  swap( n_ , m.n_ );
1824  swap( nn_, m.nn_ );
1825  swap( capacity_, m.capacity_ );
1826  swap( v_ , m.v_ );
1827 }
1828 //*************************************************************************************************
1829 
1830 
1831 //*************************************************************************************************
1840 template< typename Type // Data type of the matrix
1841  , bool SO > // Storage order
1842 inline size_t DynamicMatrix<Type,SO>::addPadding( size_t value ) const noexcept
1843 {
1844  if( usePadding && IsVectorizable_v<Type> )
1845  return nextMultiple<size_t>( value, SIMDSIZE );
1846  else return value;
1847 }
1848 //*************************************************************************************************
1849 
1850 
1851 
1852 
1853 //=================================================================================================
1854 //
1855 // NUMERIC FUNCTIONS
1856 //
1857 //=================================================================================================
1858 
1859 //*************************************************************************************************
1864 template< typename Type // Data type of the matrix
1865  , bool SO > // Storage order
1867 {
1868  using std::swap;
1869 
1870  constexpr size_t block( BLOCK_SIZE );
1871 
1872  if( m_ == n_ )
1873  {
1874  for( size_t ii=0UL; ii<m_; ii+=block ) {
1875  const size_t iend( min( ii+block, m_ ) );
1876  for( size_t jj=0UL; jj<=ii; jj+=block ) {
1877  for( size_t i=ii; i<iend; ++i ) {
1878  const size_t jend( min( jj+block, n_, i ) );
1879  for( size_t j=jj; j<jend; ++j ) {
1880  swap( v_[i*nn_+j], v_[j*nn_+i] );
1881  }
1882  }
1883  }
1884  }
1885  }
1886  else
1887  {
1888  DynamicMatrix tmp( trans(*this) );
1889  this->swap( tmp );
1890  }
1891 
1892  return *this;
1893 }
1894 //*************************************************************************************************
1895 
1896 
1897 //*************************************************************************************************
1902 template< typename Type // Data type of the matrix
1903  , bool SO > // Storage order
1905 {
1906  constexpr size_t block( BLOCK_SIZE );
1907 
1908  if( m_ == n_ )
1909  {
1910  for( size_t ii=0UL; ii<m_; ii+=block ) {
1911  const size_t iend( min( ii+block, m_ ) );
1912  for( size_t jj=0UL; jj<ii; jj+=block ) {
1913  const size_t jend( min( jj+block, n_ ) );
1914  for( size_t i=ii; i<iend; ++i ) {
1915  for( size_t j=jj; j<jend; ++j ) {
1916  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1917  }
1918  }
1919  }
1920  for( size_t i=ii; i<iend; ++i ) {
1921  for( size_t j=ii; j<i; ++j ) {
1922  cswap( v_[i*nn_+j], v_[j*nn_+i] );
1923  }
1924  conjugate( v_[i*nn_+i] );
1925  }
1926  }
1927  }
1928  else
1929  {
1930  DynamicMatrix tmp( ctrans(*this) );
1931  swap( tmp );
1932  }
1933 
1934  return *this;
1935 }
1936 //*************************************************************************************************
1937 
1938 
1939 //*************************************************************************************************
1956 template< typename Type // Data type of the matrix
1957  , bool SO > // Storage order
1958 template< typename Other > // Data type of the scalar value
1960 {
1961  for( size_t i=0UL; i<m_; ++i )
1962  for( size_t j=0UL; j<n_; ++j )
1963  v_[i*nn_+j] *= scalar;
1964 
1965  return *this;
1966 }
1967 //*************************************************************************************************
1968 
1969 
1970 
1971 
1972 //=================================================================================================
1973 //
1974 // DEBUGGING FUNCTIONS
1975 //
1976 //=================================================================================================
1977 
1978 //*************************************************************************************************
1987 template< typename Type // Data type of the matrix
1988  , bool SO > // Storage order
1989 inline bool DynamicMatrix<Type,SO>::isIntact() const noexcept
1990 {
1991  if( m_ * n_ > capacity_ )
1992  return false;
1993 
1994  if( IsVectorizable_v<Type> ) {
1995  for( size_t i=0UL; i<m_; ++i ) {
1996  for( size_t j=n_; j<nn_; ++j ) {
1997  if( v_[i*nn_+j] != Type() )
1998  return false;
1999  }
2000  }
2001  }
2002 
2003  return true;
2004 }
2005 //*************************************************************************************************
2006 
2007 
2008 
2009 
2010 //=================================================================================================
2011 //
2012 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2013 //
2014 //=================================================================================================
2015 
2016 //*************************************************************************************************
2026 template< typename Type // Data type of the matrix
2027  , bool SO > // Storage order
2028 template< typename Other > // Data type of the foreign expression
2029 inline bool DynamicMatrix<Type,SO>::canAlias( const Other* alias ) const noexcept
2030 {
2031  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2032 }
2033 //*************************************************************************************************
2034 
2035 
2036 //*************************************************************************************************
2046 template< typename Type // Data type of the matrix
2047  , bool SO > // Storage order
2048 template< typename Other > // Data type of the foreign expression
2049 inline bool DynamicMatrix<Type,SO>::isAliased( const Other* alias ) const noexcept
2050 {
2051  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2052 }
2053 //*************************************************************************************************
2054 
2055 
2056 //*************************************************************************************************
2065 template< typename Type // Data type of the matrix
2066  , bool SO > // Storage order
2067 inline bool DynamicMatrix<Type,SO>::isAligned() const noexcept
2068 {
2069  return ( usePadding || columns() % SIMDSIZE == 0UL );
2070 }
2071 //*************************************************************************************************
2072 
2073 
2074 //*************************************************************************************************
2084 template< typename Type // Data type of the matrix
2085  , bool SO > // Storage order
2086 inline bool DynamicMatrix<Type,SO>::canSMPAssign() const noexcept
2087 {
2088  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
2089 }
2090 //*************************************************************************************************
2091 
2092 
2093 //*************************************************************************************************
2108 template< typename Type // Data type of the matrix
2109  , bool SO > // Storage order
2111  DynamicMatrix<Type,SO>::load( size_t i, size_t j ) const noexcept
2112 {
2113  if( usePadding )
2114  return loada( i, j );
2115  else
2116  return loadu( i, j );
2117 }
2118 //*************************************************************************************************
2119 
2120 
2121 //*************************************************************************************************
2136 template< typename Type // Data type of the matrix
2137  , bool SO > // Storage order
2139  DynamicMatrix<Type,SO>::loada( size_t i, size_t j ) const noexcept
2140 {
2141  using blaze::loada;
2142 
2144 
2145  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2146  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2147  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2148  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2149  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2150 
2151  return loada( v_+i*nn_+j );
2152 }
2153 //*************************************************************************************************
2154 
2155 
2156 //*************************************************************************************************
2171 template< typename Type // Data type of the matrix
2172  , bool SO > // Storage order
2174  DynamicMatrix<Type,SO>::loadu( size_t i, size_t j ) const noexcept
2175 {
2176  using blaze::loadu;
2177 
2179 
2180  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2181  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2182  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2183 
2184  return loadu( v_+i*nn_+j );
2185 }
2186 //*************************************************************************************************
2187 
2188 
2189 //*************************************************************************************************
2205 template< typename Type // Data type of the matrix
2206  , bool SO > // Storage order
2208  DynamicMatrix<Type,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2209 {
2210  if( usePadding )
2211  storea( i, j, value );
2212  else
2213  storeu( i, j, value );
2214 }
2215 //*************************************************************************************************
2216 
2217 
2218 //*************************************************************************************************
2234 template< typename Type // Data type of the matrix
2235  , bool SO > // Storage order
2237  DynamicMatrix<Type,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2238 {
2239  using blaze::storea;
2240 
2242 
2243  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2244  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2245  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2246  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2247  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2248 
2249  storea( v_+i*nn_+j, value );
2250 }
2251 //*************************************************************************************************
2252 
2253 
2254 //*************************************************************************************************
2270 template< typename Type // Data type of the matrix
2271  , bool SO > // Storage order
2273  DynamicMatrix<Type,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2274 {
2275  using blaze::storeu;
2276 
2278 
2279  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2280  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2281  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2282 
2283  storeu( v_+i*nn_+j, value );
2284 }
2285 //*************************************************************************************************
2286 
2287 
2288 //*************************************************************************************************
2305 template< typename Type // Data type of the matrix
2306  , bool SO > // Storage order
2308  DynamicMatrix<Type,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2309 {
2310  using blaze::stream;
2311 
2313 
2314  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2315  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2316  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= nn_, "Invalid column access index" );
2317  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2318  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i*nn_+j ), "Invalid alignment detected" );
2319 
2320  stream( v_+i*nn_+j, value );
2321 }
2322 //*************************************************************************************************
2323 
2324 
2325 //*************************************************************************************************
2336 template< typename Type // Data type of the matrix
2337  , bool SO > // Storage order
2338 template< typename MT > // Type of the right-hand side dense matrix
2341 {
2342  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2343  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2344 
2345  const size_t jpos( n_ & size_t(-2) );
2346  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2347 
2348  for( size_t i=0UL; i<m_; ++i ) {
2349  for( size_t j=0UL; j<jpos; j+=2UL ) {
2350  v_[i*nn_+j ] = (~rhs)(i,j );
2351  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
2352  }
2353  if( jpos < n_ ) {
2354  v_[i*nn_+jpos] = (~rhs)(i,jpos);
2355  }
2356  }
2357 }
2358 //*************************************************************************************************
2359 
2360 
2361 //*************************************************************************************************
2372 template< typename Type // Data type of the matrix
2373  , bool SO > // Storage order
2374 template< typename MT > // Type of the right-hand side dense matrix
2375 inline auto DynamicMatrix<Type,SO>::assign( const DenseMatrix<MT,SO>& rhs )
2377 {
2379 
2380  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2381  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2382 
2383  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2384 
2385  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2386  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2387 
2388  if( usePadding && useStreaming &&
2389  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
2390  {
2391  for( size_t i=0UL; i<m_; ++i )
2392  {
2393  size_t j( 0UL );
2394  Iterator left( begin(i) );
2395  ConstIterator_t<MT> right( (~rhs).begin(i) );
2396 
2397  for( ; j<jpos; j+=SIMDSIZE, left+=SIMDSIZE, right+=SIMDSIZE ) {
2398  left.stream( right.load() );
2399  }
2400  for( ; remainder && j<n_; ++j, ++left, ++right ) {
2401  *left = *right;
2402  }
2403  }
2404  }
2405  else
2406  {
2407  for( size_t i=0UL; i<m_; ++i )
2408  {
2409  size_t j( 0UL );
2410  Iterator left( begin(i) );
2411  ConstIterator_t<MT> right( (~rhs).begin(i) );
2412 
2413  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2414  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2415  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2416  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2417  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2418  }
2419  for( ; j<jpos; j+=SIMDSIZE ) {
2420  left.store( right.load() ); left+=SIMDSIZE, right+=SIMDSIZE;
2421  }
2422  for( ; remainder && j<n_; ++j ) {
2423  *left = *right; ++left; ++right;
2424  }
2425  }
2426  }
2427 }
2428 //*************************************************************************************************
2429 
2430 
2431 //*************************************************************************************************
2442 template< typename Type // Data type of the matrix
2443  , bool SO > // Storage order
2444 template< typename MT > // Type of the right-hand side dense matrix
2446 {
2448 
2449  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2450  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2451 
2452  constexpr size_t block( BLOCK_SIZE );
2453 
2454  for( size_t ii=0UL; ii<m_; ii+=block ) {
2455  const size_t iend( min( m_, ii+block ) );
2456  for( size_t jj=0UL; jj<n_; jj+=block ) {
2457  const size_t jend( min( n_, jj+block ) );
2458  for( size_t i=ii; i<iend; ++i ) {
2459  for( size_t j=jj; j<jend; ++j ) {
2460  v_[i*nn_+j] = (~rhs)(i,j);
2461  }
2462  }
2463  }
2464  }
2465 }
2466 //*************************************************************************************************
2467 
2468 
2469 //*************************************************************************************************
2480 template< typename Type // Data type of the matrix
2481  , bool SO > // Storage order
2482 template< typename MT > // Type of the right-hand side sparse matrix
2484 {
2485  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2486  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2487 
2488  for( size_t i=0UL; i<m_; ++i )
2489  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2490  v_[i*nn_+element->index()] = element->value();
2491 }
2492 //*************************************************************************************************
2493 
2494 
2495 //*************************************************************************************************
2506 template< typename Type // Data type of the matrix
2507  , bool SO > // Storage order
2508 template< typename MT > // Type of the right-hand side sparse matrix
2510 {
2512 
2513  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2514  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2515 
2516  for( size_t j=0UL; j<n_; ++j )
2517  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2518  v_[element->index()*nn_+j] = element->value();
2519 }
2520 //*************************************************************************************************
2521 
2522 
2523 //*************************************************************************************************
2534 template< typename Type // Data type of the matrix
2535  , bool SO > // Storage order
2536 template< typename MT > // Type of the right-hand side dense matrix
2539 {
2540  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2541  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2542 
2543  for( size_t i=0UL; i<m_; ++i )
2544  {
2545  if( IsDiagonal_v<MT> )
2546  {
2547  v_[i*nn_+i] += (~rhs)(i,i);
2548  }
2549  else
2550  {
2551  const size_t jbegin( ( IsUpper_v<MT> )
2552  ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2553  :( 0UL ) );
2554  const size_t jend ( ( IsLower_v<MT> )
2555  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2556  :( n_ ) );
2557  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2558 
2559  size_t j( jbegin );
2560 
2561  for( ; (j+2UL) <= jend; j+=2UL ) {
2562  v_[i*nn_+j ] += (~rhs)(i,j );
2563  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
2564  }
2565  if( j < jend ) {
2566  v_[i*nn_+j] += (~rhs)(i,j);
2567  }
2568  }
2569  }
2570 }
2571 //*************************************************************************************************
2572 
2573 
2574 //*************************************************************************************************
2585 template< typename Type // Data type of the matrix
2586  , bool SO > // Storage order
2587 template< typename MT > // Type of the right-hand side dense matrix
2588 inline auto DynamicMatrix<Type,SO>::addAssign( const DenseMatrix<MT,SO>& rhs )
2590 {
2593 
2594  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2595  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2596 
2597  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2598 
2599  for( size_t i=0UL; i<m_; ++i )
2600  {
2601  const size_t jbegin( ( IsUpper_v<MT> )
2602  ?( ( IsStrictlyUpper_v<MT> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2603  :( 0UL ) );
2604  const size_t jend ( ( IsLower_v<MT> )
2605  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2606  :( n_ ) );
2607  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2608 
2609  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2610  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2611 
2612  size_t j( jbegin );
2613  Iterator left( begin(i) + jbegin );
2614  ConstIterator_t<MT> right( (~rhs).begin(i) + jbegin );
2615 
2616  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2617  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2618  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2619  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2620  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2621  }
2622  for( ; j<jpos; j+=SIMDSIZE ) {
2623  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2624  }
2625  for( ; remainder && j<jend; ++j ) {
2626  *left += *right; ++left; ++right;
2627  }
2628  }
2629 }
2630 //*************************************************************************************************
2631 
2632 
2633 //*************************************************************************************************
2644 template< typename Type // Data type of the matrix
2645  , bool SO > // Storage order
2646 template< typename MT > // Type of the right-hand side dense matrix
2648 {
2650 
2651  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2652  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2653 
2654  constexpr size_t block( BLOCK_SIZE );
2655 
2656  for( size_t ii=0UL; ii<m_; ii+=block ) {
2657  const size_t iend( min( m_, ii+block ) );
2658  for( size_t jj=0UL; jj<n_; jj+=block )
2659  {
2660  if( IsLower_v<MT> && ii < jj ) break;
2661  if( IsUpper_v<MT> && ii > jj ) continue;
2662 
2663  for( size_t i=ii; i<iend; ++i )
2664  {
2665  const size_t jbegin( ( IsUpper_v<MT> )
2666  ?( max( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), jj ) )
2667  :( jj ) );
2668  const size_t jend ( ( IsLower_v<MT> )
2669  ?( min( ( IsStrictlyLower_v<MT> ? i : i+1UL ), n_, jj+block ) )
2670  :( min( n_, jj+block ) ) );
2671  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2672 
2673  for( size_t j=jbegin; j<jend; ++j ) {
2674  v_[i*nn_+j] += (~rhs)(i,j);
2675  }
2676  }
2677  }
2678  }
2679 }
2680 //*************************************************************************************************
2681 
2682 
2683 //*************************************************************************************************
2694 template< typename Type // Data type of the matrix
2695  , bool SO > // Storage order
2696 template< typename MT > // Type of the right-hand side sparse matrix
2698 {
2699  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2700  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2701 
2702  for( size_t i=0UL; i<m_; ++i )
2703  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2704  v_[i*nn_+element->index()] += element->value();
2705 }
2706 //*************************************************************************************************
2707 
2708 
2709 //*************************************************************************************************
2720 template< typename Type // Data type of the matrix
2721  , bool SO > // Storage order
2722 template< typename MT > // Type of the right-hand side sparse matrix
2724 {
2726 
2727  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2728  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2729 
2730  for( size_t j=0UL; j<n_; ++j )
2731  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2732  v_[element->index()*nn_+j] += element->value();
2733 }
2734 //*************************************************************************************************
2735 
2736 
2737 //*************************************************************************************************
2748 template< typename Type // Data type of the matrix
2749  , bool SO > // Storage order
2750 template< typename MT > // Type of the right-hand side dense matrix
2753 {
2754  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2755  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2756 
2757  for( size_t i=0UL; i<m_; ++i )
2758  {
2759  if( IsDiagonal_v<MT> )
2760  {
2761  v_[i*nn_+i] -= (~rhs)(i,i);
2762  }
2763  else
2764  {
2765  const size_t jbegin( ( IsUpper_v<MT> )
2766  ?( IsStrictlyUpper_v<MT> ? i+1UL : i )
2767  :( 0UL ) );
2768  const size_t jend ( ( IsLower_v<MT> )
2769  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2770  :( n_ ) );
2771  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2772 
2773  size_t j( jbegin );
2774 
2775  for( ; (j+2UL) <= jend; j+=2UL ) {
2776  v_[i*nn_+j ] -= (~rhs)(i,j );
2777  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
2778  }
2779  if( j < jend ) {
2780  v_[i*nn_+j] -= (~rhs)(i,j);
2781  }
2782  }
2783  }
2784 }
2785 //*************************************************************************************************
2786 
2787 
2788 //*************************************************************************************************
2799 template< typename Type // Data type of the matrix
2800  , bool SO > // Storage order
2801 template< typename MT > // Type of the right-hand side dense matrix
2802 inline auto DynamicMatrix<Type,SO>::subAssign( const DenseMatrix<MT,SO>& rhs )
2804 {
2807 
2808  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2809  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2810 
2811  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
2812 
2813  for( size_t i=0UL; i<m_; ++i )
2814  {
2815  const size_t jbegin( ( IsUpper_v<MT> )
2816  ?( ( IsStrictlyUpper_v<MT> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2817  :( 0UL ) );
2818  const size_t jend ( ( IsLower_v<MT> )
2819  ?( IsStrictlyLower_v<MT> ? i : i+1UL )
2820  :( n_ ) );
2821  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2822 
2823  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2824  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2825 
2826  size_t j( jbegin );
2827  Iterator left( begin(i) + jbegin );
2828  ConstIterator_t<MT> right( (~rhs).begin(i) + jbegin );
2829 
2830  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2831  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2832  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2833  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2834  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2835  }
2836  for( ; j<jpos; j+=SIMDSIZE ) {
2837  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2838  }
2839  for( ; remainder && j<jend; ++j ) {
2840  *left -= *right; ++left; ++right;
2841  }
2842  }
2843 }
2844 //*************************************************************************************************
2845 
2846 
2847 //*************************************************************************************************
2858 template< typename Type // Data type of the matrix
2859  , bool SO > // Storage order
2860 template< typename MT > // Type of the right-hand side dense matrix
2862 {
2864 
2865  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2866  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2867 
2868  constexpr size_t block( BLOCK_SIZE );
2869 
2870  for( size_t ii=0UL; ii<m_; ii+=block ) {
2871  const size_t iend( min( m_, ii+block ) );
2872  for( size_t jj=0UL; jj<n_; jj+=block )
2873  {
2874  if( IsLower_v<MT> && ii < jj ) break;
2875  if( IsUpper_v<MT> && ii > jj ) continue;
2876 
2877  for( size_t i=ii; i<iend; ++i )
2878  {
2879  const size_t jbegin( ( IsUpper_v<MT> )
2880  ?( max( ( IsStrictlyUpper_v<MT> ? i+1UL : i ), jj ) )
2881  :( jj ) );
2882  const size_t jend ( ( IsLower_v<MT> )
2883  ?( min( ( IsStrictlyLower_v<MT> ? i : i+1UL ), n_, jj+block ) )
2884  :( min( n_, jj+block ) ) );
2885  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2886 
2887  for( size_t j=jbegin; j<jend; ++j ) {
2888  v_[i*nn_+j] -= (~rhs)(i,j);
2889  }
2890  }
2891  }
2892  }
2893 }
2894 //*************************************************************************************************
2895 
2896 
2897 //*************************************************************************************************
2908 template< typename Type // Data type of the matrix
2909  , bool SO > // Storage order
2910 template< typename MT > // Type of the right-hand side sparse matrix
2912 {
2913  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2914  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2915 
2916  for( size_t i=0UL; i<m_; ++i )
2917  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2918  v_[i*nn_+element->index()] -= element->value();
2919 }
2920 //*************************************************************************************************
2921 
2922 
2923 //*************************************************************************************************
2934 template< typename Type // Data type of the matrix
2935  , bool SO > // Storage order
2936 template< typename MT > // Type of the right-hand side sparse matrix
2938 {
2940 
2941  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2942  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2943 
2944  for( size_t j=0UL; j<n_; ++j )
2945  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2946  v_[element->index()*nn_+j] -= element->value();
2947 }
2948 //*************************************************************************************************
2949 
2950 
2951 //*************************************************************************************************
2962 template< typename Type // Data type of the matrix
2963  , bool SO > // Storage order
2964 template< typename MT > // Type of the right-hand side dense matrix
2967 {
2968  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2969  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2970 
2971  const size_t jpos( n_ & size_t(-2) );
2972  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == jpos, "Invalid end calculation" );
2973 
2974  for( size_t i=0UL; i<m_; ++i ) {
2975  for( size_t j=0UL; j<jpos; j+=2UL ) {
2976  v_[i*nn_+j ] *= (~rhs)(i,j );
2977  v_[i*nn_+j+1UL] *= (~rhs)(i,j+1UL);
2978  }
2979  if( jpos < n_ ) {
2980  v_[i*nn_+jpos] *= (~rhs)(i,jpos);
2981  }
2982  }
2983 }
2984 //*************************************************************************************************
2985 
2986 
2987 //*************************************************************************************************
2998 template< typename Type // Data type of the matrix
2999  , bool SO > // Storage order
3000 template< typename MT > // Type of the right-hand side dense matrix
3003 {
3005 
3006  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3007  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3008 
3009  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
3010 
3011  for( size_t i=0UL; i<m_; ++i )
3012  {
3013  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
3014  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3015 
3016  size_t j( 0UL );
3017  Iterator left( begin(i) );
3018  ConstIterator_t<MT> right( (~rhs).begin(i) );
3019 
3020  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
3021  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3022  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3023  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3024  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3025  }
3026  for( ; j<jpos; j+=SIMDSIZE ) {
3027  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
3028  }
3029  for( ; remainder && j<n_; ++j ) {
3030  *left *= *right; ++left; ++right;
3031  }
3032  }
3033 }
3034 //*************************************************************************************************
3035 
3036 
3037 //*************************************************************************************************
3048 template< typename Type // Data type of the matrix
3049  , bool SO > // Storage order
3050 template< typename MT > // Type of the right-hand side dense matrix
3052 {
3054 
3055  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3056  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3057 
3058  constexpr size_t block( BLOCK_SIZE );
3059 
3060  for( size_t ii=0UL; ii<m_; ii+=block ) {
3061  const size_t iend( min( m_, ii+block ) );
3062  for( size_t jj=0UL; jj<n_; jj+=block ) {
3063  const size_t jend( min( n_, jj+block ) );
3064  for( size_t i=ii; i<iend; ++i ) {
3065  for( size_t j=jj; j<jend; ++j ) {
3066  v_[i*nn_+j] *= (~rhs)(i,j);
3067  }
3068  }
3069  }
3070  }
3071 }
3072 //*************************************************************************************************
3073 
3074 
3075 //*************************************************************************************************
3086 template< typename Type // Data type of the matrix
3087  , bool SO > // Storage order
3088 template< typename MT > // Type of the right-hand side sparse matrix
3090 {
3091  using blaze::reset;
3092 
3093  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3094  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3095 
3096  for( size_t i=0UL; i<m_; ++i )
3097  {
3098  size_t j( 0UL );
3099 
3100  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
3101  for( ; j<element->index(); ++j )
3102  reset( v_[i*nn_+j] );
3103  v_[i*nn_+j] *= element->value();
3104  ++j;
3105  }
3106 
3107  for( ; j<n_; ++j ) {
3108  reset( v_[i*nn_+j] );
3109  }
3110  }
3111 }
3112 //*************************************************************************************************
3113 
3114 
3115 //*************************************************************************************************
3126 template< typename Type // Data type of the matrix
3127  , bool SO > // Storage order
3128 template< typename MT > // Type of the right-hand side sparse matrix
3130 {
3131  using blaze::reset;
3132 
3134 
3135  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3136  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3137 
3138  for( size_t j=0UL; j<n_; ++j )
3139  {
3140  size_t i( 0UL );
3141 
3142  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
3143  for( ; i<element->index(); ++i )
3144  reset( v_[i*nn_+j] );
3145  v_[i*nn_+j] *= element->value();
3146  ++i;
3147  }
3148 
3149  for( ; i<m_; ++i ) {
3150  reset( v_[i*nn_+j] );
3151  }
3152  }
3153 }
3154 //*************************************************************************************************
3155 
3156 
3157 
3158 
3159 
3160 
3161 
3162 
3163 //=================================================================================================
3164 //
3165 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3166 //
3167 //=================================================================================================
3168 
3169 //*************************************************************************************************
3177 template< typename Type > // Data type of the matrix
3178 class DynamicMatrix<Type,true>
3179  : public DenseMatrix< DynamicMatrix<Type,true>, true >
3180 {
3181  public:
3182  //**Type definitions****************************************************************************
3183  using This = DynamicMatrix<Type,true>;
3185  using ResultType = This;
3188  using ElementType = Type;
3190  using ReturnType = const Type&;
3191  using CompositeType = const This&;
3192 
3193  using Reference = Type&;
3194  using ConstReference = const Type&;
3195  using Pointer = Type*;
3196  using ConstPointer = const Type*;
3197 
3200  //**********************************************************************************************
3201 
3202  //**Rebind struct definition********************************************************************
3205  template< typename NewType > // Data type of the other matrix
3206  struct Rebind {
3208  };
3209  //**********************************************************************************************
3210 
3211  //**Resize struct definition********************************************************************
3214  template< size_t NewM // Number of rows of the other matrix
3215  , size_t NewN > // Number of columns of the other matrix
3216  struct Resize {
3217  using Other = DynamicMatrix<Type,true>;
3218  };
3219  //**********************************************************************************************
3220 
3221  //**Compilation flags***************************************************************************
3223 
3227  static constexpr bool simdEnabled = IsVectorizable_v<Type>;
3228 
3230 
3233  static constexpr bool smpAssignable = !IsSMPAssignable_v<Type>;
3234  //**********************************************************************************************
3235 
3236  //**Constructors********************************************************************************
3239  explicit inline DynamicMatrix() noexcept;
3240  explicit inline DynamicMatrix( size_t m, size_t n );
3241  explicit inline DynamicMatrix( size_t m, size_t n, const Type& init );
3242  inline DynamicMatrix( initializer_list< initializer_list<Type> > list );
3243 
3244  template< typename Other > explicit inline DynamicMatrix( size_t m, size_t n, const Other* array );
3245 
3246  template< typename Other, size_t Rows, size_t Cols >
3247  explicit inline DynamicMatrix( const Other (&array)[Rows][Cols] );
3248 
3249  inline DynamicMatrix( const DynamicMatrix& m );
3250  inline DynamicMatrix( DynamicMatrix&& m );
3251  template< typename MT, bool SO > inline DynamicMatrix( const Matrix<MT,SO>& m );
3253  //**********************************************************************************************
3254 
3255  //**Destructor**********************************************************************************
3258  inline ~DynamicMatrix();
3260  //**********************************************************************************************
3261 
3262  //**Data access functions***********************************************************************
3265  inline Reference operator()( size_t i, size_t j ) noexcept;
3266  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3267  inline Reference at( size_t i, size_t j );
3268  inline ConstReference at( size_t i, size_t j ) const;
3269  inline Pointer data () noexcept;
3270  inline ConstPointer data () const noexcept;
3271  inline Pointer data ( size_t j ) noexcept;
3272  inline ConstPointer data ( size_t j ) const noexcept;
3273  inline Iterator begin ( size_t j ) noexcept;
3274  inline ConstIterator begin ( size_t j ) const noexcept;
3275  inline ConstIterator cbegin( size_t j ) const noexcept;
3276  inline Iterator end ( size_t j ) noexcept;
3277  inline ConstIterator end ( size_t j ) const noexcept;
3278  inline ConstIterator cend ( size_t j ) const noexcept;
3280  //**********************************************************************************************
3281 
3282  //**Assignment operators************************************************************************
3285  inline DynamicMatrix& operator=( const Type& rhs );
3286  inline DynamicMatrix& operator=( initializer_list< initializer_list<Type> > list );
3287 
3288  template< typename Other, size_t Rows, size_t Cols >
3289  inline DynamicMatrix& operator=( const Other (&array)[Rows][Cols] );
3290 
3291  inline DynamicMatrix& operator=( const DynamicMatrix& rhs );
3292  inline DynamicMatrix& operator=( DynamicMatrix&& rhs );
3293 
3294  template< typename MT, bool SO > inline DynamicMatrix& operator= ( const Matrix<MT,SO>& rhs );
3295  template< typename MT, bool SO > inline DynamicMatrix& operator+=( const Matrix<MT,SO>& rhs );
3296  template< typename MT, bool SO > inline DynamicMatrix& operator-=( const Matrix<MT,SO>& rhs );
3297  template< typename MT, bool SO > inline DynamicMatrix& operator%=( const Matrix<MT,SO>& rhs );
3299  //**********************************************************************************************
3300 
3301  //**Utility functions***************************************************************************
3304  inline size_t rows() const noexcept;
3305  inline size_t columns() const noexcept;
3306  inline size_t spacing() const noexcept;
3307  inline size_t capacity() const noexcept;
3308  inline size_t capacity( size_t j ) const noexcept;
3309  inline size_t nonZeros() const;
3310  inline size_t nonZeros( size_t j ) const;
3311  inline void reset();
3312  inline void reset( size_t j );
3313  inline void clear();
3314  void resize ( size_t m, size_t n, bool preserve=true );
3315  inline void extend ( size_t m, size_t n, bool preserve=true );
3316  inline void reserve( size_t elements );
3317  inline void shrinkToFit();
3318  inline void swap( DynamicMatrix& m ) noexcept;
3320  //**********************************************************************************************
3321 
3322  //**Numeric functions***************************************************************************
3325  inline DynamicMatrix& transpose();
3326  inline DynamicMatrix& ctranspose();
3327 
3328  template< typename Other > inline DynamicMatrix& scale( const Other& scalar );
3330  //**********************************************************************************************
3331 
3332  private:
3333  //**********************************************************************************************
3335  template< typename MT >
3336  static constexpr bool VectorizedAssign_v =
3337  ( useOptimizedKernels &&
3338  simdEnabled && MT::simdEnabled &&
3339  IsSIMDCombinable_v< Type, ElementType_t<MT> > );
3340  //**********************************************************************************************
3341 
3342  //**********************************************************************************************
3344  template< typename MT >
3345  static constexpr bool VectorizedAddAssign_v =
3346  ( useOptimizedKernels &&
3347  simdEnabled && MT::simdEnabled &&
3348  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3349  HasSIMDAdd_v< Type, ElementType_t<MT> > &&
3350  !IsDiagonal_v<MT> );
3351  //**********************************************************************************************
3352 
3353  //**********************************************************************************************
3355  template< typename MT >
3356  static constexpr bool VectorizedSubAssign_v =
3357  ( useOptimizedKernels &&
3358  simdEnabled && MT::simdEnabled &&
3359  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3360  HasSIMDSub_v< Type, ElementType_t<MT> > &&
3361  !IsDiagonal_v<MT> );
3362  //**********************************************************************************************
3363 
3364  //**********************************************************************************************
3366  template< typename MT >
3367  static constexpr bool VectorizedSchurAssign_v =
3368  ( useOptimizedKernels &&
3369  simdEnabled && MT::simdEnabled &&
3370  IsSIMDCombinable_v< Type, ElementType_t<MT> > &&
3371  HasSIMDMult_v< Type, ElementType_t<MT> > );
3372  //**********************************************************************************************
3373 
3374  //**********************************************************************************************
3376  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
3377  //**********************************************************************************************
3378 
3379  public:
3380  //**Debugging functions*************************************************************************
3383  inline bool isIntact() const noexcept;
3385  //**********************************************************************************************
3386 
3387  //**Expression template evaluation functions****************************************************
3390  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3391  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3392 
3393  inline bool isAligned () const noexcept;
3394  inline bool canSMPAssign() const noexcept;
3395 
3396  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3397  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3398  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3399 
3400  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3401  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3402  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3403  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3404 
3405  template< typename MT >
3406  inline auto assign( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT> >;
3407 
3408  template< typename MT >
3409  inline auto assign( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT> >;
3410 
3411  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
3412  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3413  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3414 
3415  template< typename MT >
3416  inline auto addAssign( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT> >;
3417 
3418  template< typename MT >
3419  inline auto addAssign( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT> >;
3420 
3421  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
3422  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3423  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3424 
3425  template< typename MT >
3426  inline auto subAssign ( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT> >;
3427 
3428  template< typename MT >
3429  inline auto subAssign ( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT> >;
3430 
3431  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
3432  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3433  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3434 
3435  template< typename MT >
3436  inline auto schurAssign ( const DenseMatrix<MT,true>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT> >;
3437 
3438  template< typename MT >
3439  inline auto schurAssign ( const DenseMatrix<MT,true>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT> >;
3440 
3441  template< typename MT > inline void schurAssign( const DenseMatrix<MT,false>& rhs );
3442  template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3443  template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3445  //**********************************************************************************************
3446 
3447  private:
3448  //**Utility functions***************************************************************************
3451  inline size_t addPadding( size_t minRows ) const noexcept;
3453  //**********************************************************************************************
3454 
3455  //**Member variables****************************************************************************
3458  size_t m_;
3459  size_t mm_;
3460  size_t n_;
3461  size_t capacity_;
3462  Type* BLAZE_RESTRICT v_;
3463 
3466  //**********************************************************************************************
3467 
3468  //**Compile time checks*************************************************************************
3473  //**********************************************************************************************
3474 };
3476 //*************************************************************************************************
3477 
3478 
3479 
3480 
3481 //=================================================================================================
3482 //
3483 // CONSTRUCTORS
3484 //
3485 //=================================================================================================
3486 
3487 //*************************************************************************************************
3491 template< typename Type > // Data type of the matrix
3492 inline DynamicMatrix<Type,true>::DynamicMatrix() noexcept
3493  : m_ ( 0UL ) // The current number of rows of the matrix
3494  , mm_ ( 0UL ) // The alignment adjusted number of rows
3495  , n_ ( 0UL ) // The current number of columns of the matrix
3496  , capacity_( 0UL ) // The maximum capacity of the matrix
3497  , v_ ( nullptr ) // The matrix elements
3498 {}
3500 //*************************************************************************************************
3501 
3502 
3503 //*************************************************************************************************
3513 template< typename Type > // Data type of the matrix
3514 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n )
3515  : m_ ( m ) // The current number of rows of the matrix
3516  , mm_ ( addPadding( m ) ) // The alignment adjusted number of rows
3517  , n_ ( n ) // The current number of columns of the matrix
3518  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
3519  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
3520 {
3521  if( IsVectorizable_v<Type> ) {
3522  for( size_t j=0UL; j<n_; ++j ) {
3523  for( size_t i=m_; i<mm_; ++i ) {
3524  v_[i+j*mm_] = Type();
3525  }
3526  }
3527  }
3528 
3529  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3530 }
3532 //*************************************************************************************************
3533 
3534 
3535 //*************************************************************************************************
3545 template< typename Type > // Data type of the matrix
3546 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, const Type& init )
3547  : DynamicMatrix( m, n )
3548 {
3549  for( size_t j=0UL; j<n_; ++j ) {
3550  for( size_t i=0UL; i<m_; ++i ) {
3551  v_[i+j*mm_] = init;
3552  }
3553  }
3554 
3555  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3556 }
3558 //*************************************************************************************************
3559 
3560 
3561 //*************************************************************************************************
3582 template< typename Type > // Data type of the matrix
3583 inline DynamicMatrix<Type,true>::DynamicMatrix( initializer_list< initializer_list<Type> > list )
3584  : DynamicMatrix( list.size(), determineColumns( list ) )
3585 {
3586  size_t i( 0UL );
3587 
3588  for( const auto& rowList : list ) {
3589  size_t j( 0UL );
3590  for( const auto& element : rowList ) {
3591  v_[i+j*mm_] = element;
3592  ++j;
3593  }
3594  for( ; j<n_; ++j ) {
3595  v_[i+j*mm_] = Type();
3596  }
3597  ++i;
3598  }
3599 
3600  BLAZE_INTERNAL_ASSERT( i == m_, "Invalid number of elements detected" );
3601  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3602 }
3604 //*************************************************************************************************
3605 
3606 
3607 //*************************************************************************************************
3631 template< typename Type > // Data type of the matrix
3632 template< typename Other > // Data type of the initialization array
3633 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, const Other* array )
3634  : DynamicMatrix( m, n )
3635 {
3636  for( size_t j=0UL; j<n; ++j ) {
3637  for( size_t i=0UL; i<m; ++i ) {
3638  v_[i+j*mm_] = array[i+j*m];
3639  }
3640  }
3641 
3642  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3643 }
3645 //*************************************************************************************************
3646 
3647 
3648 //*************************************************************************************************
3670 template< typename Type > // Data type of the matrix
3671 template< typename Other // Data type of the initialization array
3672  , size_t Rows // Number of rows of the initialization array
3673  , size_t Cols > // Number of columns of the initialization array
3674 inline DynamicMatrix<Type,true>::DynamicMatrix( const Other (&array)[Rows][Cols] )
3675  : DynamicMatrix( Rows, Cols )
3676 {
3677  for( size_t j=0UL; j<Cols; ++j ) {
3678  for( size_t i=0UL; i<Rows; ++i ) {
3679  v_[i+j*mm_] = array[i][j];
3680  }
3681  }
3682 
3683  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3684 }
3686 //*************************************************************************************************
3687 
3688 
3689 //*************************************************************************************************
3698 template< typename Type > // Data type of the matrix
3699 inline DynamicMatrix<Type,true>::DynamicMatrix( const DynamicMatrix& m )
3700  : DynamicMatrix( m.m_, m.n_ )
3701 {
3702  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
3703 
3704  smpAssign( *this, m );
3705 
3706  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3707 }
3709 //*************************************************************************************************
3710 
3711 
3712 //*************************************************************************************************
3718 template< typename Type > // Data type of the matrix
3719 inline DynamicMatrix<Type,true>::DynamicMatrix( DynamicMatrix&& m )
3720  : m_ ( m.m_ ) // The current number of rows of the matrix
3721  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
3722  , n_ ( m.n_ ) // The current number of columns of the matrix
3723  , capacity_( m.capacity_ ) // The maximum capacity of the matrix
3724  , v_ ( m.v_ ) // The matrix elements
3725 {
3726  m.m_ = 0UL;
3727  m.mm_ = 0UL;
3728  m.n_ = 0UL;
3729  m.capacity_ = 0UL;
3730  m.v_ = nullptr;
3731 }
3733 //*************************************************************************************************
3734 
3735 
3736 //*************************************************************************************************
3742 template< typename Type > // Data type of the matrix
3743 template< typename MT // Type of the foreign matrix
3744  , bool SO > // Storage order of the foreign matrix
3745 inline DynamicMatrix<Type,true>::DynamicMatrix( const Matrix<MT,SO>& m )
3746  : DynamicMatrix( (~m).rows(), (~m).columns() )
3747 {
3748  if( IsSparseMatrix_v<MT> ) {
3749  reset();
3750  }
3751 
3752  smpAssign( *this, ~m );
3753 
3754  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3755 }
3757 //*************************************************************************************************
3758 
3759 
3760 
3761 
3762 //=================================================================================================
3763 //
3764 // DESTRUCTOR
3765 //
3766 //=================================================================================================
3767 
3768 //*************************************************************************************************
3772 template< typename Type > // Data type of the matrix
3774 {
3775  deallocate( v_ );
3776 }
3778 //*************************************************************************************************
3779 
3780 
3781 
3782 
3783 //=================================================================================================
3784 //
3785 // DATA ACCESS FUNCTIONS
3786 //
3787 //=================================================================================================
3788 
3789 //*************************************************************************************************
3800 template< typename Type > // Data type of the matrix
3802  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) noexcept
3803 {
3804  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3805  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3806  return v_[i+j*mm_];
3807 }
3809 //*************************************************************************************************
3810 
3811 
3812 //*************************************************************************************************
3823 template< typename Type > // Data type of the matrix
3825  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) const noexcept
3826 {
3827  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
3828  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
3829  return v_[i+j*mm_];
3830 }
3832 //*************************************************************************************************
3833 
3834 
3835 //*************************************************************************************************
3847 template< typename Type > // Data type of the matrix
3849  DynamicMatrix<Type,true>::at( size_t i, size_t j )
3850 {
3851  if( i >= m_ ) {
3852  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3853  }
3854  if( j >= n_ ) {
3855  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3856  }
3857  return (*this)(i,j);
3858 }
3860 //*************************************************************************************************
3861 
3862 
3863 //*************************************************************************************************
3875 template< typename Type > // Data type of the matrix
3877  DynamicMatrix<Type,true>::at( size_t i, size_t j ) const
3878 {
3879  if( i >= m_ ) {
3880  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3881  }
3882  if( j >= n_ ) {
3883  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3884  }
3885  return (*this)(i,j);
3886 }
3888 //*************************************************************************************************
3889 
3890 
3891 //*************************************************************************************************
3903 template< typename Type > // Data type of the matrix
3904 inline typename DynamicMatrix<Type,true>::Pointer
3906 {
3907  return v_;
3908 }
3910 //*************************************************************************************************
3911 
3912 
3913 //*************************************************************************************************
3925 template< typename Type > // Data type of the matrix
3927  DynamicMatrix<Type,true>::data() const noexcept
3928 {
3929  return v_;
3930 }
3932 //*************************************************************************************************
3933 
3934 
3935 //*************************************************************************************************
3944 template< typename Type > // Data type of the matrix
3945 inline typename DynamicMatrix<Type,true>::Pointer
3946  DynamicMatrix<Type,true>::data( size_t j ) noexcept
3947 {
3948  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3949  return v_ + j*mm_;
3950 }
3952 //*************************************************************************************************
3953 
3954 
3955 //*************************************************************************************************
3964 template< typename Type > // Data type of the matrix
3966  DynamicMatrix<Type,true>::data( size_t j ) const noexcept
3967 {
3968  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3969  return v_ + j*mm_;
3970 }
3972 //*************************************************************************************************
3973 
3974 
3975 //*************************************************************************************************
3982 template< typename Type > // Data type of the matrix
3983 inline typename DynamicMatrix<Type,true>::Iterator
3984  DynamicMatrix<Type,true>::begin( size_t j ) noexcept
3985 {
3986  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
3987  return Iterator( v_ + j*mm_ );
3988 }
3990 //*************************************************************************************************
3991 
3992 
3993 //*************************************************************************************************
4000 template< typename Type > // Data type of the matrix
4002  DynamicMatrix<Type,true>::begin( size_t j ) const noexcept
4003 {
4004  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4005  return ConstIterator( v_ + j*mm_ );
4006 }
4008 //*************************************************************************************************
4009 
4010 
4011 //*************************************************************************************************
4018 template< typename Type > // Data type of the matrix
4020  DynamicMatrix<Type,true>::cbegin( size_t j ) const noexcept
4021 {
4022  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4023  return ConstIterator( v_ + j*mm_ );
4024 }
4026 //*************************************************************************************************
4027 
4028 
4029 //*************************************************************************************************
4036 template< typename Type > // Data type of the matrix
4037 inline typename DynamicMatrix<Type,true>::Iterator
4038  DynamicMatrix<Type,true>::end( size_t j ) noexcept
4039 {
4040  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4041  return Iterator( v_ + j*mm_ + m_ );
4042 }
4044 //*************************************************************************************************
4045 
4046 
4047 //*************************************************************************************************
4054 template< typename Type > // Data type of the matrix
4056  DynamicMatrix<Type,true>::end( size_t j ) const noexcept
4057 {
4058  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4059  return ConstIterator( v_ + j*mm_ + m_ );
4060 }
4062 //*************************************************************************************************
4063 
4064 
4065 //*************************************************************************************************
4072 template< typename Type > // Data type of the matrix
4074  DynamicMatrix<Type,true>::cend( size_t j ) const noexcept
4075 {
4076  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
4077  return ConstIterator( v_ + j*mm_ + m_ );
4078 }
4080 //*************************************************************************************************
4081 
4082 
4083 
4084 
4085 //=================================================================================================
4086 //
4087 // ASSIGNMENT OPERATORS
4088 //
4089 //=================================================================================================
4090 
4091 //*************************************************************************************************
4098 template< typename Type > // Data type of the matrix
4099 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Type& rhs )
4100 {
4101  for( size_t j=0UL; j<n_; ++j )
4102  for( size_t i=0UL; i<m_; ++i )
4103  v_[i+j*mm_] = rhs;
4104 
4105  return *this;
4106 }
4108 //*************************************************************************************************
4109 
4110 
4111 //*************************************************************************************************
4133 template< typename Type > // Data type of the matrix
4134 inline DynamicMatrix<Type,true>&
4135  DynamicMatrix<Type,true>::operator=( initializer_list< initializer_list<Type> > list )
4136 {
4137  resize( list.size(), determineColumns( list ), false );
4138 
4139  size_t i( 0UL );
4140 
4141  for( const auto& rowList : list ) {
4142  size_t j( 0UL );
4143  for( const auto& element : rowList ) {
4144  v_[i+j*mm_] = element;
4145  ++j;
4146  }
4147  for( ; j<n_; ++j ) {
4148  v_[i+j*mm_] = Type();
4149  }
4150  ++i;
4151  }
4152 
4153  return *this;
4154 }
4156 //*************************************************************************************************
4157 
4158 
4159 //*************************************************************************************************
4181 template< typename Type > // Data type of the matrix
4182 template< typename Other // Data type of the initialization array
4183  , size_t Rows // Number of rows of the initialization array
4184  , size_t Cols > // Number of columns of the initialization array
4185 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Other (&array)[Rows][Cols] )
4186 {
4187  resize( Rows, Cols, false );
4188 
4189  for( size_t j=0UL; j<Cols; ++j )
4190  for( size_t i=0UL; i<Rows; ++i )
4191  v_[i+j*mm_] = array[i][j];
4192 
4193  return *this;
4194 }
4196 //*************************************************************************************************
4197 
4198 
4199 //*************************************************************************************************
4209 template< typename Type > // Data type of the matrix
4210 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const DynamicMatrix& rhs )
4211 {
4212  if( &rhs == this ) return *this;
4213 
4214  resize( rhs.m_, rhs.n_, false );
4215  smpAssign( *this, ~rhs );
4216 
4217  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4218 
4219  return *this;
4220 }
4222 //*************************************************************************************************
4223 
4224 
4225 //*************************************************************************************************
4232 template< typename Type > // Data type of the matrix
4233 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( DynamicMatrix&& rhs )
4234 {
4235  deallocate( v_ );
4236 
4237  m_ = rhs.m_;
4238  mm_ = rhs.mm_;
4239  n_ = rhs.n_;
4240  capacity_ = rhs.capacity_;
4241  v_ = rhs.v_;
4242 
4243  rhs.m_ = 0UL;
4244  rhs.mm_ = 0UL;
4245  rhs.n_ = 0UL;
4246  rhs.capacity_ = 0UL;
4247  rhs.v_ = nullptr;
4248 
4249  return *this;
4250 }
4252 //*************************************************************************************************
4253 
4254 
4255 //*************************************************************************************************
4265 template< typename Type > // Data type of the matrix
4266 template< typename MT // Type of the right-hand side matrix
4267  , bool SO > // Storage order of the right-hand side matrix
4268 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Matrix<MT,SO>& rhs )
4269 {
4270  using TT = decltype( trans( *this ) );
4271  using CT = decltype( ctrans( *this ) );
4272  using IT = decltype( inv( *this ) );
4273 
4274  if( IsSame_v<MT,TT> && (~rhs).isAliased( this ) ) {
4275  transpose();
4276  }
4277  else if( IsSame_v<MT,CT> && (~rhs).isAliased( this ) ) {
4278  ctranspose();
4279  }
4280  else if( !IsSame_v<MT,IT> && (~rhs).canAlias( this ) ) {
4281  DynamicMatrix tmp( ~rhs );
4282  swap( tmp );
4283  }
4284  else {
4285  resize( (~rhs).rows(), (~rhs).columns(), false );
4286  if( IsSparseMatrix_v<MT> )
4287  reset();
4288  smpAssign( *this, ~rhs );
4289  }
4290 
4291  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4292 
4293  return *this;
4294 }
4296 //*************************************************************************************************
4297 
4298 
4299 //*************************************************************************************************
4310 template< typename Type > // Data type of the matrix
4311 template< typename MT // Type of the right-hand side matrix
4312  , bool SO > // Storage order of the right-hand side matrix
4313 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
4314 {
4315  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4316  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4317  }
4318 
4319  if( (~rhs).canAlias( this ) ) {
4320  const ResultType_t<MT> tmp( ~rhs );
4321  smpAddAssign( *this, tmp );
4322  }
4323  else {
4324  smpAddAssign( *this, ~rhs );
4325  }
4326 
4327  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4328 
4329  return *this;
4330 }
4332 //*************************************************************************************************
4333 
4334 
4335 //*************************************************************************************************
4346 template< typename Type > // Data type of the matrix
4347 template< typename MT // Type of the right-hand side matrix
4348  , bool SO > // Storage order of the right-hand side matrix
4349 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
4350 {
4351  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4352  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4353  }
4354 
4355  if( (~rhs).canAlias( this ) ) {
4356  const ResultType_t<MT> tmp( ~rhs );
4357  smpSubAssign( *this, tmp );
4358  }
4359  else {
4360  smpSubAssign( *this, ~rhs );
4361  }
4362 
4363  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4364 
4365  return *this;
4366 }
4368 //*************************************************************************************************
4369 
4370 
4371 //*************************************************************************************************
4382 template< typename Type > // Data type of the matrix
4383 template< typename MT // Type of the right-hand side matrix
4384  , bool SO > // Storage order of the right-hand side matrix
4385 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator%=( const Matrix<MT,SO>& rhs )
4386 {
4387  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4388  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4389  }
4390 
4391  if( (~rhs).canAlias( this ) ) {
4392  const ResultType_t<MT> tmp( ~rhs );
4393  smpSchurAssign( *this, tmp );
4394  }
4395  else {
4396  smpSchurAssign( *this, ~rhs );
4397  }
4398 
4399  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4400 
4401  return *this;
4402 }
4404 //*************************************************************************************************
4405 
4406 
4407 
4408 
4409 //=================================================================================================
4410 //
4411 // UTILITY FUNCTIONS
4412 //
4413 //=================================================================================================
4414 
4415 //*************************************************************************************************
4421 template< typename Type > // Data type of the matrix
4422 inline size_t DynamicMatrix<Type,true>::rows() const noexcept
4423 {
4424  return m_;
4425 }
4427 //*************************************************************************************************
4428 
4429 
4430 //*************************************************************************************************
4436 template< typename Type > // Data type of the matrix
4437 inline size_t DynamicMatrix<Type,true>::columns() const noexcept
4438 {
4439  return n_;
4440 }
4442 //*************************************************************************************************
4443 
4444 
4445 //*************************************************************************************************
4454 template< typename Type > // Data type of the matrix
4455 inline size_t DynamicMatrix<Type,true>::spacing() const noexcept
4456 {
4457  return mm_;
4458 }
4460 //*************************************************************************************************
4461 
4462 
4463 //*************************************************************************************************
4469 template< typename Type > // Data type of the matrix
4470 inline size_t DynamicMatrix<Type,true>::capacity() const noexcept
4471 {
4472  return capacity_;
4473 }
4475 //*************************************************************************************************
4476 
4477 
4478 //*************************************************************************************************
4485 template< typename Type > // Data type of the matrix
4486 inline size_t DynamicMatrix<Type,true>::capacity( size_t j ) const noexcept
4487 {
4488  MAYBE_UNUSED( j );
4489  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4490  return mm_;
4491 }
4493 //*************************************************************************************************
4494 
4495 
4496 //*************************************************************************************************
4502 template< typename Type > // Data type of the matrix
4503 inline size_t DynamicMatrix<Type,true>::nonZeros() const
4504 {
4505  size_t nonzeros( 0UL );
4506 
4507  for( size_t j=0UL; j<n_; ++j )
4508  for( size_t i=0UL; i<m_; ++i )
4509  if( !isDefault( v_[i+j*mm_] ) )
4510  ++nonzeros;
4511 
4512  return nonzeros;
4513 }
4515 //*************************************************************************************************
4516 
4517 
4518 //*************************************************************************************************
4525 template< typename Type > // Data type of the matrix
4526 inline size_t DynamicMatrix<Type,true>::nonZeros( size_t j ) const
4527 {
4528  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4529 
4530  const size_t iend( j*mm_ + m_ );
4531  size_t nonzeros( 0UL );
4532 
4533  for( size_t i=j*mm_; i<iend; ++i )
4534  if( !isDefault( v_[i] ) )
4535  ++nonzeros;
4536 
4537  return nonzeros;
4538 }
4540 //*************************************************************************************************
4541 
4542 
4543 //*************************************************************************************************
4549 template< typename Type > // Data type of the matrix
4550 inline void DynamicMatrix<Type,true>::reset()
4551 {
4552  using blaze::clear;
4553 
4554  for( size_t j=0UL; j<n_; ++j )
4555  for( size_t i=0UL; i<m_; ++i )
4556  clear( v_[i+j*mm_] );
4557 }
4559 //*************************************************************************************************
4560 
4561 
4562 //*************************************************************************************************
4572 template< typename Type > // Data type of the matrix
4573 inline void DynamicMatrix<Type,true>::reset( size_t j )
4574 {
4575  using blaze::clear;
4576 
4577  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4578  for( size_t i=0UL; i<m_; ++i )
4579  clear( v_[i+j*mm_] );
4580 }
4582 //*************************************************************************************************
4583 
4584 
4585 //*************************************************************************************************
4593 template< typename Type > // Data type of the matrix
4594 inline void DynamicMatrix<Type,true>::clear()
4595 {
4596  resize( 0UL, 0UL, false );
4597 }
4599 //*************************************************************************************************
4600 
4601 
4602 //*************************************************************************************************
4637 template< typename Type > // Data type of the matrix
4638 void DynamicMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
4639 {
4640  using std::swap;
4641  using blaze::min;
4642 
4643  if( m == m_ && n == n_ ) return;
4644 
4645  const size_t mm( addPadding( m ) );
4646 
4647  if( preserve )
4648  {
4649  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
4650  const size_t min_m( min( m, m_ ) );
4651  const size_t min_n( min( n, n_ ) );
4652 
4653  for( size_t j=0UL; j<min_n; ++j ) {
4654  transfer( v_+j*mm_, v_+min_m+j*mm_, v+j*mm );
4655  }
4656 
4657  swap( v_, v );
4658  deallocate( v );
4659  capacity_ = mm*n;
4660  }
4661  else if( mm*n > capacity_ ) {
4662  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
4663  swap( v_, v );
4664  deallocate( v );
4665  capacity_ = mm*n;
4666  }
4667 
4668  if( IsVectorizable_v<Type> ) {
4669  for( size_t j=0UL; j<n; ++j )
4670  for( size_t i=m; i<mm; ++i )
4671  v_[i+j*mm] = Type();
4672  }
4673 
4674  m_ = m;
4675  mm_ = mm;
4676  n_ = n;
4677 }
4679 //*************************************************************************************************
4680 
4681 
4682 //*************************************************************************************************
4697 template< typename Type > // Data type of the matrix
4698 inline void DynamicMatrix<Type,true>::extend( size_t m, size_t n, bool preserve )
4699 {
4700  resize( m_+m, n_+n, preserve );
4701 }
4703 //*************************************************************************************************
4704 
4705 
4706 //*************************************************************************************************
4716 template< typename Type > // Data type of the matrix
4717 inline void DynamicMatrix<Type,true>::reserve( size_t elements )
4718 {
4719  using std::swap;
4720 
4721  if( elements > capacity_ )
4722  {
4723  // Allocating a new array
4724  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
4725 
4726  // Initializing the new array
4727  transfer( v_, v_+capacity_, tmp );
4728 
4729  if( IsVectorizable_v<Type> ) {
4730  for( size_t i=capacity_; i<elements; ++i )
4731  tmp[i] = Type();
4732  }
4733 
4734  // Replacing the old array
4735  swap( tmp, v_ );
4736  deallocate( tmp );
4737  capacity_ = elements;
4738  }
4739 }
4741 //*************************************************************************************************
4742 
4743 
4744 //*************************************************************************************************
4755 template< typename Type > // Data type of the matrix
4757 {
4758  if( ( mm_ * n_ ) < capacity_ ) {
4759  DynamicMatrix( *this ).swap( *this );
4760  }
4761 }
4763 //*************************************************************************************************
4764 
4765 
4766 //*************************************************************************************************
4773 template< typename Type > // Data type of the matrix
4774 inline void DynamicMatrix<Type,true>::swap( DynamicMatrix& m ) noexcept
4775 {
4776  using std::swap;
4777 
4778  swap( m_ , m.m_ );
4779  swap( mm_, m.mm_ );
4780  swap( n_ , m.n_ );
4781  swap( capacity_, m.capacity_ );
4782  swap( v_ , m.v_ );
4783 }
4785 //*************************************************************************************************
4786 
4787 
4788 //*************************************************************************************************
4798 template< typename Type > // Data type of the matrix
4799 inline size_t DynamicMatrix<Type,true>::addPadding( size_t values ) const noexcept
4800 {
4801  if( usePadding && IsVectorizable_v<Type> )
4802  return nextMultiple<size_t>( values, SIMDSIZE );
4803  else return values;
4804 }
4806 //*************************************************************************************************
4807 
4808 
4809 
4810 
4811 //=================================================================================================
4812 //
4813 // NUMERIC FUNCTIONS
4814 //
4815 //=================================================================================================
4816 
4817 //*************************************************************************************************
4823 template< typename Type > // Data type of the matrix
4824 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::transpose()
4825 {
4826  using std::swap;
4827 
4828  constexpr size_t block( BLOCK_SIZE );
4829 
4830  if( m_ == n_ )
4831  {
4832  for( size_t jj=0UL; jj<n_; jj+=block ) {
4833  const size_t jend( min( jj+block, n_ ) );
4834  for( size_t ii=0UL; ii<=jj; ii+=block ) {
4835  for( size_t j=jj; j<jend; ++j ) {
4836  const size_t iend( min( ii+block, m_, j ) );
4837  for( size_t i=ii; i<iend; ++i ) {
4838  swap( v_[i+j*mm_], v_[j+i*mm_] );
4839  }
4840  }
4841  }
4842  }
4843  }
4844  else
4845  {
4846  DynamicMatrix tmp( trans(*this) );
4847  this->swap( tmp );
4848  }
4849 
4850  return *this;
4851 }
4853 //*************************************************************************************************
4854 
4855 
4856 //*************************************************************************************************
4862 template< typename Type > // Data type of the matrix
4863 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::ctranspose()
4864 {
4865  constexpr size_t block( BLOCK_SIZE );
4866 
4867  if( m_ == n_ )
4868  {
4869  for( size_t jj=0UL; jj<n_; jj+=block ) {
4870  const size_t jend( min( jj+block, n_ ) );
4871  for( size_t ii=0UL; ii<jj; ii+=block ) {
4872  const size_t iend( min( ii+block, m_ ) );
4873  for( size_t j=jj; j<jend; ++j ) {
4874  for( size_t i=ii; i<iend; ++i ) {
4875  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4876  }
4877  }
4878  }
4879  for( size_t j=jj; j<jend; ++j ) {
4880  for( size_t i=jj; i<j; ++i ) {
4881  cswap( v_[i+j*mm_], v_[j+i*mm_] );
4882  }
4883  conjugate( v_[j+j*mm_] );
4884  }
4885  }
4886  }
4887  else
4888  {
4889  DynamicMatrix tmp( ctrans(*this) );
4890  this->swap( tmp );
4891  }
4892 
4893  return *this;
4894 }
4896 //*************************************************************************************************
4897 
4898 
4899 //*************************************************************************************************
4917 template< typename Type > // Data type of the matrix
4918 template< typename Other > // Data type of the scalar value
4919 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::scale( const Other& scalar )
4920 {
4921  for( size_t j=0UL; j<n_; ++j )
4922  for( size_t i=0UL; i<m_; ++i )
4923  v_[i+j*mm_] *= scalar;
4924 
4925  return *this;
4926 }
4928 //*************************************************************************************************
4929 
4930 
4931 
4932 
4933 //=================================================================================================
4934 //
4935 // DEBUGGING FUNCTIONS
4936 //
4937 //=================================================================================================
4938 
4939 //*************************************************************************************************
4949 template< typename Type > // Data type of the matrix
4950 inline bool DynamicMatrix<Type,true>::isIntact() const noexcept
4951 {
4952  if( m_ * n_ > capacity_ )
4953  return false;
4954 
4955  if( IsVectorizable_v<Type> ) {
4956  for( size_t j=0UL; j<n_; ++j ) {
4957  for( size_t i=m_; i<mm_; ++i ) {
4958  if( v_[i+j*mm_] != Type() )
4959  return false;
4960  }
4961  }
4962  }
4963 
4964  return true;
4965 }
4967 //*************************************************************************************************
4968 
4969 
4970 
4971 
4972 //=================================================================================================
4973 //
4974 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4975 //
4976 //=================================================================================================
4977 
4978 //*************************************************************************************************
4989 template< typename Type > // Data type of the matrix
4990 template< typename Other > // Data type of the foreign expression
4991 inline bool DynamicMatrix<Type,true>::canAlias( const Other* alias ) const noexcept
4992 {
4993  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4994 }
4996 //*************************************************************************************************
4997 
4998 
4999 //*************************************************************************************************
5010 template< typename Type > // Data type of the matrix
5011 template< typename Other > // Data type of the foreign expression
5012 inline bool DynamicMatrix<Type,true>::isAliased( const Other* alias ) const noexcept
5013 {
5014  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5015 }
5017 //*************************************************************************************************
5018 
5019 
5020 //*************************************************************************************************
5030 template< typename Type > // Data type of the matrix
5031 inline bool DynamicMatrix<Type,true>::isAligned() const noexcept
5032 {
5033  return ( usePadding || rows() % SIMDSIZE == 0UL );
5034 }
5036 //*************************************************************************************************
5037 
5038 
5039 //*************************************************************************************************
5050 template< typename Type > // Data type of the matrix
5051 inline bool DynamicMatrix<Type,true>::canSMPAssign() const noexcept
5052 {
5053  return ( rows() * columns() >= SMP_DMATASSIGN_THRESHOLD );
5054 }
5056 //*************************************************************************************************
5057 
5058 
5059 //*************************************************************************************************
5074 template< typename Type > // Data type of the matrix
5076  DynamicMatrix<Type,true>::load( size_t i, size_t j ) const noexcept
5077 {
5078  if( usePadding )
5079  return loada( i, j );
5080  else
5081  return loadu( i, j );
5082 }
5084 //*************************************************************************************************
5085 
5086 
5087 //*************************************************************************************************
5102 template< typename Type > // Data type of the matrix
5104  DynamicMatrix<Type,true>::loada( size_t i, size_t j ) const noexcept
5105 {
5106  using blaze::loada;
5107 
5109 
5110  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5111  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5112  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5113  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5114  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5115 
5116  return loada( v_+i+j*mm_ );
5117 }
5119 //*************************************************************************************************
5120 
5121 
5122 //*************************************************************************************************
5137 template< typename Type > // Data type of the matrix
5139  DynamicMatrix<Type,true>::loadu( size_t i, size_t j ) const noexcept
5140 {
5141  using blaze::loadu;
5142 
5144 
5145  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5146  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5147  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5148 
5149  return loadu( v_+i+j*mm_ );
5150 }
5152 //*************************************************************************************************
5153 
5154 
5155 //*************************************************************************************************
5171 template< typename Type > // Data type of the matrix
5173  DynamicMatrix<Type,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5174 {
5175  if( usePadding )
5176  storea( i, j, value );
5177  else
5178  storeu( i, j, value );
5179 }
5181 //*************************************************************************************************
5182 
5183 
5184 //*************************************************************************************************
5200 template< typename Type > // Data type of the matrix
5202  DynamicMatrix<Type,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5203 {
5204  using blaze::storea;
5205 
5207 
5208  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5209  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5210  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5211  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5212  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5213 
5214  storea( v_+i+j*mm_, value );
5215 }
5217 //*************************************************************************************************
5218 
5219 
5220 //*************************************************************************************************
5236 template< typename Type > // Data type of the matrix
5238  DynamicMatrix<Type,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5239 {
5240  using blaze::storeu;
5241 
5243 
5244  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5245  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5246  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5247 
5248  storeu( v_+i+j*mm_, value );
5249 }
5251 //*************************************************************************************************
5252 
5253 
5254 //*************************************************************************************************
5271 template< typename Type > // Data type of the matrix
5273  DynamicMatrix<Type,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5274 {
5275  using blaze::stream;
5276 
5278 
5279  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5280  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= mm_, "Invalid row access index" );
5281  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5282  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5283  BLAZE_INTERNAL_ASSERT( checkAlignment( v_+i+j*mm_ ), "Invalid alignment detected" );
5284 
5285  stream( v_+i+j*mm_, value );
5286 }
5288 //*************************************************************************************************
5289 
5290 
5291 //*************************************************************************************************
5303 template< typename Type > // Data type of the matrix
5304 template< typename MT > // Type of the right-hand side dense matrix
5305 inline auto DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
5306  -> DisableIf_t< VectorizedAssign_v<MT> >
5307 {
5308  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5309  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5310 
5311  const size_t ipos( m_ & size_t(-2) );
5312  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5313 
5314  for( size_t j=0UL; j<n_; ++j ) {
5315  for( size_t i=0UL; i<ipos; i+=2UL ) {
5316  v_[i +j*mm_] = (~rhs)(i ,j);
5317  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
5318  }
5319  if( ipos < m_ ) {
5320  v_[ipos+j*mm_] = (~rhs)(ipos,j);
5321  }
5322  }
5323 }
5325 //*************************************************************************************************
5326 
5327 
5328 //*************************************************************************************************
5340 template< typename Type > // Data type of the matrix
5341 template< typename MT > // Type of the right-hand side dense matrix
5342 inline auto DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
5343  -> EnableIf_t< VectorizedAssign_v<MT> >
5344 {
5346 
5347  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5348  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5349 
5350  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5351 
5352  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5353  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5354 
5355  if( usePadding && useStreaming &&
5356  ( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) ) && !(~rhs).isAliased( this ) )
5357  {
5358  for( size_t j=0UL; j<n_; ++j )
5359  {
5360  size_t i( 0UL );
5361  Iterator left( begin(j) );
5362  ConstIterator_t<MT> right( (~rhs).begin(j) );
5363 
5364  for( ; i<ipos; i+=SIMDSIZE ) {
5365  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5366  }
5367  for( ; remainder && i<m_; ++i ) {
5368  *left = *right; ++left; ++right;
5369  }
5370  }
5371  }
5372  else
5373  {
5374  for( size_t j=0UL; j<n_; ++j )
5375  {
5376  size_t i( 0UL );
5377  Iterator left( begin(j) );
5378  ConstIterator_t<MT> right( (~rhs).begin(j) );
5379 
5380  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5381  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5382  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5383  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5384  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5385  }
5386  for( ; i<ipos; i+=SIMDSIZE ) {
5387  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5388  }
5389  for( ; remainder && i<m_; ++i ) {
5390  *left = *right; ++left; ++right;
5391  }
5392  }
5393  }
5394 }
5396 //*************************************************************************************************
5397 
5398 
5399 //*************************************************************************************************
5411 template< typename Type > // Data type of the matrix
5412 template< typename MT > // Type of the right-hand side dense matrix
5413 inline void DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,false>& rhs )
5414 {
5416 
5417  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5418  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5419 
5420  constexpr size_t block( BLOCK_SIZE );
5421 
5422  for( size_t jj=0UL; jj<n_; jj+=block ) {
5423  const size_t jend( min( n_, jj+block ) );
5424  for( size_t ii=0UL; ii<m_; ii+=block ) {
5425  const size_t iend( min( m_, ii+block ) );
5426  for( size_t j=jj; j<jend; ++j ) {
5427  for( size_t i=ii; i<iend; ++i ) {
5428  v_[i+j*mm_] = (~rhs)(i,j);
5429  }
5430  }
5431  }
5432  }
5433 }
5435 //*************************************************************************************************
5436 
5437 
5438 //*************************************************************************************************
5450 template< typename Type > // Data type of the matrix
5451 template< typename MT > // Type of the right-hand side sparse matrix
5452 inline void DynamicMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
5453 {
5454  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5455  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5456 
5457  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5458  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5459  v_[element->index()+j*mm_] = element->value();
5460 }
5462 //*************************************************************************************************
5463 
5464 
5465 //*************************************************************************************************
5477 template< typename Type > // Data type of the matrix
5478 template< typename MT > // Type of the right-hand side sparse matrix
5479 inline void DynamicMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
5480 {
5482 
5483  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5484  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5485 
5486  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5487  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5488  v_[i+element->index()*mm_] = element->value();
5489 }
5491 //*************************************************************************************************
5492 
5493 
5494 //*************************************************************************************************
5506 template< typename Type > // Data type of the matrix
5507 template< typename MT > // Type of the right-hand side dense matrix
5508 inline auto DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
5509  -> DisableIf_t< VectorizedAddAssign_v<MT> >
5510 {
5511  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5512  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5513 
5514  for( size_t j=0UL; j<n_; ++j )
5515  {
5516  if( IsDiagonal_v<MT> )
5517  {
5518  v_[j+j*mm_] += (~rhs)(j,j);
5519  }
5520  else
5521  {
5522  const size_t ibegin( ( IsLower_v<MT> )
5523  ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5524  :( 0UL ) );
5525  const size_t iend ( ( IsUpper_v<MT> )
5526  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5527  :( m_ ) );
5528  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5529 
5530  size_t i( ibegin );
5531 
5532  for( ; (i+2UL) <= iend; i+=2UL ) {
5533  v_[i +j*mm_] += (~rhs)(i ,j);
5534  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
5535  }
5536  if( i < iend ) {
5537  v_[i+j*mm_] += (~rhs)(i,j);
5538  }
5539  }
5540  }
5541 }
5543 //*************************************************************************************************
5544 
5545 
5546 //*************************************************************************************************
5558 template< typename Type > // Data type of the matrix
5559 template< typename MT > // Type of the right-hand side dense matrix
5560 inline auto DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
5561  -> EnableIf_t< VectorizedAddAssign_v<MT> >
5562 {
5565 
5566  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5567  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5568 
5569  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5570 
5571  for( size_t j=0UL; j<n_; ++j )
5572  {
5573  const size_t ibegin( ( IsLower_v<MT> )
5574  ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) & size_t(-SIMDSIZE) )
5575  :( 0UL ) );
5576  const size_t iend ( ( IsUpper_v<MT> )
5577  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5578  :( m_ ) );
5579  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5580 
5581  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5582  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5583 
5584  size_t i( ibegin );
5585  Iterator left( begin(j) + ibegin );
5586  ConstIterator_t<MT> right( (~rhs).begin(j) + ibegin );
5587 
5588  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5589  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5590  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5591  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5592  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5593  }
5594  for( ; i<ipos; i+=SIMDSIZE ) {
5595  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5596  }
5597  for( ; remainder && i<iend; ++i ) {
5598  *left += *right; ++left; ++right;
5599  }
5600  }
5601 }
5603 //*************************************************************************************************
5604 
5605 
5606 //*************************************************************************************************
5618 template< typename Type > // Data type of the matrix
5619 template< typename MT > // Type of the right-hand side dense matrix
5620 inline void DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,false>& rhs )
5621 {
5623 
5624  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5625  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5626 
5627  constexpr size_t block( BLOCK_SIZE );
5628 
5629  for( size_t jj=0UL; jj<n_; jj+=block ) {
5630  const size_t jend( min( n_, jj+block ) );
5631  for( size_t ii=0UL; ii<m_; ii+=block )
5632  {
5633  if( IsLower_v<MT> && ii < jj ) continue;
5634  if( IsUpper_v<MT> && ii > jj ) break;
5635 
5636  for( size_t j=jj; j<jend; ++j )
5637  {
5638  const size_t ibegin( ( IsLower_v<MT> )
5639  ?( max( ( IsStrictlyLower_v<MT> ? j+1UL : j ), ii ) )
5640  :( ii ) );
5641  const size_t iend ( ( IsUpper_v<MT> )
5642  ?( min( ( IsStrictlyUpper_v<MT> ? j : j+1UL ), m_, ii+block ) )
5643  :( min( m_, ii+block ) ) );
5644  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5645 
5646  for( size_t i=ibegin; i<iend; ++i ) {
5647  v_[i+j*mm_] += (~rhs)(i,j);
5648  }
5649  }
5650  }
5651  }
5652 }
5654 //*************************************************************************************************
5655 
5656 
5657 //*************************************************************************************************
5669 template< typename Type > // Data type of the matrix
5670 template< typename MT > // Type of the right-hand side sparse matrix
5671 inline void DynamicMatrix<Type,true>::addAssign( const SparseMatrix<MT,true>& rhs )
5672 {
5673  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5674  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5675 
5676  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5677  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5678  v_[element->index()+j*mm_] += element->value();
5679 }
5681 //*************************************************************************************************
5682 
5683 
5684 //*************************************************************************************************
5696 template< typename Type > // Data type of the matrix
5697 template< typename MT > // Type of the right-hand side sparse matrix
5698 inline void DynamicMatrix<Type,true>::addAssign( const SparseMatrix<MT,false>& rhs )
5699 {
5701 
5702  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5703  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5704 
5705  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5706  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5707  v_[i+element->index()*mm_] += element->value();
5708 }
5710 //*************************************************************************************************
5711 
5712 
5713 //*************************************************************************************************
5725 template< typename Type > // Data type of the matrix
5726 template< typename MT > // Type of the right-hand side dense matrix
5727 inline auto DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
5728  -> DisableIf_t< VectorizedSubAssign_v<MT> >
5729 {
5730  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5731  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5732 
5733  for( size_t j=0UL; j<n_; ++j )
5734  {
5735  if( IsDiagonal_v<MT> )
5736  {
5737  v_[j+j*mm_] -= (~rhs)(j,j);
5738  }
5739  else
5740  {
5741  const size_t ibegin( ( IsLower_v<MT> )
5742  ?( IsStrictlyLower_v<MT> ? j+1UL : j )
5743  :( 0UL ) );
5744  const size_t iend ( ( IsUpper_v<MT> )
5745  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5746  :( m_ ) );
5747  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5748 
5749  size_t i( ibegin );
5750 
5751  for( ; (i+2UL) <= iend; i+=2UL ) {
5752  v_[i +j*mm_] -= (~rhs)(i ,j);
5753  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
5754  }
5755  if( i < iend ) {
5756  v_[i+j*mm_] -= (~rhs)(i,j);
5757  }
5758  }
5759  }
5760 }
5762 //*************************************************************************************************
5763 
5764 
5765 //*************************************************************************************************
5777 template< typename Type > // Data type of the matrix
5778 template< typename MT > // Type of the right-hand side dense matrix
5779 inline auto DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
5780  -> EnableIf_t< VectorizedSubAssign_v<MT> >
5781 {
5784 
5785  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5786  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5787 
5788  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5789 
5790  for( size_t j=0UL; j<n_; ++j )
5791  {
5792  const size_t ibegin( ( IsLower_v<MT> )
5793  ?( ( IsStrictlyLower_v<MT> ? j+1UL : j ) & size_t(-SIMDSIZE) )
5794  :( 0UL ) );
5795  const size_t iend ( ( IsUpper_v<MT> )
5796  ?( IsStrictlyUpper_v<MT> ? j : j+1UL )
5797  :( m_ ) );
5798  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5799 
5800  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5801  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5802 
5803  size_t i( ibegin );
5804  Iterator left( begin(j) + ibegin );
5805  ConstIterator_t<MT> right( (~rhs).begin(j) + ibegin );
5806 
5807  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5808  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5809  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5810  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5811  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5812  }
5813  for( ; i<ipos; i+=SIMDSIZE ) {
5814  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5815  }
5816  for( ; remainder && i<iend; ++i ) {
5817  *left -= *right; ++left; ++right;
5818  }
5819  }
5820 }
5822 //*************************************************************************************************
5823 
5824 
5825 //*************************************************************************************************
5837 template< typename Type > // Data type of the matrix
5838 template< typename MT > // Type of the right-hand side dense matrix
5839 inline void DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,false>& rhs )
5840 {
5842 
5843  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5844  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5845 
5846  constexpr size_t block( BLOCK_SIZE );
5847 
5848  for( size_t jj=0UL; jj<n_; jj+=block ) {
5849  const size_t jend( min( n_, jj+block ) );
5850  for( size_t ii=0UL; ii<m_; ii+=block )
5851  {
5852  if( IsLower_v<MT> && ii < jj ) continue;
5853  if( IsUpper_v<MT> && ii > jj ) break;
5854 
5855  for( size_t j=jj; j<jend; ++j )
5856  {
5857  const size_t ibegin( ( IsLower_v<MT> )
5858  ?( max( ( IsStrictlyLower_v<MT> ? j+1UL : j ), ii ) )
5859  :( ii ) );
5860  const size_t iend ( ( IsUpper_v<MT> )
5861  ?( min( ( IsStrictlyUpper_v<MT> ? j : j+1UL ), m_, ii+block ) )
5862  :( min( m_, ii+block ) ) );
5863  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5864 
5865  for( size_t i=ibegin; i<iend; ++i ) {
5866  v_[i+j*mm_] -= (~rhs)(i,j);
5867  }
5868  }
5869  }
5870  }
5871 }
5873 //*************************************************************************************************
5874 
5875 
5876 //*************************************************************************************************
5888 template< typename Type > // Data type of the matrix
5889 template< typename MT > // Type of the right-hand side sparse matrix
5890 inline void DynamicMatrix<Type,true>::subAssign( const SparseMatrix<MT,true>& rhs )
5891 {
5892  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5893  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5894 
5895  for( size_t j=0UL; j<(~rhs).columns(); ++j )
5896  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5897  v_[element->index()+j*mm_] -= element->value();
5898 }
5900 //*************************************************************************************************
5901 
5902 
5903 //*************************************************************************************************
5915 template< typename Type > // Data type of the matrix
5916 template< typename MT > // Type of the right-hand side sparse matrix
5917 inline void DynamicMatrix<Type,true>::subAssign( const SparseMatrix<MT,false>& rhs )
5918 {
5920 
5921  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5922  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5923 
5924  for( size_t i=0UL; i<(~rhs).rows(); ++i )
5925  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5926  v_[i+element->index()*mm_] -= element->value();
5927 }
5929 //*************************************************************************************************
5930 
5931 
5932 //*************************************************************************************************
5944 template< typename Type > // Data type of the matrix
5945 template< typename MT > // Type of the right-hand side dense matrix
5946 inline auto DynamicMatrix<Type,true>::schurAssign( const DenseMatrix<MT,true>& rhs )
5947  -> DisableIf_t< VectorizedSchurAssign_v<MT> >
5948 {
5949  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5950  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5951 
5952  const size_t ipos( m_ & size_t(-2) );
5953  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ipos, "Invalid end calculation" );
5954 
5955  for( size_t j=0UL; j<n_; ++j ) {
5956  for( size_t i=0UL; (i+2UL) <= ipos; i+=2UL ) {
5957  v_[i +j*mm_] *= (~rhs)(i ,j);
5958  v_[i+1+j*mm_] *= (~rhs)(i+1,j);
5959  }
5960  if( ipos < m_ ) {
5961  v_[ipos+j*mm_] *= (~rhs)(ipos,j);
5962  }
5963  }
5964 }
5966 //*************************************************************************************************
5967 
5968 
5969 //*************************************************************************************************
5981 template< typename Type > // Data type of the matrix
5982 template< typename MT > // Type of the right-hand side dense matrix
5983 inline auto DynamicMatrix<Type,true>::schurAssign( const DenseMatrix<MT,true>& rhs )
5984  -> EnableIf_t< VectorizedSchurAssign_v<MT> >
5985 {
5987 
5988  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
5989  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
5990 
5991  constexpr bool remainder( !usePadding || !IsPadded_v<MT> );
5992 
5993  for( size_t j=0UL; j<n_; ++j )
5994  {
5995  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5996  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5997 
5998  size_t i( 0UL );
5999  Iterator left( begin(j) );
6000  ConstIterator_t<MT> right( (~rhs).begin(j) );
6001 
6002  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6003  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6004  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6005  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6006  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6007  }
6008  for( ; i<ipos; i+=SIMDSIZE ) {
6009  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6010  }
6011  for( ; remainder && i<m_; ++i ) {
6012  *left *= *right; ++left; ++right;
6013  }
6014  }
6015 }
6017 //*************************************************************************************************
6018 
6019 
6020 //*************************************************************************************************
6032 template< typename Type > // Data type of the matrix
6033 template< typename MT > // Type of the right-hand side dense matrix
6034 inline void DynamicMatrix<Type,true>::schurAssign( const DenseMatrix<MT,false>& rhs )
6035 {
6037 
6038  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6039  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6040 
6041  constexpr size_t block( BLOCK_SIZE );
6042 
6043  for( size_t jj=0UL; jj<n_; jj+=block ) {
6044  const size_t jend( min( n_, jj+block ) );
6045  for( size_t ii=0UL; ii<m_; ii+=block ) {
6046  const size_t iend( min( m_, ii+block ) );
6047  for( size_t j=jj; j<jend; ++j ) {
6048  for( size_t i=ii; i<iend; ++i ) {
6049  v_[i+j*mm_] *= (~rhs)(i,j);
6050  }
6051  }
6052  }
6053  }
6054 }
6056 //*************************************************************************************************
6057 
6058 
6059 //*************************************************************************************************
6071 template< typename Type > // Data type of the matrix
6072 template< typename MT > // Type of the right-hand side sparse matrix
6073 inline void DynamicMatrix<Type,true>::schurAssign( const SparseMatrix<MT,true>& rhs )
6074 {
6075  using blaze::reset;
6076 
6077  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6078  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6079 
6080  for( size_t j=0UL; j<n_; ++j )
6081  {
6082  size_t i( 0UL );
6083 
6084  for( auto element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
6085  for( ; i<element->index(); ++i )
6086  reset( v_[i+j*mm_] );
6087  v_[i+j*mm_] *= element->value();
6088  ++i;
6089  }
6090 
6091  for( ; i<m_; ++i ) {
6092  reset( v_[i+j*mm_] );
6093  }
6094  }
6095 }
6097 //*************************************************************************************************
6098 
6099 
6100 //*************************************************************************************************
6112 template< typename Type > // Data type of the matrix
6113 template< typename MT > // Type of the right-hand side sparse matrix
6114 inline void DynamicMatrix<Type,true>::schurAssign( const SparseMatrix<MT,false>& rhs )
6115 {
6116  using blaze::reset;
6117 
6119 
6120  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
6121  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
6122 
6123  for( size_t i=0UL; i<m_; ++i )
6124  {
6125  size_t j( 0UL );
6126 
6127  for( auto element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
6128  for( ; j<element->index(); ++j )
6129  reset( v_[i+j*mm_] );
6130  v_[i+j*mm_] *= element->value();
6131  ++j;
6132  }
6133 
6134  for( ; j<n_; ++j ) {
6135  reset( v_[i+j*mm_] );
6136  }
6137  }
6138 }
6140 //*************************************************************************************************
6141 
6142 
6143 
6144 
6145 
6146 
6147 
6148 
6149 //=================================================================================================
6150 //
6151 // DYNAMICMATRIX OPERATORS
6152 //
6153 //=================================================================================================
6154 
6155 //*************************************************************************************************
6158 template< typename Type, bool SO >
6159 void reset( DynamicMatrix<Type,SO>& m );
6160 
6161 template< typename Type, bool SO >
6162 void reset( DynamicMatrix<Type,SO>& m, size_t i );
6163 
6164 template< typename Type, bool SO >
6165 void clear( DynamicMatrix<Type,SO>& m );
6166 
6167 template< bool RF, typename Type, bool SO >
6168 bool isDefault( const DynamicMatrix<Type,SO>& m );
6169 
6170 template< typename Type, bool SO >
6171 bool isIntact( const DynamicMatrix<Type,SO>& m ) noexcept;
6172 
6173 template< typename Type, bool SO >
6174 void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) noexcept;
6176 //*************************************************************************************************
6177 
6178 
6179 //*************************************************************************************************
6186 template< typename Type // Data type of the matrix
6187  , bool SO > // Storage order
6189 {
6190  m.reset();
6191 }
6192 //*************************************************************************************************
6193 
6194 
6195 //*************************************************************************************************
6208 template< typename Type // Data type of the matrix
6209  , bool SO > // Storage order
6210 inline void reset( DynamicMatrix<Type,SO>& m, size_t i )
6211 {
6212  m.reset( i );
6213 }
6214 //*************************************************************************************************
6215 
6216 
6217 //*************************************************************************************************
6224 template< typename Type // Data type of the matrix
6225  , bool SO > // Storage order
6227 {
6228  m.clear();
6229 }
6230 //*************************************************************************************************
6231 
6232 
6233 //*************************************************************************************************
6258 template< bool RF // Relaxation flag
6259  , typename Type // Data type of the matrix
6260  , bool SO > // Storage order
6261 inline bool isDefault( const DynamicMatrix<Type,SO>& m )
6262 {
6263  return ( m.rows() == 0UL && m.columns() == 0UL );
6264 }
6265 //*************************************************************************************************
6266 
6267 
6268 //*************************************************************************************************
6286 template< typename Type // Data type of the matrix
6287  , bool SO > // Storage order
6288 inline bool isIntact( const DynamicMatrix<Type,SO>& m ) noexcept
6289 {
6290  return m.isIntact();
6291 }
6292 //*************************************************************************************************
6293 
6294 
6295 //*************************************************************************************************
6303 template< typename Type // Data type of the matrix
6304  , bool SO > // Storage order
6306 {
6307  a.swap( b );
6308 }
6309 //*************************************************************************************************
6310 
6311 
6312 
6313 
6314 //=================================================================================================
6315 //
6316 // HASCONSTDATAACCESS SPECIALIZATIONS
6317 //
6318 //=================================================================================================
6319 
6320 //*************************************************************************************************
6322 template< typename T, bool SO >
6323 struct HasConstDataAccess< DynamicMatrix<T,SO> >
6324  : public TrueType
6325 {};
6327 //*************************************************************************************************
6328 
6329 
6330 
6331 
6332 //=================================================================================================
6333 //
6334 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6335 //
6336 //=================================================================================================
6337 
6338 //*************************************************************************************************
6340 template< typename T, bool SO >
6341 struct HasMutableDataAccess< DynamicMatrix<T,SO> >
6342  : public TrueType
6343 {};
6345 //*************************************************************************************************
6346 
6347 
6348 
6349 
6350 //=================================================================================================
6351 //
6352 // ISALIGNED SPECIALIZATIONS
6353 //
6354 //=================================================================================================
6355 
6356 //*************************************************************************************************
6358 template< typename T, bool SO >
6359 struct IsAligned< DynamicMatrix<T,SO> >
6360  : public BoolConstant<usePadding>
6361 {};
6363 //*************************************************************************************************
6364 
6365 
6366 
6367 
6368 //=================================================================================================
6369 //
6370 // ISCONTIGUOUS SPECIALIZATIONS
6371 //
6372 //=================================================================================================
6373 
6374 //*************************************************************************************************
6376 template< typename T, bool SO >
6377 struct IsContiguous< DynamicMatrix<T,SO> >
6378  : public TrueType
6379 {};
6381 //*************************************************************************************************
6382 
6383 
6384 
6385 
6386 //=================================================================================================
6387 //
6388 // ISPADDED SPECIALIZATIONS
6389 //
6390 //=================================================================================================
6391 
6392 //*************************************************************************************************
6394 template< typename T, bool SO >
6395 struct IsPadded< DynamicMatrix<T,SO> >
6396  : public BoolConstant<usePadding>
6397 {};
6399 //*************************************************************************************************
6400 
6401 
6402 
6403 
6404 //=================================================================================================
6405 //
6406 // ISRESIZABLE SPECIALIZATIONS
6407 //
6408 //=================================================================================================
6409 
6410 //*************************************************************************************************
6412 template< typename T, bool SO >
6413 struct IsResizable< DynamicMatrix<T,SO> >
6414  : public TrueType
6415 {};
6417 //*************************************************************************************************
6418 
6419 
6420 
6421 
6422 //=================================================================================================
6423 //
6424 // ISSHRINKABLE SPECIALIZATIONS
6425 //
6426 //=================================================================================================
6427 
6428 //*************************************************************************************************
6430 template< typename T, bool SO >
6431 struct IsShrinkable< DynamicMatrix<T,SO> >
6432  : public TrueType
6433 {};
6435 //*************************************************************************************************
6436 
6437 
6438 
6439 
6440 //=================================================================================================
6441 //
6442 // ADDTRAIT SPECIALIZATIONS
6443 //
6444 //=================================================================================================
6445 
6446 //*************************************************************************************************
6448 template< typename T1, typename T2 >
6449 struct AddTraitEval2< T1, T2
6450  , EnableIf_t< IsMatrix_v<T1> &&
6451  IsMatrix_v<T2> &&
6452  ( IsDenseMatrix_v<T1> || IsDenseMatrix_v<T2> ) &&
6453  ( Size_v<T1,0UL> == DefaultSize_v ) &&
6454  ( Size_v<T2,0UL> == DefaultSize_v ) &&
6455  ( Size_v<T1,1UL> == DefaultSize_v ) &&
6456  ( Size_v<T2,1UL> == DefaultSize_v ) &&
6457  ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
6458  ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
6459  ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) &&
6460  ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
6461 {
6462  using ET1 = ElementType_t<T1>;
6463  using ET2 = ElementType_t<T2>;
6464 
6465  static constexpr bool SO1 = StorageOrder_v<T1>;
6466  static constexpr bool SO2 = StorageOrder_v<T2>;
6467 
6468  static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
6469  ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6470  ? ( IsSymmetric_v<T1>
6471  ? SO2
6472  : SO1 )
6473  : SO1 && SO2 )
6474  : ( IsDenseMatrix_v<T1>
6475  ? SO1
6476  : SO2 ) );
6477 
6478  using Type = DynamicMatrix< AddTrait_t<ET1,ET2>, SO >;
6479 };
6481 //*************************************************************************************************
6482 
6483 
6484 
6485 
6486 //=================================================================================================
6487 //
6488 // SUBTRAIT SPECIALIZATIONS
6489 //
6490 //=================================================================================================
6491 
6492 //*************************************************************************************************
6494 template< typename T1, typename T2 >
6495 struct SubTraitEval2< T1, T2
6496  , EnableIf_t< IsMatrix_v<T1> &&
6497  IsMatrix_v<T2> &&
6498  ( IsDenseMatrix_v<T1> || IsDenseMatrix_v<T2> ) &&
6499  ( Size_v<T1,0UL> == DefaultSize_v ) &&
6500  ( Size_v<T2,0UL> == DefaultSize_v ) &&
6501  ( Size_v<T1,1UL> == DefaultSize_v ) &&
6502  ( Size_v<T2,1UL> == DefaultSize_v ) &&
6503  ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
6504  ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
6505  ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) &&
6506  ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
6507 {
6508  using ET1 = ElementType_t<T1>;
6509  using ET2 = ElementType_t<T2>;
6510 
6511  static constexpr bool SO1 = StorageOrder_v<T1>;
6512  static constexpr bool SO2 = StorageOrder_v<T2>;
6513 
6514  static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
6515  ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6516  ? ( IsSymmetric_v<T1>
6517  ? SO2
6518  : SO1 )
6519  : SO1 && SO2 )
6520  : ( IsDenseMatrix_v<T1>
6521  ? SO1
6522  : SO2 ) );
6523 
6524  using Type = DynamicMatrix< SubTrait_t<ET1,ET2>, SO >;
6525 };
6527 //*************************************************************************************************
6528 
6529 
6530 
6531 
6532 //=================================================================================================
6533 //
6534 // SCHURTRAIT SPECIALIZATIONS
6535 //
6536 //=================================================================================================
6537 
6538 //*************************************************************************************************
6540 template< typename T1, typename T2 >
6541 struct SchurTraitEval2< T1, T2
6542  , EnableIf_t< IsDenseMatrix_v<T1> &&
6543  IsDenseMatrix_v<T2> &&
6544  ( Size_v<T1,0UL> == DefaultSize_v ) &&
6545  ( Size_v<T2,0UL> == DefaultSize_v ) &&
6546  ( Size_v<T1,1UL> == DefaultSize_v ) &&
6547  ( Size_v<T2,1UL> == DefaultSize_v ) &&
6548  ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
6549  ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
6550  ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) &&
6551  ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
6552 {
6553  using ET1 = ElementType_t<T1>;
6554  using ET2 = ElementType_t<T2>;
6555 
6556  static constexpr bool SO1 = StorageOrder_v<T1>;
6557  static constexpr bool SO2 = StorageOrder_v<T2>;
6558 
6559  static constexpr bool SO = ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6560  ? ( IsSymmetric_v<T1>
6561  ? SO2
6562  : SO1 )
6563  : SO1 && SO2 );
6564 
6565  using Type = DynamicMatrix< MultTrait_t<ET1,ET2>, SO >;
6566 };
6568 //*************************************************************************************************
6569 
6570 
6571 
6572 
6573 //=================================================================================================
6574 //
6575 // MULTTRAIT SPECIALIZATIONS
6576 //
6577 //=================================================================================================
6578 
6579 //*************************************************************************************************
6581 template< typename T1, typename T2 >
6582 struct MultTraitEval2< T1, T2
6583  , EnableIf_t< IsDenseMatrix_v<T1> &&
6584  IsNumeric_v<T2> &&
6585  ( Size_v<T1,0UL> == DefaultSize_v ) &&
6586  ( Size_v<T1,1UL> == DefaultSize_v ) &&
6587  ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
6588  ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) > >
6589 {
6590  using ET1 = ElementType_t<T1>;
6591 
6592  using Type = DynamicMatrix< MultTrait_t<ET1,T2>, StorageOrder_v<T1> >;
6593 };
6594 
6595 template< typename T1, typename T2 >
6596 struct MultTraitEval2< T1, T2
6597  , EnableIf_t< IsNumeric_v<T1> &&
6598  IsDenseMatrix_v<T2> &&
6599  ( Size_v<T2,0UL> == DefaultSize_v ) &&
6600  ( Size_v<T2,1UL> == DefaultSize_v ) &&
6601  ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
6602  ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
6603 {
6604  using ET2 = ElementType_t<T2>;
6605 
6606  using Type = DynamicMatrix< MultTrait_t<T1,ET2>, StorageOrder_v<T2> >;
6607 };
6608 
6609 template< typename T1, typename T2 >
6610 struct MultTraitEval2< T1, T2
6611  , EnableIf_t< IsDenseVector_v<T1> &&
6612  IsDenseVector_v<T2> &&
6613  IsColumnVector_v<T1> &&
6614  IsRowVector_v<T2> &&
6615  ( ( Size_v<T1,0UL> == DefaultSize_v ) ||
6616  ( Size_v<T2,0UL> == DefaultSize_v ) ) &&
6617  ( ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) ||
6618  ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) ) > >
6619 {
6620  using ET1 = ElementType_t<T1>;
6621  using ET2 = ElementType_t<T2>;
6622 
6623  using Type = DynamicMatrix< MultTrait_t<ET1,ET2>, false >;
6624 };
6625 
6626 template< typename T1, typename T2 >
6627 struct MultTraitEval2< T1, T2
6628  , EnableIf_t< IsMatrix_v<T1> &&
6629  IsMatrix_v<T2> &&
6630  ( IsDenseMatrix_v<T1> || IsDenseMatrix_v<T2> ) &&
6631  ( ( Size_v<T1,0UL> == DefaultSize_v &&
6632  ( !IsSquare_v<T1> || Size_v<T2,0UL> == DefaultSize_v ) ) ||
6633  ( Size_v<T2,1UL> == DefaultSize_v &&
6634  ( !IsSquare_v<T2> || Size_v<T1,1UL> == DefaultSize_v ) ) ) &&
6635  ( ( MaxSize_v<T1,0UL> == DefaultMaxSize_v &&
6636  ( !IsSquare_v<T1> || MaxSize_v<T2,0UL> == DefaultMaxSize_v ) ) ||
6637  ( MaxSize_v<T2,1UL> == DefaultMaxSize_v &&
6638  ( !IsSquare_v<T2> || MaxSize_v<T1,1UL> == DefaultMaxSize_v ) ) ) > >
6639 {
6640  using ET1 = ElementType_t<T1>;
6641  using ET2 = ElementType_t<T2>;
6642 
6643  static constexpr bool SO = ( IsSparseMatrix_v<T1> ? StorageOrder_v<T2> : StorageOrder_v<T1> );
6644 
6645  using Type = DynamicMatrix< MultTrait_t<ET1,ET2>, SO >;
6646 };
6648 //*************************************************************************************************
6649 
6650 
6651 
6652 
6653 //=================================================================================================
6654 //
6655 // KRONTRAIT SPECIALIZATIONS
6656 //
6657 //=================================================================================================
6658 
6659 //*************************************************************************************************
6661 template< typename T1, typename T2 >
6662 struct KronTraitEval2< T1, T2
6663  , EnableIf_t< IsDenseMatrix_v<T1> &&
6664  IsDenseMatrix_v<T2> &&
6665  ( ( Size_v<T1,0UL> == DefaultSize_v ) ||
6666  ( Size_v<T2,0UL> == DefaultSize_v ) ||
6667  ( Size_v<T1,1UL> == DefaultSize_v ) ||
6668  ( Size_v<T2,1UL> == DefaultSize_v ) ) &&
6669  ( ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) ||
6670  ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) ||
6671  ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) ||
6672  ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) ) > >
6673 {
6674  using ET1 = ElementType_t<T1>;
6675  using ET2 = ElementType_t<T2>;
6676 
6677  using Type = DynamicMatrix< MultTrait_t<ET1,ET2>, StorageOrder_v<T2> >;
6678 };
6680 //*************************************************************************************************
6681 
6682 
6683 
6684 
6685 //=================================================================================================
6686 //
6687 // DIVTRAIT SPECIALIZATIONS
6688 //
6689 //=================================================================================================
6690 
6691 //*************************************************************************************************
6693 template< typename T1, typename T2 >
6694 struct DivTraitEval2< T1, T2
6695  , EnableIf_t< IsDenseMatrix_v<T1> &&
6696  IsNumeric_v<T2> &&
6697  ( Size_v<T1,0UL> == DefaultSize_v ) &&
6698  ( Size_v<T1,1UL> == DefaultSize_v ) &&
6699  ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
6700  ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) > >
6701 {
6702  using ET1 = ElementType_t<T1>;
6703 
6704  using Type = DynamicMatrix< DivTrait_t<ET1,T2>, StorageOrder_v<T1> >;
6705 };
6707 //*************************************************************************************************
6708 
6709 
6710 
6711 
6712 //=================================================================================================
6713 //
6714 // MAPTRAIT SPECIALIZATIONS
6715 //
6716 //=================================================================================================
6717 
6718 //*************************************************************************************************
6720 template< typename T, typename OP >
6721 struct UnaryMapTraitEval2< T, OP
6722  , EnableIf_t< IsDenseMatrix_v<T> &&
6723  ( Size_v<T,0UL> == DefaultSize_v ||
6724  Size_v<T,1UL> == DefaultSize_v ) &&
6725  ( MaxSize_v<T,0UL> == DefaultMaxSize_v ||
6726  MaxSize_v<T,1UL> == DefaultMaxSize_v ) > >
6727 {
6728  using ET = ElementType_t<T>;
6729 
6730  using Type = DynamicMatrix< MapTrait_t<ET,OP>, StorageOrder_v<T> >;
6731 };
6733 //*************************************************************************************************
6734 
6735 
6736 //*************************************************************************************************
6738 template< typename T1, typename T2, typename OP >
6739 struct BinaryMapTraitEval2< T1, T2, OP
6740  , EnableIf_t< IsMatrix_v<T1> &&
6741  IsMatrix_v<T2> &&
6742  ( Size_v<T1,0UL> == DefaultSize_v ) &&
6743  ( Size_v<T2,0UL> == DefaultSize_v ) &&
6744  ( Size_v<T1,1UL> == DefaultSize_v ) &&
6745  ( Size_v<T2,1UL> == DefaultSize_v ) &&
6746  ( MaxSize_v<T1,0UL> == DefaultMaxSize_v ) &&
6747  ( MaxSize_v<T2,0UL> == DefaultMaxSize_v ) &&
6748  ( MaxSize_v<T1,1UL> == DefaultMaxSize_v ) &&
6749  ( MaxSize_v<T2,1UL> == DefaultMaxSize_v ) > >
6750 {
6751  using ET1 = ElementType_t<T1>;
6752  using ET2 = ElementType_t<T2>;
6753 
6754  static constexpr bool SO1 = StorageOrder_v<T1>;
6755  static constexpr bool SO2 = StorageOrder_v<T2>;
6756 
6757  static constexpr bool SO = ( IsDenseMatrix_v<T1> && IsDenseMatrix_v<T2>
6758  ? ( IsSymmetric_v<T1> ^ IsSymmetric_v<T2>
6759  ? ( IsSymmetric_v<T1>
6760  ? SO2
6761  : SO1 )
6762  : SO1 && SO2 )
6763  : ( IsDenseMatrix_v<T1>
6764  ? SO1
6765  : SO2 ) );
6766 
6767  using Type = DynamicMatrix< MapTrait_t<ET1,ET2,OP>, SO >;
6768 };
6770 //*************************************************************************************************
6771 
6772 
6773 
6774 
6775 //=================================================================================================
6776 //
6777 // EXPANDTRAIT SPECIALIZATIONS
6778 //
6779 //=================================================================================================
6780 
6781 //*************************************************************************************************
6783 template< typename T // Type to be expanded
6784  , size_t E > // Compile time expansion
6785 struct ExpandTraitEval2< T, E
6786  , EnableIf_t< IsDenseVector_v<T> &&
6787  ( ( E == inf ) ||
6788  ( ( Size_v<T,0UL> == DefaultSize_v ) &&
6789  ( MaxSize_v<T,0UL> == DefaultMaxSize_v ) ) ) > >
6790 {
6791  static constexpr bool TF = ( IsColumnVector_v<T> ? columnMajor : rowMajor );
6792 
6793  using Type = DynamicMatrix< ElementType_t<T>, TF >;
6794 };
6796 //*************************************************************************************************
6797 
6798 
6799 
6800 
6801 //=================================================================================================
6802 //
6803 // HIGHTYPE SPECIALIZATIONS
6804 //
6805 //=================================================================================================
6806 
6807 //*************************************************************************************************
6809 template< typename T1, bool SO, typename T2 >
6810 struct HighType< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6811 {
6812  using Type = DynamicMatrix< typename HighType<T1,T2>::Type, SO >;
6813 };
6815 //*************************************************************************************************
6816 
6817 
6818 
6819 
6820 //=================================================================================================
6821 //
6822 // LOWTYPE SPECIALIZATIONS
6823 //
6824 //=================================================================================================
6825 
6826 //*************************************************************************************************
6828 template< typename T1, bool SO, typename T2 >
6829 struct LowType< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
6830 {
6831  using Type = DynamicMatrix< typename LowType<T1,T2>::Type, SO >;
6832 };
6834 //*************************************************************************************************
6835 
6836 
6837 
6838 
6839 //=================================================================================================
6840 //
6841 // SUBMATRIXTRAIT SPECIALIZATIONS
6842 //
6843 //=================================================================================================
6844 
6845 //*************************************************************************************************
6847 template< typename MT >
6848 struct SubmatrixTraitEval2< MT, inf, inf, inf, inf
6849  , EnableIf_t< IsDenseMatrix_v<MT> &&
6850  ( Size_v<MT,0UL> == DefaultSize_v ||
6851  Size_v<MT,1UL> == DefaultSize_v ) &&
6852  ( MaxSize_v<MT,0UL> == DefaultMaxSize_v ||
6853  MaxSize_v<MT,1UL> == DefaultMaxSize_v ) > >
6854 {
6855  using Type = DynamicMatrix< RemoveConst_t< ElementType_t<MT> >, StorageOrder_v<MT> >;
6856 };
6858 //*************************************************************************************************
6859 
6860 
6861 
6862 
6863 //=================================================================================================
6864 //
6865 // ROWSTRAIT SPECIALIZATIONS
6866 //
6867 //=================================================================================================
6868 
6869 //*************************************************************************************************
6871 template< typename MT, size_t M >
6872 struct RowsTraitEval2< MT, M
6873  , EnableIf_t< IsDenseMatrix_v<MT> &&
6874  ( M == 0UL || Size_v<MT,1UL> == DefaultSize_v ) &&
6875  ( M == 0UL || MaxSize_v<MT,1UL> == DefaultMaxSize_v ) > >
6876 {
6877  using Type = DynamicMatrix< RemoveConst_t< ElementType_t<MT> >, false >;
6878 };
6880 //*************************************************************************************************
6881 
6882 
6883 
6884 
6885 //=================================================================================================
6886 //
6887 // COLUMNSTRAIT SPECIALIZATIONS
6888 //
6889 //=================================================================================================
6890 
6891 //*************************************************************************************************
6893 template< typename MT, size_t N >
6894 struct ColumnsTraitEval2< MT, N
6895  , EnableIf_t< IsDenseMatrix_v<MT> &&
6896  ( N == 0UL || Size_v<MT,0UL> == DefaultSize_v ) &&
6897  ( N == 0UL || MaxSize_v<MT,0UL> == DefaultMaxSize_v ) > >
6898 {
6899  using Type = DynamicMatrix< RemoveConst_t< ElementType_t<MT> >, true >;
6900 };
6902 //*************************************************************************************************
6903 
6904 } // namespace blaze
6905 
6906 #endif
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,...
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:511
size_t addPadding(size_t value) const noexcept
Add the necessary amount of padding to the given value.
Definition: DynamicMatrix.h:1842
Header file for auxiliary alias declarations.
Headerfile for the generic min algorithm.
BLAZE_ALWAYS_INLINE void storeu(size_t i, size_t j, const SIMDType &value) noexcept
Unaligned store of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2273
Header file for kernel specific block sizes.
Header file for the Schur product trait.
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: DynamicMatrix.h:2067
void reserve(size_t elements)
Setting the minimum capacity of the matrix.
Definition: DynamicMatrix.h:1763
constexpr bool IsMatrix_v
Auxiliary variable template for the IsMatrix type trait.The IsMatrix_v variable template provides a c...
Definition: IsMatrix.h:138
Header file for the nextMultiple shim.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
Header file for the alignment flag values.
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: DynamicMatrix.h:1466
Header file for the subtraction trait.
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: DynamicMatrix.h:2111
Header file for basic type definitions.
auto subAssign(const DenseMatrix< MT, SO > &rhs) -> DisableIf_t< VectorizedSubAssign_v< MT > >
Default implementation of the subtraction assignment of a row-major dense matrix.
Definition: DynamicMatrix.h:2751
DynamicMatrix< Type,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: DynamicMatrix.h:229
Type *BLAZE_RESTRICT v_
The dynamically allocated matrix elements.
Definition: DynamicMatrix.h:514
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:2174
typename T::ResultType ResultType_t
Alias declaration for nested ResultType type definitions.The ResultType_t alias declaration provides ...
Definition: Aliases.h:390
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
Header file for the IsSparseMatrix type trait.
DynamicMatrix & operator=(const Type &rhs)
Homogenous assignment to all matrix elements.
Definition: DynamicMatrix.h:1159
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: DynamicMatrix.h:1686
Header file for the IsDiagonal type trait.
DynamicMatrix() noexcept
The default constructor for DynamicMatrix.
Definition: DynamicMatrix.h:552
Header file for the IsSame and IsStrictlySame type traits.
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
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:2208
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
Type ElementType
Type of the matrix elements.
Definition: DynamicMatrix.h:231
Header file for the IsRowVector type trait.
typename SIMDTrait< T >::Type SIMDTrait_t
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_t alias declaration provid...
Definition: SIMDTrait.h:315
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
Header file for the MAYBE_UNUSED function template.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type,...
Definition: Volatile.h:79
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: DynamicMatrix.h:1135
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric_v< T >)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
Header file for the reset shim.
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:187
Type & Reference
Reference to a non-constant matrix value.
Definition: DynamicMatrix.h:236
This ResultType
Result type for expression template evaluations.
Definition: DynamicMatrix.h:228
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: IntegralConstant.h:132
Header file for all forward declarations of the math module.
Header file for memory allocation and deallocation functionality.
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
Efficient implementation of a dynamic matrix.The DynamicMatrix class template is the representation ...
Definition: DynamicMatrix.h:221
DenseMatrix< This, SO > BaseType
Base type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:227
Header file for the MaxSize type trait.
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:2308
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
constexpr bool rowMajor
Storage order flag for row-major matrices.
Definition: StorageOrder.h:71
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes....
Definition: DenseMatrix.h:81
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes....
Definition: Forward.h:145
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
bool canSMPAssign() const noexcept
Returns whether the matrix can be used in SMP assignments.
Definition: DynamicMatrix.h:2086
Constraint on the data type.
constexpr bool IsDenseMatrix_v
Auxiliary variable template for the IsDenseMatrix type trait.The IsDenseMatrix_v variable template pr...
Definition: IsDenseMatrix.h:138
Header file for the IsMatrix type trait.
~DynamicMatrix()
The destructor for DynamicMatrix.
Definition: DynamicMatrix.h:816
Header file for the SparseMatrix base class.
Header file for the IsSquare type trait.
size_t spacing() const noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DynamicMatrix.h:1499
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
constexpr bool columnMajor
Storage order flag for column-major matrices.
Definition: StorageOrder.h:99
Headerfile for the generic max algorithm.
Header file for the DisableIf class template.
Header file for the LowType type trait.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
constexpr ptrdiff_t DefaultMaxSize_v
Default size of the MaxSize type trait.
Definition: MaxSize.h:72
Header file for the IsSymmetric type trait.
DynamicMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: DynamicMatrix.h:1904
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1361
void shrinkToFit()
Requesting the removal of unused capacity.
Definition: DynamicMatrix.h:1801
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: DynamicMatrix.h:2049
const This & CompositeType
Data type for composite expression templates.
Definition: DynamicMatrix.h:234
Header file for the IsShrinkable type trait.
DynamicMatrix< NewType, SO > Other
The type of the other DynamicMatrix.
Definition: DynamicMatrix.h:250
#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.
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:187
Header file for the expand trait.
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1162
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Type * Pointer
Pointer to a non-constant matrix value.
Definition: DynamicMatrix.h:238
Header file for the HasSIMDAdd type trait.
Header file for the DenseMatrix base class.
Header file for the DenseIterator class template.
decltype(auto) inv(const DenseMatrix< MT, SO > &dm)
Calculation of the inverse of the given dense matrix.
Definition: DMatInvExpr.h:423
constexpr bool IsNumeric_v
Auxiliary variable template for the IsNumeric type trait.The IsNumeric_v variable template provides a...
Definition: IsNumeric.h:143
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,...
Definition: Diagonal.h:79
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: DynamicMatrix.h:276
Header file for the IsLower type trait.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
Header file for the IsAligned type trait.
void extend(size_t m, size_t n, bool preserve=true)
Extending the size of the matrix.
Definition: DynamicMatrix.h:1745
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
#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.
Header file for the Kron product trait.
#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:1599
auto addAssign(const DenseMatrix< MT, SO > &rhs) -> DisableIf_t< VectorizedAddAssign_v< MT > >
Default implementation of the addition assignment of a row-major dense matrix.
Definition: DynamicMatrix.h:2537
decltype(auto) elements(Vector< VT, TF > &vector, REAs... args)
Creating a view on a selection of elements of the given vector.
Definition: Elements.h:139
SIMDTrait_t< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: DynamicMatrix.h:232
Header file for the exception macros of the math module.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1198
void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:738
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:438
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: DynamicMatrix.h:1480
Header file for the IsDenseMatrix type trait.
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:615
Header file for the IsPadded type trait.
const Type & ConstReference
Reference to a constant matrix value.
Definition: DynamicMatrix.h:237
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:2237
Header file for the IsVectorizable type trait.
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: DynamicMatrix.h:944
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: DynamicMatrix.h:844
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:512
Header file for the RemoveConst type trait.
Header file for the IsSIMDCombinable type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type,...
Definition: Symmetric.h:79
Header file for the HasSIMDMult type trait.
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric_v< T >)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Header file for run time assertion macros.
auto schurAssign(const DenseMatrix< MT, SO > &rhs) -> DisableIf_t< VectorizedSchurAssign_v< MT > >
Default implementation of the Schur product assignment of a row-major dense matrix.
Definition: DynamicMatrix.h:2965
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: DynamicMatrix.h:1025
Header file for the addition trait.
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
void clear()
Clearing the matrix.
Definition: DynamicMatrix.h:1643
Header file for the division trait.
Header file for the submatrix trait.
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: DynamicMatrix.h:1069
Constraint on the data type.
Header file for the IsContiguous type trait.
Header file for the columns trait.
Headerfile for the generic transfer algorithm.
size_t m_
The current number of rows of the matrix.
Definition: DynamicMatrix.h:510
static constexpr size_t SIMDSIZE
The number of elements packed within a single SIMD element.
Definition: DynamicMatrix.h:428
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:295
Header file for the cache size of the target architecture.
DynamicMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: DynamicMatrix.h:230
#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,...
Definition: Reference.h:79
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:282
System settings for the restrict keyword.
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: DynamicMatrix.h:2029
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
Constraint on the data type.
auto assign(const DenseMatrix< MT, SO > &rhs) -> DisableIf_t< VectorizedAssign_v< MT > >
Default implementation of the assignment of a row-major dense matrix.
Definition: DynamicMatrix.h:2339
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:114
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
Constraint on the data type.
void swap(DynamicMatrix &m) noexcept
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:1818
Constraint on the data type.
Header file for the HasSIMDSub type trait.
Header file for the HasMutableDataAccess type trait.
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: DynamicMatrix.h:241
constexpr ptrdiff_t DefaultSize_v
Default size of the Size type trait.
Definition: Size.h:72
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: DynamicMatrix.h:1549
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant alias template represents ...
Definition: IntegralConstant.h:110
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
void swap(DynamicMatrix< Type, SO > &a, DynamicMatrix< Type, SO > &b) noexcept
Swapping the contents of two dynamic matrices.
Definition: DynamicMatrix.h:6305
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
Header file for the IsDenseVector type trait.
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
Header file for the rows trait.
typename T::ConstIterator ConstIterator_t
Alias declaration for nested ConstIterator type definitions.The ConstIterator_t alias declaration pro...
Definition: Aliases.h:110
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< 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:74
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
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:2139
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: DynamicMatrix.h:1091
DynamicMatrix< Type, SO > This
Type of this DynamicMatrix instance.
Definition: DynamicMatrix.h:226
DynamicMatrix< Type, SO > Other
The type of the other DynamicMatrix.
Definition: DynamicMatrix.h:260
EnableIf_t< IsBuiltin_v< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:224
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
Header file for the default transpose flag for all vectors of the Blaze library.
Initializer list type of the Blaze library.
bool isIntact() const noexcept
Returns whether the invariants of the dynamic matrix are intact.
Definition: DynamicMatrix.h:1989
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:188
Header file for the alignment check function.
size_t capacity_
The maximum capacity of the matrix.
Definition: DynamicMatrix.h:513
constexpr bool IsDenseVector_v
Auxiliary variable template for the IsDenseVector type trait.The IsDenseVector_v variable template pr...
Definition: IsDenseVector.h:138
Header file for the StorageOrder type trait.
Header file for the IntegralConstant class template.
Resize mechanism to obtain a DynamicMatrix with different fixed dimensions.
Definition: DynamicMatrix.h:259
constexpr Infinity inf
Global Infinity instance.The blaze::inf instance can be used wherever a built-in data type is expecte...
Definition: Infinity.h:1080
Header file for the map trait.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
Rebind mechanism to obtain a DynamicMatrix with different data/element type.
Definition: DynamicMatrix.h:249
DenseIterator< const Type, usePadding > ConstIterator
Iterator over constant elements.
Definition: DynamicMatrix.h:242
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
Header file for the IsUpper type trait.
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: DynamicMatrix.h:1513
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.The IsDiagonal_v variable template provides...
Definition: IsDiagonal.h:148
Header file for the IsColumnVector type trait.
OutputIterator transfer(InputIterator first, InputIterator last, OutputIterator dest)
Transfers the elements from the given source range to the destination range.
Definition: Transfer.h:70
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: DynamicMatrix.h:889
Header file for the IsResizable type trait.
System settings for the inline keywords.
Header file for the Size type trait.
EnableIf_t< IsBuiltin_v< T >, T * > allocate(size_t size)
Aligned array allocation for built-in data types.
Definition: Memory.h:156
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
static constexpr bool simdEnabled
Compilation flag for SIMD optimization.
Definition: DynamicMatrix.h:270
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
const Type & ReturnType
Return type for expression template evaluations.
Definition: DynamicMatrix.h:233
DynamicMatrix & transpose()
In-place transpose of the matrix.
Definition: DynamicMatrix.h:1866
constexpr size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determines the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:108
Header file for the HighType type trait.
Header file for the clear shim.
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: DynamicMatrix.h:239
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825