HybridMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_DENSE_HYBRIDMATRIX_H_
36 #define _BLAZE_MATH_DENSE_HYBRIDMATRIX_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <utility>
45 #include <blaze/math/Aliases.h>
50 #include <blaze/math/Exception.h>
53 #include <blaze/math/Forward.h>
54 #include <blaze/math/Functions.h>
56 #include <blaze/math/shims/Clear.h>
59 #include <blaze/math/SIMD.h>
92 #include <blaze/system/Inline.h>
98 #include <blaze/util/Assert.h>
105 #include <blaze/util/DisableIf.h>
106 #include <blaze/util/EnableIf.h>
108 #include <blaze/util/Memory.h>
109 #include <blaze/util/StaticAssert.h>
110 #include <blaze/util/Template.h>
111 #include <blaze/util/TrueType.h>
112 #include <blaze/util/Types.h>
116 #include <blaze/util/Unused.h>
117 
118 
119 namespace blaze {
120 
121 //=================================================================================================
122 //
123 // CLASS DEFINITION
124 //
125 //=================================================================================================
126 
127 //*************************************************************************************************
213 template< typename Type // Data type of the matrix
214  , size_t M // Number of rows
215  , size_t N // Number of columns
216  , bool SO = defaultStorageOrder > // Storage order
217 class HybridMatrix
218  : public DenseMatrix< HybridMatrix<Type,M,N,SO>, SO >
219 {
220  public:
221  //**Type definitions****************************************************************************
224  using ResultType = This;
227  using ElementType = Type;
229  using ReturnType = const Type&;
230  using CompositeType = const This&;
231 
232  using Reference = Type&;
233  using ConstReference = const Type&;
234  using Pointer = Type*;
235  using ConstPointer = const Type*;
236 
239  //**********************************************************************************************
240 
241  //**Rebind struct definition********************************************************************
244  template< typename NewType > // Data type of the other matrix
245  struct Rebind {
247  };
248  //**********************************************************************************************
249 
250  //**Resize struct definition********************************************************************
253  template< size_t NewM // Number of rows of the other matrix
254  , size_t NewN > // Number of columns of the other matrix
255  struct Resize {
257  };
258  //**********************************************************************************************
259 
260  //**Compilation flags***************************************************************************
262 
266  enum : bool { simdEnabled = IsVectorizable<Type>::value };
267 
269 
272  enum : bool { smpAssignable = false };
273  //**********************************************************************************************
274 
275  //**Constructors********************************************************************************
278  explicit inline HybridMatrix();
279  explicit inline HybridMatrix( size_t m, size_t n );
280  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
281  explicit inline HybridMatrix( initializer_list< initializer_list<Type> > list );
282 
283  template< typename Other >
284  explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
285 
286  template< typename Other, size_t Rows, size_t Cols >
287  explicit inline HybridMatrix( const Other (&array)[Rows][Cols] );
288 
289  inline HybridMatrix( const HybridMatrix& m );
290  template< typename MT, bool SO2 > inline HybridMatrix( const Matrix<MT,SO2>& m );
292  //**********************************************************************************************
293 
294  //**Destructor**********************************************************************************
295  // No explicitly declared destructor.
296  //**********************************************************************************************
297 
298  //**Data access functions***********************************************************************
301  inline Reference operator()( size_t i, size_t j ) noexcept;
302  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
303  inline Reference at( size_t i, size_t j );
304  inline ConstReference at( size_t i, size_t j ) const;
305  inline Pointer data () noexcept;
306  inline ConstPointer data () const noexcept;
307  inline Pointer data ( size_t i ) noexcept;
308  inline ConstPointer data ( size_t i ) const noexcept;
309  inline Iterator begin ( size_t i ) noexcept;
310  inline ConstIterator begin ( size_t i ) const noexcept;
311  inline ConstIterator cbegin( size_t i ) const noexcept;
312  inline Iterator end ( size_t i ) noexcept;
313  inline ConstIterator end ( size_t i ) const noexcept;
314  inline ConstIterator cend ( size_t i ) const noexcept;
316  //**********************************************************************************************
317 
318  //**Assignment operators************************************************************************
321  inline HybridMatrix& operator=( const Type& set );
322  inline HybridMatrix& operator=( initializer_list< initializer_list<Type> > list );
323 
324  template< typename Other, size_t Rows, size_t Cols >
325  inline HybridMatrix& operator=( const Other (&array)[Rows][Cols] );
326 
327  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
328  template< typename MT, bool SO2 > inline HybridMatrix& operator= ( const Matrix<MT,SO2>& rhs );
329  template< typename MT, bool SO2 > inline HybridMatrix& operator+=( const Matrix<MT,SO2>& rhs );
330  template< typename MT, bool SO2 > inline HybridMatrix& operator-=( const Matrix<MT,SO2>& rhs );
331  template< typename MT, bool SO2 > inline HybridMatrix& operator%=( const Matrix<MT,SO2>& rhs );
332  template< typename MT, bool SO2 > inline HybridMatrix& operator*=( const Matrix<MT,SO2>& rhs );
333 
334  template< typename Other >
335  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator*=( Other rhs );
336 
337  template< typename Other >
338  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator/=( Other rhs );
340  //**********************************************************************************************
341 
342  //**Utility functions***************************************************************************
345  inline size_t rows() const noexcept;
346  inline size_t columns() const noexcept;
347  inline constexpr size_t spacing() const noexcept;
348  inline constexpr size_t capacity() const noexcept;
349  inline size_t capacity( size_t i ) const noexcept;
350  inline size_t nonZeros() const;
351  inline size_t nonZeros( size_t i ) const;
352  inline void reset();
353  inline void reset( size_t i );
354  inline void clear();
355  void resize ( size_t m, size_t n, bool preserve=true );
356  inline void extend ( size_t m, size_t n, bool preserve=true );
357  inline void swap( HybridMatrix& m ) noexcept;
359  //**********************************************************************************************
360 
361  //**Numeric functions***************************************************************************
364  inline HybridMatrix& transpose();
365  inline HybridMatrix& ctranspose();
366 
367  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
369  //**********************************************************************************************
370 
371  //**Memory functions****************************************************************************
374  static inline void* operator new ( std::size_t size );
375  static inline void* operator new[]( std::size_t size );
376  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
377  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
378 
379  static inline void operator delete ( void* ptr );
380  static inline void operator delete[]( void* ptr );
381  static inline void operator delete ( void* ptr, const std::nothrow_t& );
382  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
384  //**********************************************************************************************
385 
386  private:
387  //**********************************************************************************************
389  template< typename MT >
391  struct VectorizedAssign {
392  enum : bool { value = useOptimizedKernels &&
393  simdEnabled && MT::simdEnabled &&
396  };
398  //**********************************************************************************************
399 
400  //**********************************************************************************************
402  template< typename MT >
404  struct VectorizedAddAssign {
405  enum : bool { value = useOptimizedKernels &&
406  simdEnabled && MT::simdEnabled &&
411  };
413  //**********************************************************************************************
414 
415  //**********************************************************************************************
417  template< typename MT >
419  struct VectorizedSubAssign {
420  enum : bool { value = useOptimizedKernels &&
421  simdEnabled && MT::simdEnabled &&
426  };
428  //**********************************************************************************************
429 
430  //**********************************************************************************************
432  template< typename MT >
434  struct VectorizedSchurAssign {
435  enum : bool { value = useOptimizedKernels &&
436  simdEnabled && MT::simdEnabled &&
440  };
442  //**********************************************************************************************
443 
444  //**********************************************************************************************
446  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
447  //**********************************************************************************************
448 
449  public:
450  //**Debugging functions*************************************************************************
453  inline bool isIntact() const noexcept;
455  //**********************************************************************************************
456 
457  //**Expression template evaluation functions****************************************************
460  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
461  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
462 
463  inline bool isAligned() const noexcept;
464 
465  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
466  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
467  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
468 
469  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
470  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
471  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
472  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
473 
474  template< typename MT, bool SO2 >
475  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
476 
477  template< typename MT, bool SO2 >
478  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
479 
480  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
481  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
482 
483  template< typename MT, bool SO2 >
484  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
485 
486  template< typename MT, bool SO2 >
487  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
488 
489  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
490  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
491 
492  template< typename MT, bool SO2 >
493  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
494 
495  template< typename MT, bool SO2 >
496  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
497 
498  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
499  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
500 
501  template< typename MT, bool SO2 >
502  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO2>& rhs );
503 
504  template< typename MT, bool SO2 >
505  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO2>& rhs );
506 
507  template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
508  template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
510  //**********************************************************************************************
511 
512  private:
513  //**********************************************************************************************
515  enum : size_t { NN = ( usePadding )?( nextMultiple( N, SIMDSIZE ) ):( N ) };
516  //**********************************************************************************************
517 
518  //**Member variables****************************************************************************
522 
531  size_t m_;
532  size_t n_;
533 
534  //**********************************************************************************************
535 
536  //**Compile time checks*************************************************************************
542  BLAZE_STATIC_ASSERT( !usePadding || NN % SIMDSIZE == 0UL );
543  BLAZE_STATIC_ASSERT( NN >= N );
545  //**********************************************************************************************
546 };
547 //*************************************************************************************************
548 
549 
550 
551 
552 //=================================================================================================
553 //
554 // CONSTRUCTORS
555 //
556 //=================================================================================================
557 
558 //*************************************************************************************************
563 template< typename Type // Data type of the matrix
564  , size_t M // Number of rows
565  , size_t N // Number of columns
566  , bool SO > // Storage order
568  : v_() // The statically allocated matrix elements
569  , m_( 0UL ) // The current number of rows of the matrix
570  , n_( 0UL ) // The current number of columns of the matrix
571 {
573 
574  if( IsNumeric<Type>::value ) {
575  for( size_t i=0UL; i<M*NN; ++i )
576  v_[i] = Type();
577  }
578 
579  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
580 }
581 //*************************************************************************************************
582 
583 
584 //*************************************************************************************************
597 template< typename Type // Data type of the matrix
598  , size_t M // Number of rows
599  , size_t N // Number of columns
600  , bool SO > // Storage order
601 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n )
602  : v_() // The statically allocated matrix elements
603  , m_( m ) // The current number of rows of the matrix
604  , n_( n ) // The current number of columns of the matrix
605 {
607 
608  if( m > M ) {
609  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
610  }
611 
612  if( n > N ) {
613  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
614  }
615 
616  if( IsNumeric<Type>::value ) {
617  for( size_t i=0UL; i<M*NN; ++i )
618  v_[i] = Type();
619  }
620 
621  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
622 }
623 //*************************************************************************************************
624 
625 
626 //*************************************************************************************************
640 template< typename Type // Data type of the matrix
641  , size_t M // Number of rows
642  , size_t N // Number of columns
643  , bool SO > // Storage order
644 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Type& init )
645  : v_() // The statically allocated matrix elements
646  , m_( m ) // The current number of rows of the matrix
647  , n_( n ) // The current number of columns of the matrix
648 {
650 
651  if( m > M ) {
652  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
653  }
654 
655  if( n > N ) {
656  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
657  }
658 
659  for( size_t i=0UL; i<m; ++i ) {
660  for( size_t j=0UL; j<n; ++j )
661  v_[i*NN+j] = init;
662 
663  if( IsNumeric<Type>::value ) {
664  for( size_t j=n; j<NN; ++j )
665  v_[i*NN+j] = Type();
666  }
667  }
668 
669  if( IsNumeric<Type>::value ) {
670  for( size_t i=m; i<M; ++i )
671  for( size_t j=0UL; j<NN; ++j )
672  v_[i*NN+j] = Type();
673  }
674 
675  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
676 }
677 //*************************************************************************************************
678 
679 
680 //*************************************************************************************************
704 template< typename Type // Data type of the matrix
705  , size_t M // Number of rows
706  , size_t N // Number of columns
707  , bool SO > // Storage order
709  : v_() // The statically allocated matrix elements
710  , m_( list.size() ) // The current number of rows of the matrix
711  , n_( determineColumns( list ) ) // The current number of columns of the matrix
712 {
714 
715  if( m_ > M ) {
716  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
717  }
718 
719  if( n_ > N ) {
720  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
721  }
722 
723  size_t i( 0UL );
724 
725  for( const auto& rowList : list ) {
726  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
727  ++i;
728  }
729 
730  if( IsNumeric<Type>::value ) {
731  for( ; i<M; ++i )
732  for( size_t j=0UL; j<NN; ++j )
733  v_[i*NN+j] = Type();
734  }
735 
736  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
737 }
738 //*************************************************************************************************
739 
740 
741 //*************************************************************************************************
768 template< typename Type // Data type of the matrix
769  , size_t M // Number of rows
770  , size_t N // Number of columns
771  , bool SO > // Storage order
772 template< typename Other > // Data type of the initialization array
773 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Other* array )
774  : v_() // The statically allocated matrix elements
775  , m_( m ) // The current number of rows of the matrix
776  , n_( n ) // The current number of columns of the matrix
777 {
779 
780  if( m > M ) {
781  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
782  }
783 
784  if( n > N ) {
785  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
786  }
787 
788  for( size_t i=0UL; i<m; ++i ) {
789  for( size_t j=0UL; j<n; ++j )
790  v_[i*NN+j] = array[i*n+j];
791 
792  if( IsNumeric<Type>::value ) {
793  for( size_t j=n; j<NN; ++j )
794  v_[i*NN+j] = Type();
795  }
796  }
797 
798  if( IsNumeric<Type>::value ) {
799  for( size_t i=m; i<M; ++i )
800  for( size_t j=0UL; j<NN; ++j )
801  v_[i*NN+j] = Type();
802  }
803 
804  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
805 }
806 //*************************************************************************************************
807 
808 
809 //*************************************************************************************************
830 template< typename Type // Data type of the matrix
831  , size_t M // Number of rows
832  , size_t N // Number of columns
833  , bool SO > // Storage order
834 template< typename Other // Data type of the initialization array
835  , size_t Rows // Number of rows of the initialization array
836  , size_t Cols > // Number of columns of the initialization array
837 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( const Other (&array)[Rows][Cols] )
838  : v_() // The statically allocated matrix elements
839  , m_( Rows ) // The current number of rows of the matrix
840  , n_( Cols ) // The current number of columns of the matrix
841 {
842  BLAZE_STATIC_ASSERT( Rows <= M );
843  BLAZE_STATIC_ASSERT( Cols <= N );
845 
846  for( size_t i=0UL; i<Rows; ++i ) {
847  for( size_t j=0UL; j<Cols; ++j )
848  v_[i*NN+j] = array[i][j];
849 
850  if( IsNumeric<Type>::value ) {
851  for( size_t j=Cols; j<NN; ++j )
852  v_[i*NN+j] = Type();
853  }
854  }
855 
856  if( IsNumeric<Type>::value ) {
857  for( size_t i=Rows; i<M; ++i )
858  for( size_t j=0UL; j<NN; ++j )
859  v_[i*NN+j] = Type();
860  }
861 
862  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
863 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
875 template< typename Type // Data type of the matrix
876  , size_t M // Number of rows
877  , size_t N // Number of columns
878  , bool SO > // Storage order
880  : v_() // The statically allocated matrix elements
881  , m_( m.m_ ) // The current number of rows of the matrix
882  , n_( m.n_ ) // The current number of columns of the matrix
883 {
885 
886  for( size_t i=0UL; i<m_; ++i ) {
887  for( size_t j=0UL; j<n_; ++j )
888  v_[i*NN+j] = m.v_[i*NN+j];
889 
890  if( IsNumeric<Type>::value ) {
891  for( size_t j=n_; j<NN; ++j )
892  v_[i*NN+j] = Type();
893  }
894  }
895 
896  if( IsNumeric<Type>::value ) {
897  for( size_t i=m_; i<M; ++i )
898  for( size_t j=0UL; j<NN; ++j )
899  v_[i*NN+j] = Type();
900  }
901 
902  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
903 }
904 //*************************************************************************************************
905 
906 
907 //*************************************************************************************************
913 template< typename Type // Data type of the matrix
914  , size_t M // Number of rows
915  , size_t N // Number of columns
916  , bool SO > // Storage order
917 template< typename MT // Type of the foreign matrix
918  , bool SO2 > // Storage order of the foreign matrix
920  : v_() // The statically allocated matrix elements
921  , m_( (~m).rows() ) // The current number of rows of the matrix
922  , n_( (~m).columns() ) // The current number of columns of the matrix
923 {
924  using blaze::assign;
925 
927 
928  if( (~m).rows() > M || (~m).columns() > N ) {
929  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
930  }
931 
932  for( size_t i=0UL; i<m_; ++i ) {
933  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : n_ );
934  j<( IsNumeric<Type>::value ? NN : n_ );
935  ++j ) {
936  v_[i*NN+j] = Type();
937  }
938  }
939 
940  if( IsNumeric<Type>::value ) {
941  for( size_t i=m_; i<M; ++i )
942  for( size_t j=0UL; j<NN; ++j )
943  v_[i*NN+j] = Type();
944  }
945 
946  assign( *this, ~m );
947 
948  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
949 }
950 //*************************************************************************************************
951 
952 
953 
954 
955 //=================================================================================================
956 //
957 // DATA ACCESS FUNCTIONS
958 //
959 //=================================================================================================
960 
961 //*************************************************************************************************
971 template< typename Type // Data type of the matrix
972  , size_t M // Number of rows
973  , size_t N // Number of columns
974  , bool SO > // Storage order
976  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) noexcept
977 {
978  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
979  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
980  return v_[i*NN+j];
981 }
982 //*************************************************************************************************
983 
984 
985 //*************************************************************************************************
995 template< typename Type // Data type of the matrix
996  , size_t M // Number of rows
997  , size_t N // Number of columns
998  , bool SO > // Storage order
1000  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const noexcept
1001 {
1002  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
1003  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
1004  return v_[i*NN+j];
1005 }
1006 //*************************************************************************************************
1007 
1008 
1009 //*************************************************************************************************
1020 template< typename Type // Data type of the matrix
1021  , size_t M // Number of rows
1022  , size_t N // Number of columns
1023  , bool SO > // Storage order
1025  HybridMatrix<Type,M,N,SO>::at( size_t i, size_t j )
1026 {
1027  if( i >= m_ ) {
1028  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1029  }
1030  if( j >= n_ ) {
1031  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1032  }
1033  return (*this)(i,j);
1034 }
1035 //*************************************************************************************************
1036 
1037 
1038 //*************************************************************************************************
1049 template< typename Type // Data type of the matrix
1050  , size_t M // Number of rows
1051  , size_t N // Number of columns
1052  , bool SO > // Storage order
1054  HybridMatrix<Type,M,N,SO>::at( size_t i, size_t j ) const
1055 {
1056  if( i >= m_ ) {
1057  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1058  }
1059  if( j >= n_ ) {
1060  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1061  }
1062  return (*this)(i,j);
1063 }
1064 //*************************************************************************************************
1065 
1066 
1067 //*************************************************************************************************
1079 template< typename Type // Data type of the matrix
1080  , size_t M // Number of rows
1081  , size_t N // Number of columns
1082  , bool SO > // Storage order
1083 inline typename HybridMatrix<Type,M,N,SO>::Pointer
1085 {
1086  return v_;
1087 }
1088 //*************************************************************************************************
1089 
1090 
1091 //*************************************************************************************************
1103 template< typename Type // Data type of the matrix
1104  , size_t M // Number of rows
1105  , size_t N // Number of columns
1106  , bool SO > // Storage order
1109 {
1110  return v_;
1111 }
1112 //*************************************************************************************************
1113 
1114 
1115 //*************************************************************************************************
1123 template< typename Type // Data type of the matrix
1124  , size_t M // Number of rows
1125  , size_t N // Number of columns
1126  , bool SO > // Storage order
1127 inline typename HybridMatrix<Type,M,N,SO>::Pointer
1128  HybridMatrix<Type,M,N,SO>::data( size_t i ) noexcept
1129 {
1130  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1131  return v_ + i*NN;
1132 }
1133 //*************************************************************************************************
1134 
1135 
1136 //*************************************************************************************************
1144 template< typename Type // Data type of the matrix
1145  , size_t M // Number of rows
1146  , size_t N // Number of columns
1147  , bool SO > // Storage order
1149  HybridMatrix<Type,M,N,SO>::data( size_t i ) const noexcept
1150 {
1151  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1152  return v_ + i*NN;
1153 }
1154 //*************************************************************************************************
1155 
1156 
1157 //*************************************************************************************************
1168 template< typename Type // Data type of the matrix
1169  , size_t M // Number of rows
1170  , size_t N // Number of columns
1171  , bool SO > // Storage order
1174 {
1175  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1176  return Iterator( v_ + i*NN );
1177 }
1178 //*************************************************************************************************
1179 
1180 
1181 //*************************************************************************************************
1192 template< typename Type // Data type of the matrix
1193  , size_t M // Number of rows
1194  , size_t N // Number of columns
1195  , bool SO > // Storage order
1197  HybridMatrix<Type,M,N,SO>::begin( size_t i ) const noexcept
1198 {
1199  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1200  return ConstIterator( v_ + i*NN );
1201 }
1202 //*************************************************************************************************
1203 
1204 
1205 //*************************************************************************************************
1216 template< typename Type // Data type of the matrix
1217  , size_t M // Number of rows
1218  , size_t N // Number of columns
1219  , bool SO > // Storage order
1221  HybridMatrix<Type,M,N,SO>::cbegin( size_t i ) const noexcept
1222 {
1223  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1224  return ConstIterator( v_ + i*NN );
1225 }
1226 //*************************************************************************************************
1227 
1228 
1229 //*************************************************************************************************
1240 template< typename Type // Data type of the matrix
1241  , size_t M // Number of rows
1242  , size_t N // Number of columns
1243  , bool SO > // Storage order
1245  HybridMatrix<Type,M,N,SO>::end( size_t i ) noexcept
1246 {
1247  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1248  return Iterator( v_ + i*NN + N );
1249 }
1250 //*************************************************************************************************
1251 
1252 
1253 //*************************************************************************************************
1264 template< typename Type // Data type of the matrix
1265  , size_t M // Number of rows
1266  , size_t N // Number of columns
1267  , bool SO > // Storage order
1269  HybridMatrix<Type,M,N,SO>::end( size_t i ) const noexcept
1270 {
1271  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1272  return ConstIterator( v_ + i*NN + N );
1273 }
1274 //*************************************************************************************************
1275 
1276 
1277 //*************************************************************************************************
1288 template< typename Type // Data type of the matrix
1289  , size_t M // Number of rows
1290  , size_t N // Number of columns
1291  , bool SO > // Storage order
1293  HybridMatrix<Type,M,N,SO>::cend( size_t i ) const noexcept
1294 {
1295  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1296  return ConstIterator( v_ + i*NN + N );
1297 }
1298 //*************************************************************************************************
1299 
1300 
1301 
1302 
1303 //=================================================================================================
1304 //
1305 // ASSIGNMENT OPERATORS
1306 //
1307 //=================================================================================================
1308 
1309 //*************************************************************************************************
1315 template< typename Type // Data type of the matrix
1316  , size_t M // Number of rows
1317  , size_t N // Number of columns
1318  , bool SO > // Storage order
1320 {
1321  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1322  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1323 
1324  for( size_t i=0UL; i<m_; ++i )
1325  for( size_t j=0UL; j<n_; ++j )
1326  v_[i*NN+j] = set;
1327 
1328  return *this;
1329 }
1330 //*************************************************************************************************
1331 
1332 
1333 //*************************************************************************************************
1358 template< typename Type // Data type of the matrix
1359  , size_t M // Number of rows
1360  , size_t N // Number of columns
1361  , bool SO > // Storage order
1364 {
1365  const size_t m( list.size() );
1366  const size_t n( determineColumns( list ) );
1367 
1368  if( m > M ) {
1369  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1370  }
1371 
1372  if( n > N ) {
1373  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1374  }
1375 
1376  resize( m, n, false );
1377 
1378  size_t i( 0UL );
1379 
1380  for( const auto& rowList : list ) {
1381  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
1382  ++i;
1383  }
1384 
1385  return *this;
1386 }
1387 //*************************************************************************************************
1388 
1389 
1390 //*************************************************************************************************
1411 template< typename Type // Data type of the matrix
1412  , size_t M // Number of rows
1413  , size_t N // Number of columns
1414  , bool SO > // Storage order
1415 template< typename Other // Data type of the initialization array
1416  , size_t Rows // Number of rows of the initialization array
1417  , size_t Cols > // Number of columns of the initialization array
1418 inline HybridMatrix<Type,M,N,SO>& HybridMatrix<Type,M,N,SO>::operator=( const Other (&array)[Rows][Cols] )
1419 {
1420  BLAZE_STATIC_ASSERT( Rows <= M );
1421  BLAZE_STATIC_ASSERT( Cols <= N );
1422 
1423  resize( Rows, Cols );
1424 
1425  for( size_t i=0UL; i<Rows; ++i )
1426  for( size_t j=0UL; j<Cols; ++j )
1427  v_[i*NN+j] = array[i][j];
1428 
1429  return *this;
1430 }
1431 //*************************************************************************************************
1432 
1433 
1434 //*************************************************************************************************
1442 template< typename Type // Data type of the matrix
1443  , size_t M // Number of rows
1444  , size_t N // Number of columns
1445  , bool SO > // Storage order
1447 {
1448  using blaze::assign;
1449 
1450  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1451  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1452 
1453  resize( rhs.rows(), rhs.columns() );
1454  assign( *this, ~rhs );
1455 
1456  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1457 
1458  return *this;
1459 }
1460 //*************************************************************************************************
1461 
1462 
1463 //*************************************************************************************************
1474 template< typename Type // Data type of the matrix
1475  , size_t M // Number of rows
1476  , size_t N // Number of columns
1477  , bool SO > // Storage order
1478 template< typename MT // Type of the right-hand side matrix
1479  , bool SO2 > // Storage order of the right-hand side matrix
1481 {
1482  using blaze::assign;
1483 
1484  using TT = TransExprTrait_<This>;
1485  using CT = CTransExprTrait_<This>;
1486  using IT = InvExprTrait_<This>;
1487 
1488  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
1489  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
1490  }
1491 
1492  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1493  transpose();
1494  }
1495  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1496  ctranspose();
1497  }
1498  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1499  HybridMatrix tmp( ~rhs );
1500  resize( tmp.rows(), tmp.columns() );
1501  assign( *this, tmp );
1502  }
1503  else {
1504  resize( (~rhs).rows(), (~rhs).columns() );
1506  reset();
1507  assign( *this, ~rhs );
1508  }
1509 
1510  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1511 
1512  return *this;
1513 }
1514 //*************************************************************************************************
1515 
1516 
1517 //*************************************************************************************************
1527 template< typename Type // Data type of the matrix
1528  , size_t M // Number of rows
1529  , size_t N // Number of columns
1530  , bool SO > // Storage order
1531 template< typename MT // Type of the right-hand side matrix
1532  , bool SO2 > // Storage order of the right-hand side matrix
1534 {
1535  using blaze::addAssign;
1536 
1537  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1538  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1539  }
1540 
1541  if( (~rhs).canAlias( this ) ) {
1542  const ResultType_<MT> tmp( ~rhs );
1543  addAssign( *this, tmp );
1544  }
1545  else {
1546  addAssign( *this, ~rhs );
1547  }
1548 
1549  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1550 
1551  return *this;
1552 }
1553 //*************************************************************************************************
1554 
1555 
1556 //*************************************************************************************************
1566 template< typename Type // Data type of the matrix
1567  , size_t M // Number of rows
1568  , size_t N // Number of columns
1569  , bool SO > // Storage order
1570 template< typename MT // Type of the right-hand side matrix
1571  , bool SO2 > // Storage order of the right-hand side matrix
1573 {
1574  using blaze::subAssign;
1575 
1576  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1577  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1578  }
1579 
1580  if( (~rhs).canAlias( this ) ) {
1581  const ResultType_<MT> tmp( ~rhs );
1582  subAssign( *this, tmp );
1583  }
1584  else {
1585  subAssign( *this, ~rhs );
1586  }
1587 
1588  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1589 
1590  return *this;
1591 }
1592 //*************************************************************************************************
1593 
1594 
1595 //*************************************************************************************************
1605 template< typename Type // Data type of the matrix
1606  , size_t M // Number of rows
1607  , size_t N // Number of columns
1608  , bool SO > // Storage order
1609 template< typename MT // Type of the right-hand side matrix
1610  , bool SO2 > // Storage order of the right-hand side matrix
1612 {
1613  using blaze::schurAssign;
1614 
1615  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1616  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1617  }
1618 
1619  if( (~rhs).canAlias( this ) ) {
1620  const ResultType_<MT> tmp( ~rhs );
1621  schurAssign( *this, tmp );
1622  }
1623  else {
1624  schurAssign( *this, ~rhs );
1625  }
1626 
1627  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1628 
1629  return *this;
1630 }
1631 //*************************************************************************************************
1632 
1633 
1634 //*************************************************************************************************
1644 template< typename Type // Data type of the matrix
1645  , size_t M // Number of rows
1646  , size_t N // Number of columns
1647  , bool SO > // Storage order
1648 template< typename MT // Type of the right-hand side matrix
1649  , bool SO2 > // Storage order of the right-hand side matrix
1651 {
1652  using blaze::assign;
1653 
1654  if( n_ != (~rhs).rows() || (~rhs).columns() > N ) {
1655  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1656  }
1657 
1658  const HybridMatrix tmp( *this * (~rhs) );
1659  resize( tmp.rows(), tmp.columns() );
1660  assign( *this, tmp );
1661 
1662  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1663 
1664  return *this;
1665 }
1666 //*************************************************************************************************
1667 
1668 
1669 //*************************************************************************************************
1676 template< typename Type // Data type of the matrix
1677  , size_t M // Number of rows
1678  , size_t N // Number of columns
1679  , bool SO > // Storage order
1680 template< typename Other > // Data type of the right-hand side scalar
1683 {
1684  using blaze::assign;
1685 
1686  assign( *this, (*this) * rhs );
1687 
1688  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1689 
1690  return *this;
1691 }
1692 //*************************************************************************************************
1693 
1694 
1695 //*************************************************************************************************
1704 template< typename Type // Data type of the matrix
1705  , size_t M // Number of rows
1706  , size_t N // Number of columns
1707  , bool SO > // Storage order
1708 template< typename Other > // Data type of the right-hand side scalar
1709 inline EnableIf_<IsNumeric<Other>, HybridMatrix<Type,M,N,SO> >&
1711 {
1712  using blaze::assign;
1713 
1714  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1715 
1716  assign( *this, (*this) / rhs );
1717 
1718  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1719 
1720  return *this;
1721 }
1722 //*************************************************************************************************
1723 
1724 
1725 
1726 
1727 //=================================================================================================
1728 //
1729 // UTILITY FUNCTIONS
1730 //
1731 //=================================================================================================
1732 
1733 //*************************************************************************************************
1738 template< typename Type // Data type of the matrix
1739  , size_t M // Number of rows
1740  , size_t N // Number of columns
1741  , bool SO > // Storage order
1742 inline size_t HybridMatrix<Type,M,N,SO>::rows() const noexcept
1743 {
1744  return m_;
1745 }
1746 //*************************************************************************************************
1747 
1748 
1749 //*************************************************************************************************
1754 template< typename Type // Data type of the matrix
1755  , size_t M // Number of rows
1756  , size_t N // Number of columns
1757  , bool SO > // Storage order
1758 inline size_t HybridMatrix<Type,M,N,SO>::columns() const noexcept
1759 {
1760  return n_;
1761 }
1762 //*************************************************************************************************
1763 
1764 
1765 //*************************************************************************************************
1773 template< typename Type // Data type of the matrix
1774  , size_t M // Number of rows
1775  , size_t N // Number of columns
1776  , bool SO > // Storage order
1777 inline constexpr size_t HybridMatrix<Type,M,N,SO>::spacing() const noexcept
1778 {
1779  return NN;
1780 }
1781 //*************************************************************************************************
1782 
1783 
1784 //*************************************************************************************************
1789 template< typename Type // Data type of the matrix
1790  , size_t M // Number of rows
1791  , size_t N // Number of columns
1792  , bool SO > // Storage order
1793 inline constexpr size_t HybridMatrix<Type,M,N,SO>::capacity() const noexcept
1794 {
1795  return M*NN;
1796 }
1797 //*************************************************************************************************
1798 
1799 
1800 //*************************************************************************************************
1811 template< typename Type // Data type of the matrix
1812  , size_t M // Number of rows
1813  , size_t N // Number of columns
1814  , bool SO > // Storage order
1815 inline size_t HybridMatrix<Type,M,N,SO>::capacity( size_t i ) const noexcept
1816 {
1817  UNUSED_PARAMETER( i );
1818 
1819  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1820 
1821  return NN;
1822 }
1823 //*************************************************************************************************
1824 
1825 
1826 //*************************************************************************************************
1831 template< typename Type // Data type of the matrix
1832  , size_t M // Number of rows
1833  , size_t N // Number of columns
1834  , bool SO > // Storage order
1836 {
1837  size_t nonzeros( 0UL );
1838 
1839  for( size_t i=0UL; i<m_; ++i )
1840  for( size_t j=0UL; j<n_; ++j )
1841  if( !isDefault( v_[i*NN+j] ) )
1842  ++nonzeros;
1843 
1844  return nonzeros;
1845 }
1846 //*************************************************************************************************
1847 
1848 
1849 //*************************************************************************************************
1860 template< typename Type // Data type of the matrix
1861  , size_t M // Number of rows
1862  , size_t N // Number of columns
1863  , bool SO > // Storage order
1864 inline size_t HybridMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1865 {
1866  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1867 
1868  const size_t jend( i*NN + n_ );
1869  size_t nonzeros( 0UL );
1870 
1871  for( size_t j=i*NN; j<jend; ++j )
1872  if( !isDefault( v_[j] ) )
1873  ++nonzeros;
1874 
1875  return nonzeros;
1876 }
1877 //*************************************************************************************************
1878 
1879 
1880 //*************************************************************************************************
1885 template< typename Type // Data type of the matrix
1886  , size_t M // Number of rows
1887  , size_t N // Number of columns
1888  , bool SO > // Storage order
1890 {
1891  using blaze::clear;
1892 
1893  for( size_t i=0UL; i<m_; ++i )
1894  for( size_t j=0UL; j<n_; ++j )
1895  clear( v_[i*NN+j] );
1896 }
1897 //*************************************************************************************************
1898 
1899 
1900 //*************************************************************************************************
1911 template< typename Type // Data type of the matrix
1912  , size_t M // Number of rows
1913  , size_t N // Number of columns
1914  , bool SO > // Storage order
1915 inline void HybridMatrix<Type,M,N,SO>::reset( size_t i )
1916 {
1917  using blaze::clear;
1918 
1919  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1920  for( size_t j=0UL; j<n_; ++j )
1921  clear( v_[i*NN+j] );
1922 }
1923 //*************************************************************************************************
1924 
1925 
1926 //*************************************************************************************************
1933 template< typename Type // Data type of the matrix
1934  , size_t M // Number of rows
1935  , size_t N // Number of columns
1936  , bool SO > // Storage order
1938 {
1939  resize( 0UL, 0UL );
1940 }
1941 //*************************************************************************************************
1942 
1943 
1944 //*************************************************************************************************
1980 template< typename Type // Data type of the matrix
1981  , size_t M // Number of rows
1982  , size_t N // Number of columns
1983  , bool SO > // Storage order
1984 void HybridMatrix<Type,M,N,SO>::resize( size_t m, size_t n, bool preserve )
1985 {
1986  UNUSED_PARAMETER( preserve );
1987 
1988  if( m > M ) {
1989  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1990  }
1991 
1992  if( n > N ) {
1993  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1994  }
1995 
1996  if( IsVectorizable<Type>::value && n < n_ ) {
1997  for( size_t i=0UL; i<m; ++i )
1998  for( size_t j=n; j<n_; ++j )
1999  v_[i*NN+j] = Type();
2000  }
2001 
2002  if( IsVectorizable<Type>::value && m < m_ ) {
2003  for( size_t i=m; i<m_; ++i )
2004  for( size_t j=0UL; j<n_; ++j )
2005  v_[i*NN+j] = Type();
2006  }
2007 
2008  m_ = m;
2009  n_ = n;
2010 }
2011 //*************************************************************************************************
2012 
2013 
2014 //*************************************************************************************************
2029 template< typename Type // Data type of the matrix
2030  , size_t M // Number of rows
2031  , size_t N // Number of columns
2032  , bool SO > // Storage order
2033 inline void HybridMatrix<Type,M,N,SO>::extend( size_t m, size_t n, bool preserve )
2034 {
2035  UNUSED_PARAMETER( preserve );
2036  resize( m_+m, n_+n );
2037 }
2038 //*************************************************************************************************
2039 
2040 
2041 //*************************************************************************************************
2047 template< typename Type // Data type of the matrix
2048  , size_t M // Number of rows
2049  , size_t N // Number of columns
2050  , bool SO > // Storage order
2052 {
2053  using std::swap;
2054 
2055  const size_t maxrows( max( m_, m.m_ ) );
2056  const size_t maxcols( max( n_, m.n_ ) );
2057 
2058  for( size_t i=0UL; i<maxrows; ++i ) {
2059  for( size_t j=0UL; j<maxcols; ++j ) {
2060  swap( v_[i*NN+j], m(i,j) );
2061  }
2062  }
2063 
2064  swap( m_, m.m_ );
2065  swap( n_, m.n_ );
2066 }
2067 //*************************************************************************************************
2068 
2069 
2070 
2071 
2072 //=================================================================================================
2073 //
2074 // NUMERIC FUNCTIONS
2075 //
2076 //=================================================================================================
2077 
2078 //*************************************************************************************************
2089 template< typename Type // Data type of the matrix
2090  , size_t M // Number of rows
2091  , size_t N // Number of columns
2092  , bool SO > // Storage order
2094 {
2095  using std::swap;
2096 
2097  if( m_ > N || n_ > M ) {
2098  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2099  }
2100 
2101  const size_t maxsize( max( m_, n_ ) );
2102  for( size_t i=1UL; i<maxsize; ++i ) {
2103  for( size_t j=0UL; j<i; ++j ) {
2104  swap( v_[i*NN+j], v_[j*NN+i] );
2105  }
2106  }
2107 
2108  if( IsVectorizable<Type>::value && m_ < n_ ) {
2109  for( size_t i=0UL; i<m_; ++i ) {
2110  for( size_t j=m_; j<n_; ++j ) {
2111  v_[i*NN+j] = Type();
2112  }
2113  }
2114  }
2115 
2116  if( IsVectorizable<Type>::value && m_ > n_ ) {
2117  for( size_t i=n_; i<m_; ++i ) {
2118  for( size_t j=0UL; j<n_; ++j ) {
2119  v_[i*NN+j] = Type();
2120  }
2121  }
2122  }
2123 
2124  swap( m_, n_ );
2125 
2126  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2127 
2128  return *this;
2129 }
2130 //*************************************************************************************************
2131 
2132 
2133 //*************************************************************************************************
2144 template< typename Type // Data type of the matrix
2145  , size_t M // Number of rows
2146  , size_t N // Number of columns
2147  , bool SO > // Storage order
2149 {
2150  using std::swap;
2151 
2152  if( m_ > N || n_ > M ) {
2153  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2154  }
2155 
2156  const size_t maxsize( max( m_, n_ ) );
2157  for( size_t i=0UL; i<maxsize; ++i ) {
2158  for( size_t j=0UL; j<i; ++j ) {
2159  cswap( v_[i*NN+j], v_[j*NN+i] );
2160  }
2161  conjugate( v_[i*NN+i] );
2162  }
2163 
2164  if( IsVectorizable<Type>::value && m_ < n_ ) {
2165  for( size_t i=0UL; i<m_; ++i ) {
2166  for( size_t j=m_; j<n_; ++j ) {
2167  v_[i*NN+j] = Type();
2168  }
2169  }
2170  }
2171 
2172  if( IsVectorizable<Type>::value && m_ > n_ ) {
2173  for( size_t i=n_; i<m_; ++i ) {
2174  for( size_t j=0UL; j<n_; ++j ) {
2175  v_[i*NN+j] = Type();
2176  }
2177  }
2178  }
2179 
2180  swap( m_, n_ );
2181 
2182  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2183 
2184  return *this;
2185 }
2186 //*************************************************************************************************
2187 
2188 
2189 //*************************************************************************************************
2206 template< typename Type // Data type of the matrix
2207  , size_t M // Number of rows
2208  , size_t N // Number of columns
2209  , bool SO > // Storage order
2210 template< typename Other > // Data type of the scalar value
2212 {
2213  for( size_t i=0UL; i<m_; ++i )
2214  for( size_t j=0UL; j<n_; ++j )
2215  v_[i*NN+j] *= scalar;
2216 
2217  return *this;
2218 }
2219 //*************************************************************************************************
2220 
2221 
2222 
2223 
2224 //=================================================================================================
2225 //
2226 // MEMORY FUNCTIONS
2227 //
2228 //=================================================================================================
2229 
2230 //*************************************************************************************************
2240 template< typename Type // Data type of the matrix
2241  , size_t M // Number of rows
2242  , size_t N // Number of columns
2243  , bool SO > // Storage order
2244 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size )
2245 {
2247 
2248  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2249 
2250  return allocate<HybridMatrix>( 1UL );
2251 }
2252 //*************************************************************************************************
2253 
2254 
2255 //*************************************************************************************************
2265 template< typename Type // Data type of the matrix
2266  , size_t M // Number of rows
2267  , size_t N // Number of columns
2268  , bool SO > // Storage order
2269 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
2270 {
2271  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2272  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2273 
2274  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2275 }
2276 //*************************************************************************************************
2277 
2278 
2279 //*************************************************************************************************
2289 template< typename Type // Data type of the matrix
2290  , size_t M // Number of rows
2291  , size_t N // Number of columns
2292  , bool SO > // Storage order
2293 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
2294 {
2295  UNUSED_PARAMETER( size );
2296 
2297  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2298 
2299  return allocate<HybridMatrix>( 1UL );
2300 }
2301 //*************************************************************************************************
2302 
2303 
2304 //*************************************************************************************************
2314 template< typename Type // Data type of the matrix
2315  , size_t M // Number of rows
2316  , size_t N // Number of columns
2317  , bool SO > // Storage order
2318 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2319 {
2320  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2321  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2322 
2323  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2324 }
2325 //*************************************************************************************************
2326 
2327 
2328 //*************************************************************************************************
2334 template< typename Type // Data type of the matrix
2335  , size_t M // Number of rows
2336  , size_t N // Number of columns
2337  , bool SO > // Storage order
2338 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr )
2339 {
2340  deallocate( static_cast<HybridMatrix*>( ptr ) );
2341 }
2342 //*************************************************************************************************
2343 
2344 
2345 //*************************************************************************************************
2351 template< typename Type // Data type of the matrix
2352  , size_t M // Number of rows
2353  , size_t N // Number of columns
2354  , bool SO > // Storage order
2355 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2356 {
2357  deallocate( static_cast<HybridMatrix*>( ptr ) );
2358 }
2359 //*************************************************************************************************
2360 
2361 
2362 //*************************************************************************************************
2368 template< typename Type // Data type of the matrix
2369  , size_t M // Number of rows
2370  , size_t N // Number of columns
2371  , bool SO > // Storage order
2372 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2373 {
2374  deallocate( static_cast<HybridMatrix*>( ptr ) );
2375 }
2376 //*************************************************************************************************
2377 
2378 
2379 //*************************************************************************************************
2385 template< typename Type // Data type of the matrix
2386  , size_t M // Number of rows
2387  , size_t N // Number of columns
2388  , bool SO > // Storage order
2389 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2390 {
2391  deallocate( static_cast<HybridMatrix*>( ptr ) );
2392 }
2393 //*************************************************************************************************
2394 
2395 
2396 
2397 
2398 //=================================================================================================
2399 //
2400 // DEBUGGING FUNCTIONS
2401 //
2402 //=================================================================================================
2403 
2404 //*************************************************************************************************
2413 template< typename Type // Data type of the matrix
2414  , size_t M // Number of rows
2415  , size_t N // Number of columns
2416  , bool SO > // Storage order
2417 inline bool HybridMatrix<Type,M,N,SO>::isIntact() const noexcept
2418 {
2419  if( m_ > M || n_ > N )
2420  return false;
2421 
2423  {
2424  for( size_t i=0UL; i<m_; ++i ) {
2425  for( size_t j=n_; j<NN; ++j ) {
2426  if( v_[i*NN+j] != Type() )
2427  return false;
2428  }
2429  }
2430 
2431  for( size_t i=m_; i<M; ++i ) {
2432  for( size_t j=0UL; j<NN; ++j ) {
2433  if( v_[i*NN+j] != Type() )
2434  return false;
2435  }
2436  }
2437  }
2438 
2439  return true;
2440 }
2441 //*************************************************************************************************
2442 
2443 
2444 
2445 
2446 //=================================================================================================
2447 //
2448 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2449 //
2450 //=================================================================================================
2451 
2452 //*************************************************************************************************
2462 template< typename Type // Data type of the matrix
2463  , size_t M // Number of rows
2464  , size_t N // Number of columns
2465  , bool SO > // Storage order
2466 template< typename Other > // Data type of the foreign expression
2467 inline bool HybridMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const noexcept
2468 {
2469  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2470 }
2471 //*************************************************************************************************
2472 
2473 
2474 //*************************************************************************************************
2484 template< typename Type // Data type of the matrix
2485  , size_t M // Number of rows
2486  , size_t N // Number of columns
2487  , bool SO > // Storage order
2488 template< typename Other > // Data type of the foreign expression
2489 inline bool HybridMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const noexcept
2490 {
2491  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2492 }
2493 //*************************************************************************************************
2494 
2495 
2496 //*************************************************************************************************
2505 template< typename Type // Data type of the matrix
2506  , size_t M // Number of rows
2507  , size_t N // Number of columns
2508  , bool SO > // Storage order
2509 inline bool HybridMatrix<Type,M,N,SO>::isAligned() const noexcept
2510 {
2511  return ( usePadding || columns() % SIMDSIZE == 0UL );
2512 }
2513 //*************************************************************************************************
2514 
2515 
2516 //*************************************************************************************************
2531 template< typename Type // Data type of the matrix
2532  , size_t M // Number of rows
2533  , size_t N // Number of columns
2534  , bool SO > // Storage order
2536  HybridMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const noexcept
2537 {
2538  if( usePadding )
2539  return loada( i, j );
2540  else
2541  return loadu( i, j );
2542 }
2543 //*************************************************************************************************
2544 
2545 
2546 //*************************************************************************************************
2561 template< typename Type // Data type of the matrix
2562  , size_t M // Number of rows
2563  , size_t N // Number of columns
2564  , bool SO > // Storage order
2566  HybridMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const noexcept
2567 {
2568  using blaze::loada;
2569 
2571 
2572  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2573  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2574  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2575  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2576  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2577 
2578  return loada( &v_[i*NN+j] );
2579 }
2580 //*************************************************************************************************
2581 
2582 
2583 //*************************************************************************************************
2598 template< typename Type // Data type of the matrix
2599  , size_t M // Number of rows
2600  , size_t N // Number of columns
2601  , bool SO > // Storage order
2603  HybridMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const noexcept
2604 {
2605  using blaze::loadu;
2606 
2608 
2609  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2610  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2611  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2612 
2613  return loadu( &v_[i*NN+j] );
2614 }
2615 //*************************************************************************************************
2616 
2617 
2618 //*************************************************************************************************
2634 template< typename Type // Data type of the matrix
2635  , size_t M // Number of rows
2636  , size_t N // Number of columns
2637  , bool SO > // Storage order
2639  HybridMatrix<Type,M,N,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2640 {
2641  if( usePadding )
2642  storea( i, j, value );
2643  else
2644  storeu( i, j, value );
2645 }
2646 //*************************************************************************************************
2647 
2648 
2649 //*************************************************************************************************
2665 template< typename Type // Data type of the matrix
2666  , size_t M // Number of rows
2667  , size_t N // Number of columns
2668  , bool SO > // Storage order
2670  HybridMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2671 {
2672  using blaze::storea;
2673 
2675 
2676  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2677  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2678  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2679  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2680  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2681 
2682  storea( &v_[i*NN+j], value );
2683 }
2684 //*************************************************************************************************
2685 
2686 
2687 //*************************************************************************************************
2703 template< typename Type // Data type of the matrix
2704  , size_t M // Number of rows
2705  , size_t N // Number of columns
2706  , bool SO > // Storage order
2708  HybridMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2709 {
2710  using blaze::storeu;
2711 
2713 
2714  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2715  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2716  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2717 
2718  storeu( &v_[i*NN+j], value );
2719 }
2720 //*************************************************************************************************
2721 
2722 
2723 //*************************************************************************************************
2740 template< typename Type // Data type of the matrix
2741  , size_t M // Number of rows
2742  , size_t N // Number of columns
2743  , bool SO > // Storage order
2745  HybridMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2746 {
2747  using blaze::stream;
2748 
2750 
2751  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2752  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2753  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2754  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2755  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2756 
2757  stream( &v_[i*NN+j], value );
2758 }
2759 //*************************************************************************************************
2760 
2761 
2762 //*************************************************************************************************
2773 template< typename Type // Data type of the matrix
2774  , size_t M // Number of rows
2775  , size_t N // Number of columns
2776  , bool SO > // Storage order
2777 template< typename MT // Type of the right-hand side dense matrix
2778  , bool SO2 > // Storage order of the right-hand side dense matrix
2781 {
2782  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2783 
2784  for( size_t i=0UL; i<m_; ++i ) {
2785  for( size_t j=0UL; j<n_; ++j ) {
2786  v_[i*NN+j] = (~rhs)(i,j);
2787  }
2788  }
2789 }
2790 //*************************************************************************************************
2791 
2792 
2793 //*************************************************************************************************
2804 template< typename Type // Data type of the matrix
2805  , size_t M // Number of rows
2806  , size_t N // Number of columns
2807  , bool SO > // Storage order
2808 template< typename MT // Type of the right-hand side dense matrix
2809  , bool SO2 > // Storage order of the right-hand side dense matrix
2812 {
2814 
2815  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2816 
2817  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2818 
2819  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2820  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2821 
2822  for( size_t i=0UL; i<m_; ++i )
2823  {
2824  size_t j( 0UL );
2825 
2826  for( ; j<jpos; j+=SIMDSIZE ) {
2827  store( i, j, (~rhs).load(i,j) );
2828  }
2829  for( ; remainder && j<n_; ++j ) {
2830  v_[i*NN+j] = (~rhs)(i,j);
2831  }
2832  }
2833 }
2834 //*************************************************************************************************
2835 
2836 
2837 //*************************************************************************************************
2848 template< typename Type // Data type of the matrix
2849  , size_t M // Number of rows
2850  , size_t N // Number of columns
2851  , bool SO > // Storage order
2852 template< typename MT > // Type of the right-hand side sparse matrix
2854 {
2855  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2856 
2857  for( size_t i=0UL; i<m_; ++i )
2858  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2859  v_[i*NN+element->index()] = element->value();
2860 }
2861 //*************************************************************************************************
2862 
2863 
2864 //*************************************************************************************************
2875 template< typename Type // Data type of the matrix
2876  , size_t M // Number of rows
2877  , size_t N // Number of columns
2878  , bool SO > // Storage order
2879 template< typename MT > // Type of the right-hand side sparse matrix
2881 {
2883 
2884  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2885 
2886  for( size_t j=0UL; j<n_; ++j )
2887  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2888  v_[element->index()*NN+j] = element->value();
2889 }
2890 //*************************************************************************************************
2891 
2892 
2893 //*************************************************************************************************
2904 template< typename Type // Data type of the matrix
2905  , size_t M // Number of rows
2906  , size_t N // Number of columns
2907  , bool SO > // Storage order
2908 template< typename MT // Type of the right-hand side dense matrix
2909  , bool SO2 > // Storage order of the right-hand side dense matrix
2912 {
2913  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2914 
2915  for( size_t i=0UL; i<m_; ++i )
2916  {
2917  if( IsDiagonal<MT>::value )
2918  {
2919  v_[i*NN+i] += (~rhs)(i,i);
2920  }
2921  else
2922  {
2923  const size_t jbegin( ( IsUpper<MT>::value )
2924  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2925  :( 0UL ) );
2926  const size_t jend ( ( IsLower<MT>::value )
2927  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2928  :( n_ ) );
2929  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2930 
2931  for( size_t j=jbegin; j<jend; ++j ) {
2932  v_[i*NN+j] += (~rhs)(i,j);
2933  }
2934  }
2935  }
2936 }
2937 //*************************************************************************************************
2938 
2939 
2940 //*************************************************************************************************
2951 template< typename Type // Data type of the matrix
2952  , size_t M // Number of rows
2953  , size_t N // Number of columns
2954  , bool SO > // Storage order
2955 template< typename MT // Type of the right-hand side dense matrix
2956  , bool SO2 > // Storage order of the right-hand side dense matrix
2957 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2959 {
2962 
2963  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2964 
2965  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2966 
2967  for( size_t i=0UL; i<m_; ++i )
2968  {
2969  const size_t jbegin( ( IsUpper<MT>::value )
2970  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2971  :( 0UL ) );
2972  const size_t jend ( ( IsLower<MT>::value )
2973  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2974  :( n_ ) );
2975  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2976 
2977  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2978  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2979 
2980  size_t j( jbegin );
2981 
2982  for( ; j<jpos; j+=SIMDSIZE ) {
2983  store( i, j, load(i,j) + (~rhs).load(i,j) );
2984  }
2985  for( ; remainder && j<jend; ++j ) {
2986  v_[i*NN+j] += (~rhs)(i,j);
2987  }
2988  }
2989 }
2990 //*************************************************************************************************
2991 
2992 
2993 //*************************************************************************************************
3004 template< typename Type // Data type of the matrix
3005  , size_t M // Number of rows
3006  , size_t N // Number of columns
3007  , bool SO > // Storage order
3008 template< typename MT > // Type of the right-hand side sparse matrix
3010 {
3011  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3012 
3013  for( size_t i=0UL; i<m_; ++i )
3014  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3015  v_[i*NN+element->index()] += element->value();
3016 }
3017 //*************************************************************************************************
3018 
3019 
3020 //*************************************************************************************************
3031 template< typename Type // Data type of the matrix
3032  , size_t M // Number of rows
3033  , size_t N // Number of columns
3034  , bool SO > // Storage order
3035 template< typename MT > // Type of the right-hand side sparse matrix
3037 {
3039 
3040  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3041 
3042  for( size_t j=0UL; j<n_; ++j )
3043  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3044  v_[element->index()*NN+j] += element->value();
3045 }
3046 //*************************************************************************************************
3047 
3048 
3049 //*************************************************************************************************
3060 template< typename Type // Data type of the matrix
3061  , size_t M // Number of rows
3062  , size_t N // Number of columns
3063  , bool SO > // Storage order
3064 template< typename MT // Type of the right-hand side dense matrix
3065  , bool SO2 > // Storage order of the right-hand side dense matrix
3068 {
3069  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3070 
3071  for( size_t i=0UL; i<m_; ++i )
3072  {
3073  if( IsDiagonal<MT>::value )
3074  {
3075  v_[i*NN+i] -= (~rhs)(i,i);
3076  }
3077  else
3078  {
3079  const size_t jbegin( ( IsUpper<MT>::value )
3080  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
3081  :( 0UL ) );
3082  const size_t jend ( ( IsLower<MT>::value )
3083  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
3084  :( n_ ) );
3085  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3086 
3087  for( size_t j=jbegin; j<jend; ++j ) {
3088  v_[i*NN+j] -= (~rhs)(i,j);
3089  }
3090  }
3091  }
3092 }
3093 //*************************************************************************************************
3094 
3095 
3096 //*************************************************************************************************
3107 template< typename Type // Data type of the matrix
3108  , size_t M // Number of rows
3109  , size_t N // Number of columns
3110  , bool SO > // Storage order
3111 template< typename MT // Type of the right-hand side dense matrix
3112  , bool SO2 > // Storage order of the right-hand side dense matrix
3113 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
3115 {
3118 
3119  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3120 
3121  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
3122 
3123  for( size_t i=0UL; i<m_; ++i )
3124  {
3125  const size_t jbegin( ( IsUpper<MT>::value )
3126  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
3127  :( 0UL ) );
3128  const size_t jend ( ( IsLower<MT>::value )
3129  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
3130  :( n_ ) );
3131  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3132 
3133  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
3134  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3135 
3136  size_t j( jbegin );
3137 
3138  for( ; j<jpos; j+=SIMDSIZE ) {
3139  store( i, j, load(i,j) - (~rhs).load(i,j) );
3140  }
3141  for( ; remainder && j<jend; ++j ) {
3142  v_[i*NN+j] -= (~rhs)(i,j);
3143  }
3144  }
3145 }
3146 //*************************************************************************************************
3147 
3148 
3149 //*************************************************************************************************
3160 template< typename Type // Data type of the matrix
3161  , size_t M // Number of rows
3162  , size_t N // Number of columns
3163  , bool SO > // Storage order
3164 template< typename MT > // Type of the right-hand side sparse matrix
3166 {
3167  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3168 
3169  for( size_t i=0UL; i<m_; ++i )
3170  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3171  v_[i*NN+element->index()] -= element->value();
3172 }
3173 //*************************************************************************************************
3174 
3175 
3176 //*************************************************************************************************
3187 template< typename Type // Data type of the matrix
3188  , size_t M // Number of rows
3189  , size_t N // Number of columns
3190  , bool SO > // Storage order
3191 template< typename MT > // Type of the right-hand side sparse matrix
3193 {
3195 
3196  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3197 
3198  for( size_t j=0UL; j<n_; ++j )
3199  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3200  v_[element->index()*NN+j] -= element->value();
3201 }
3202 //*************************************************************************************************
3203 
3204 
3205 //*************************************************************************************************
3216 template< typename Type // Data type of the matrix
3217  , size_t M // Number of rows
3218  , size_t N // Number of columns
3219  , bool SO > // Storage order
3220 template< typename MT // Type of the right-hand side dense matrix
3221  , bool SO2 > // Storage order of the right-hand side dense matrix
3222 inline DisableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3224 {
3225  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3226 
3227  for( size_t i=0UL; i<m_; ++i ) {
3228  for( size_t j=0UL; j<n_; ++j ) {
3229  v_[i*NN+j] *= (~rhs)(i,j);
3230  }
3231  }
3232 }
3233 //*************************************************************************************************
3234 
3235 
3236 //*************************************************************************************************
3247 template< typename Type // Data type of the matrix
3248  , size_t M // Number of rows
3249  , size_t N // Number of columns
3250  , bool SO > // Storage order
3251 template< typename MT // Type of the right-hand side dense matrix
3252  , bool SO2 > // Storage order of the right-hand side dense matrix
3253 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3255 {
3257 
3258  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3259 
3260  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
3261 
3262  for( size_t i=0UL; i<m_; ++i )
3263  {
3264  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
3265  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3266 
3267  size_t j( 0UL );
3268 
3269  for( ; j<jpos; j+=SIMDSIZE ) {
3270  store( i, j, load(i,j) * (~rhs).load(i,j) );
3271  }
3272  for( ; remainder && j<n_; ++j ) {
3273  v_[i*NN+j] *= (~rhs)(i,j);
3274  }
3275  }
3276 }
3277 //*************************************************************************************************
3278 
3279 
3280 //*************************************************************************************************
3291 template< typename Type // Data type of the matrix
3292  , size_t M // Number of rows
3293  , size_t N // Number of columns
3294  , bool SO > // Storage order
3295 template< typename MT > // Type of the right-hand side sparse matrix
3297 {
3298  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3299 
3300  const HybridMatrix tmp( serial( *this ) );
3301 
3302  reset();
3303 
3304  for( size_t i=0UL; i<m_; ++i )
3305  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3306  v_[i*NN+element->index()] = tmp.v_[i*NN+element->index()] * element->value();
3307 }
3308 //*************************************************************************************************
3309 
3310 
3311 //*************************************************************************************************
3322 template< typename Type // Data type of the matrix
3323  , size_t M // Number of rows
3324  , size_t N // Number of columns
3325  , bool SO > // Storage order
3326 template< typename MT > // Type of the right-hand side sparse matrix
3328 {
3330 
3331  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3332 
3333  const HybridMatrix tmp( serial( *this ) );
3334 
3335  reset();
3336 
3337  for( size_t j=0UL; j<n_; ++j )
3338  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3339  v_[element->index()*NN+j] = tmp.v_[element->index()*NN+j] * element->value();
3340 }
3341 //*************************************************************************************************
3342 
3343 
3344 
3345 
3346 
3347 
3348 
3349 
3350 //=================================================================================================
3351 //
3352 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3353 //
3354 //=================================================================================================
3355 
3356 //*************************************************************************************************
3364 template< typename Type // Data type of the matrix
3365  , size_t M // Number of rows
3366  , size_t N > // Number of columns
3367 class HybridMatrix<Type,M,N,true>
3368  : public DenseMatrix< HybridMatrix<Type,M,N,true>, true >
3369 {
3370  public:
3371  //**Type definitions****************************************************************************
3374  using ResultType = This;
3377  using ElementType = Type;
3379  using ReturnType = const Type&;
3380  using CompositeType = const This&;
3381 
3382  using Reference = Type&;
3383  using ConstReference = const Type&;
3384  using Pointer = Type*;
3385  using ConstPointer = const Type*;
3386 
3389  //**********************************************************************************************
3390 
3391  //**Rebind struct definition********************************************************************
3394  template< typename NewType > // Data type of the other matrix
3395  struct Rebind {
3396  using Other = HybridMatrix<NewType,M,N,true>;
3397  };
3398  //**********************************************************************************************
3399 
3400  //**Resize struct definition********************************************************************
3403  template< size_t NewM // Number of rows of the other matrix
3404  , size_t NewN > // Number of columns of the other matrix
3405  struct Resize {
3406  using Other = HybridMatrix<Type,NewM,NewN,true>;
3407  };
3408  //**********************************************************************************************
3409 
3410  //**Compilation flags***************************************************************************
3412 
3416  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3417 
3419 
3422  enum : bool { smpAssignable = false };
3423  //**********************************************************************************************
3424 
3425  //**Constructors********************************************************************************
3428  explicit inline HybridMatrix();
3429  explicit inline HybridMatrix( size_t m, size_t n );
3430  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
3431  explicit inline HybridMatrix( initializer_list< initializer_list<Type> > list );
3432 
3433  template< typename Other >
3434  explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
3435 
3436  template< typename Other, size_t Rows, size_t Cols >
3437  explicit inline HybridMatrix( const Other (&array)[Rows][Cols] );
3438 
3439  inline HybridMatrix( const HybridMatrix& m );
3440  template< typename MT, bool SO > inline HybridMatrix( const Matrix<MT,SO>& m );
3442  //**********************************************************************************************
3443 
3444  //**Destructor**********************************************************************************
3445  // No explicitly declared destructor.
3446  //**********************************************************************************************
3447 
3448  //**Data access functions***********************************************************************
3451  inline Reference operator()( size_t i, size_t j ) noexcept;
3452  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3453  inline Reference at( size_t i, size_t j );
3454  inline ConstReference at( size_t i, size_t j ) const;
3455  inline Pointer data () noexcept;
3456  inline ConstPointer data () const noexcept;
3457  inline Pointer data ( size_t j ) noexcept;
3458  inline ConstPointer data ( size_t j ) const noexcept;
3459  inline Iterator begin ( size_t j ) noexcept;
3460  inline ConstIterator begin ( size_t j ) const noexcept;
3461  inline ConstIterator cbegin( size_t j ) const noexcept;
3462  inline Iterator end ( size_t j ) noexcept;
3463  inline ConstIterator end ( size_t j ) const noexcept;
3464  inline ConstIterator cend ( size_t j ) const noexcept;
3466  //**********************************************************************************************
3467 
3468  //**Assignment operators************************************************************************
3471  inline HybridMatrix& operator=( const Type& set );
3472  inline HybridMatrix& operator=( initializer_list< initializer_list<Type> > list );
3473 
3474  template< typename Other, size_t Rows, size_t Cols >
3475  inline HybridMatrix& operator=( const Other (&array)[Rows][Cols] );
3476 
3477  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
3478  template< typename MT, bool SO > inline HybridMatrix& operator= ( const Matrix<MT,SO>& rhs );
3479  template< typename MT, bool SO > inline HybridMatrix& operator+=( const Matrix<MT,SO>& rhs );
3480  template< typename MT, bool SO > inline HybridMatrix& operator-=( const Matrix<MT,SO>& rhs );
3481  template< typename MT, bool SO > inline HybridMatrix& operator%=( const Matrix<MT,SO>& rhs );
3482  template< typename MT, bool SO > inline HybridMatrix& operator*=( const Matrix<MT,SO>& rhs );
3483 
3484  template< typename Other >
3485  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator*=( Other rhs );
3486 
3487  template< typename Other >
3488  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator/=( Other rhs );
3490  //**********************************************************************************************
3491 
3492  //**Utility functions***************************************************************************
3495  inline size_t rows() const noexcept;
3496  inline size_t columns() const noexcept;
3497  inline constexpr size_t spacing() const noexcept;
3498  inline constexpr size_t capacity() const noexcept;
3499  inline size_t capacity( size_t j ) const noexcept;
3500  inline size_t nonZeros() const;
3501  inline size_t nonZeros( size_t j ) const;
3502  inline void reset();
3503  inline void reset( size_t i );
3504  inline void clear();
3505  void resize ( size_t m, size_t n, bool preserve=true );
3506  inline void extend ( size_t m, size_t n, bool preserve=true );
3507  inline void swap( HybridMatrix& m ) noexcept;
3509  //**********************************************************************************************
3510 
3511  //**Numeric functions***************************************************************************
3514  inline HybridMatrix& transpose();
3515  inline HybridMatrix& ctranspose();
3516 
3517  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
3519  //**********************************************************************************************
3520 
3521  //**Memory functions****************************************************************************
3524  static inline void* operator new ( std::size_t size );
3525  static inline void* operator new[]( std::size_t size );
3526  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3527  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3528 
3529  static inline void operator delete ( void* ptr );
3530  static inline void operator delete[]( void* ptr );
3531  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3532  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3534  //**********************************************************************************************
3535 
3536  private:
3537  //**********************************************************************************************
3539  template< typename MT >
3540  struct VectorizedAssign {
3541  enum : bool { value = useOptimizedKernels &&
3542  simdEnabled && MT::simdEnabled &&
3545  };
3546  //**********************************************************************************************
3547 
3548  //**********************************************************************************************
3550  template< typename MT >
3551  struct VectorizedAddAssign {
3552  enum : bool { value = useOptimizedKernels &&
3553  simdEnabled && MT::simdEnabled &&
3558  };
3559  //**********************************************************************************************
3560 
3561  //**********************************************************************************************
3563  template< typename MT >
3564  struct VectorizedSubAssign {
3565  enum : bool { value = useOptimizedKernels &&
3566  simdEnabled && MT::simdEnabled &&
3571  };
3572  //**********************************************************************************************
3573 
3574  //**********************************************************************************************
3576  template< typename MT >
3577  struct VectorizedSchurAssign {
3578  enum : bool { value = useOptimizedKernels &&
3579  simdEnabled && MT::simdEnabled &&
3583  };
3584  //**********************************************************************************************
3585 
3586  //**********************************************************************************************
3588  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3589  //**********************************************************************************************
3590 
3591  public:
3592  //**Debugging functions*************************************************************************
3595  inline bool isIntact() const noexcept;
3597  //**********************************************************************************************
3598 
3599  //**Expression template evaluation functions****************************************************
3602  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3603  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3604 
3605  inline bool isAligned() const noexcept;
3606 
3607  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3608  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3609  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3610 
3611  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3612  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3613  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3614  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3615 
3616  template< typename MT, bool SO >
3617  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3618 
3619  template< typename MT, bool SO >
3620  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3621 
3622  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3623  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3624 
3625  template< typename MT, bool SO >
3626  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3627 
3628  template< typename MT, bool SO >
3629  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3630 
3631  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3632  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3633 
3634  template< typename MT, bool SO >
3635  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3636 
3637  template< typename MT, bool SO >
3638  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3639 
3640  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3641  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3642 
3643  template< typename MT, bool SO >
3644  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
3645 
3646  template< typename MT, bool SO >
3647  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
3648 
3649  template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3650  template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3652  //**********************************************************************************************
3653 
3654  private:
3655  //**********************************************************************************************
3657  enum : size_t { MM = ( usePadding )?( nextMultiple( M, SIMDSIZE ) ):( M ) };
3658  //**********************************************************************************************
3659 
3660  //**Member variables****************************************************************************
3664 
3666  size_t m_;
3667  size_t n_;
3668 
3669  //**********************************************************************************************
3670 
3671  //**Compile time checks*************************************************************************
3676  BLAZE_STATIC_ASSERT( !usePadding || MM % SIMDSIZE == 0UL );
3677  BLAZE_STATIC_ASSERT( MM >= M );
3678  //**********************************************************************************************
3679 };
3681 //*************************************************************************************************
3682 
3683 
3684 
3685 
3686 //=================================================================================================
3687 //
3688 // CONSTRUCTORS
3689 //
3690 //=================================================================================================
3691 
3692 //*************************************************************************************************
3698 template< typename Type // Data type of the matrix
3699  , size_t M // Number of rows
3700  , size_t N > // Number of columns
3702  : v_() // The statically allocated matrix elements
3703  , m_( 0UL ) // The current number of rows of the matrix
3704  , n_( 0UL ) // The current number of columns of the matrix
3705 {
3707 
3708  if( IsNumeric<Type>::value ) {
3709  for( size_t i=0UL; i<MM*N; ++i )
3710  v_[i] = Type();
3711  }
3712 
3713  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3714 }
3716 //*************************************************************************************************
3717 
3718 
3719 //*************************************************************************************************
3733 template< typename Type // Data type of the matrix
3734  , size_t M // Number of rows
3735  , size_t N > // Number of columns
3736 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n )
3737  : v_() // The statically allocated matrix elements
3738  , m_( m ) // The current number of rows of the matrix
3739  , n_( n ) // The current number of columns of the matrix
3740 {
3742 
3743  if( m > M ) {
3744  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3745  }
3746 
3747  if( n > N ) {
3748  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3749  }
3750 
3751  if( IsNumeric<Type>::value ) {
3752  for( size_t i=0UL; i<MM*N; ++i )
3753  v_[i] = Type();
3754  }
3755 
3756  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3757 }
3759 //*************************************************************************************************
3760 
3761 
3762 //*************************************************************************************************
3777 template< typename Type // Data type of the matrix
3778  , size_t M // Number of rows
3779  , size_t N > // Number of columns
3780 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Type& init )
3781  : v_() // The statically allocated matrix elements
3782  , m_( m ) // The current number of rows of the matrix
3783  , n_( n ) // The current number of columns of the matrix
3784 {
3786 
3787  if( m > M ) {
3788  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3789  }
3790 
3791  if( n > N ) {
3792  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3793  }
3794 
3795  for( size_t j=0UL; j<n; ++j ) {
3796  for( size_t i=0UL; i<m; ++i )
3797  v_[i+j*MM] = init;
3798 
3799  if( IsNumeric<Type>::value ) {
3800  for( size_t i=m; i<MM; ++i )
3801  v_[i+j*MM] = Type();
3802  }
3803  }
3804 
3805  if( IsNumeric<Type>::value ) {
3806  for( size_t j=n; j<N; ++j )
3807  for( size_t i=0UL; i<MM; ++i )
3808  v_[i+j*MM] = Type();
3809  }
3810 
3811  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3812 }
3814 //*************************************************************************************************
3815 
3816 
3817 //*************************************************************************************************
3842 template< typename Type // Data type of the matrix
3843  , size_t M // Number of rows
3844  , size_t N > // Number of columns
3846  : v_() // The statically allocated matrix elements
3847  , m_( list.size() ) // The current number of rows of the matrix
3848  , n_( determineColumns( list ) ) // The current number of columns of the matrix
3849 {
3851 
3852  if( m_ > M ) {
3853  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3854  }
3855 
3856  if( n_ > N ) {
3857  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3858  }
3859 
3860  size_t i( 0UL );
3861 
3862  for( const auto& rowList : list ) {
3863  size_t j( 0UL );
3864  for( const auto& element : rowList ) {
3865  v_[i+j*MM] = element;
3866  ++j;
3867  }
3868  if( IsNumeric<Type>::value ) {
3869  for( ; j<N; ++j ) {
3870  v_[i+j*MM] = Type();
3871  }
3872  }
3873  ++i;
3874  }
3875 
3876  BLAZE_INTERNAL_ASSERT( i == m_, "Invalid number of elements detected" );
3877 
3878  if( IsNumeric<Type>::value ) {
3879  for( ; i<MM; ++i ) {
3880  for( size_t j=0UL; j<N; ++j ) {
3881  v_[i+j*MM] = Type();
3882  }
3883  }
3884  }
3885 
3886  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3887 }
3889 //*************************************************************************************************
3890 
3891 
3892 //*************************************************************************************************
3920 template< typename Type // Data type of the matrix
3921  , size_t M // Number of rows
3922  , size_t N > // Number of columns
3923 template< typename Other > // Data type of the initialization array
3924 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Other* array )
3925  : v_() // The statically allocated matrix elements
3926  , m_( m ) // The current number of rows of the matrix
3927  , n_( n ) // The current number of columns of the matrix
3928 {
3930 
3931  if( m > M ) {
3932  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3933  }
3934 
3935  if( n > N ) {
3936  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3937  }
3938 
3939  for( size_t j=0UL; j<n; ++j ) {
3940  for( size_t i=0UL; i<m; ++i )
3941  v_[i+j*MM] = array[i+j*m];
3942 
3943  if( IsNumeric<Type>::value ) {
3944  for( size_t i=m; i<MM; ++i )
3945  v_[i+j*MM] = Type();
3946  }
3947  }
3948 
3949  if( IsNumeric<Type>::value ) {
3950  for( size_t j=n; j<N; ++j )
3951  for( size_t i=0UL; i<MM; ++i )
3952  v_[i+j*MM] = Type();
3953  }
3954 
3955  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3956 }
3958 //*************************************************************************************************
3959 
3960 
3961 //*************************************************************************************************
3983 template< typename Type // Data type of the matrix
3984  , size_t M // Number of rows
3985  , size_t N > // Number of columns
3986 template< typename Other // Data type of the initialization array
3987  , size_t Rows // Number of rows of the initialization array
3988  , size_t Cols > // Number of columns of the initialization array
3989 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const Other (&array)[Rows][Cols] )
3990  : v_() // The statically allocated matrix elements
3991  , m_( Rows ) // The current number of rows of the matrix
3992  , n_( Cols ) // The current number of columns of the matrix
3993 {
3994  BLAZE_STATIC_ASSERT( Rows <= M );
3995  BLAZE_STATIC_ASSERT( Cols <= N );
3997 
3998  for( size_t j=0UL; j<Cols; ++j ) {
3999  for( size_t i=0UL; i<Rows; ++i )
4000  v_[i+j*MM] = array[i][j];
4001 
4002  if( IsNumeric<Type>::value ) {
4003  for( size_t i=Rows; i<MM; ++i )
4004  v_[i+j*MM] = Type();
4005  }
4006  }
4007 
4008  if( IsNumeric<Type>::value ) {
4009  for( size_t j=Cols; j<N; ++j )
4010  for( size_t i=0UL; i<MM; ++i )
4011  v_[i+j*MM] = Type();
4012  }
4013 
4014  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4015 }
4017 //*************************************************************************************************
4018 
4019 
4020 //*************************************************************************************************
4029 template< typename Type // Data type of the matrix
4030  , size_t M // Number of rows
4031  , size_t N > // Number of columns
4033  : v_() // The statically allocated matrix elements
4034  , m_( m.m_ ) // The current number of rows of the matrix
4035  , n_( m.n_ ) // The current number of columns of the matrix
4036 {
4038 
4039  for( size_t j=0UL; j<n_; ++j ) {
4040  for( size_t i=0UL; i<m_; ++i )
4041  v_[i+j*MM] = m.v_[i+j*MM];
4042 
4043  if( IsNumeric<Type>::value ) {
4044  for( size_t i=m_; i<MM; ++i )
4045  v_[i+j*MM] = Type();
4046  }
4047  }
4048 
4049  if( IsNumeric<Type>::value ) {
4050  for( size_t j=n_; j<N; ++j )
4051  for( size_t i=0UL; i<MM; ++i )
4052  v_[i+j*MM] = Type();
4053  }
4054 
4055  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4056 }
4058 //*************************************************************************************************
4059 
4060 
4061 //*************************************************************************************************
4068 template< typename Type // Data type of the matrix
4069  , size_t M // Number of rows
4070  , size_t N > // Number of columns
4071 template< typename MT // Type of the foreign matrix
4072  , bool SO2 > // Storage order of the foreign matrix
4074  : v_() // The statically allocated matrix elements
4075  , m_( (~m).rows() ) // The current number of rows of the matrix
4076  , n_( (~m).columns() ) // The current number of columns of the matrix
4077 {
4078  using blaze::assign;
4079 
4081 
4082  if( (~m).rows() > M || (~m).columns() > N ) {
4083  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
4084  }
4085 
4086  for( size_t j=0UL; j<n_; ++j ) {
4087  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : m_ );
4088  i<( IsNumeric<Type>::value ? MM : m_ );
4089  ++i ) {
4090  v_[i+j*MM] = Type();
4091  }
4092  }
4093 
4094  if( IsNumeric<Type>::value ) {
4095  for( size_t j=n_; j<N; ++j )
4096  for( size_t i=0UL; i<MM; ++i )
4097  v_[i+j*MM] = Type();
4098  }
4099 
4100  assign( *this, ~m );
4101 
4102  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4103 }
4105 //*************************************************************************************************
4106 
4107 
4108 
4109 
4110 //=================================================================================================
4111 //
4112 // DATA ACCESS FUNCTIONS
4113 //
4114 //=================================================================================================
4115 
4116 //*************************************************************************************************
4127 template< typename Type // Data type of the matrix
4128  , size_t M // Number of rows
4129  , size_t N > // Number of columns
4131  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) noexcept
4132 {
4133  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
4134  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
4135  return v_[i+j*MM];
4136 }
4138 //*************************************************************************************************
4139 
4140 
4141 //*************************************************************************************************
4152 template< typename Type // Data type of the matrix
4153  , size_t M // Number of rows
4154  , size_t N > // Number of columns
4156  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const noexcept
4157 {
4158  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
4159  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
4160  return v_[i+j*MM];
4161 }
4163 //*************************************************************************************************
4164 
4165 
4166 //*************************************************************************************************
4178 template< typename Type // Data type of the matrix
4179  , size_t M // Number of rows
4180  , size_t N > // Number of columns
4182  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j )
4183 {
4184  if( i >= m_ ) {
4185  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4186  }
4187  if( j >= n_ ) {
4188  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4189  }
4190  return (*this)(i,j);
4191 }
4193 //*************************************************************************************************
4194 
4195 
4196 //*************************************************************************************************
4208 template< typename Type // Data type of the matrix
4209  , size_t M // Number of rows
4210  , size_t N > // Number of columns
4212  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
4213 {
4214  if( i >= m_ ) {
4215  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4216  }
4217  if( j >= n_ ) {
4218  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4219  }
4220  return (*this)(i,j);
4221 }
4223 //*************************************************************************************************
4224 
4225 
4226 //*************************************************************************************************
4238 template< typename Type // Data type of the matrix
4239  , size_t M // Number of rows
4240  , size_t N > // Number of columns
4243 {
4244  return v_;
4245 }
4247 //*************************************************************************************************
4248 
4249 
4250 //*************************************************************************************************
4262 template< typename Type // Data type of the matrix
4263  , size_t M // Number of rows
4264  , size_t N > // Number of columns
4266  HybridMatrix<Type,M,N,true>::data() const noexcept
4267 {
4268  return v_;
4269 }
4271 //*************************************************************************************************
4272 
4273 
4274 //*************************************************************************************************
4283 template< typename Type // Data type of the matrix
4284  , size_t M // Number of rows
4285  , size_t N > // Number of columns
4287  HybridMatrix<Type,M,N,true>::data( size_t j ) noexcept
4288 {
4289  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4290  return v_ + j*MM;
4291 }
4293 //*************************************************************************************************
4294 
4295 
4296 //*************************************************************************************************
4305 template< typename Type // Data type of the matrix
4306  , size_t M // Number of rows
4307  , size_t N > // Number of columns
4309  HybridMatrix<Type,M,N,true>::data( size_t j ) const noexcept
4310 {
4311  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4312  return v_ + j*MM;
4313 }
4315 //*************************************************************************************************
4316 
4317 
4318 //*************************************************************************************************
4325 template< typename Type // Data type of the matrix
4326  , size_t M // Number of rows
4327  , size_t N > // Number of columns
4329  HybridMatrix<Type,M,N,true>::begin( size_t j ) noexcept
4330 {
4331  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4332  return Iterator( v_ + j*MM );
4333 }
4335 //*************************************************************************************************
4336 
4337 
4338 //*************************************************************************************************
4345 template< typename Type // Data type of the matrix
4346  , size_t M // Number of rows
4347  , size_t N > // Number of columns
4349  HybridMatrix<Type,M,N,true>::begin( size_t j ) const noexcept
4350 {
4351  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4352  return ConstIterator( v_ + j*MM );
4353 }
4355 //*************************************************************************************************
4356 
4357 
4358 //*************************************************************************************************
4365 template< typename Type // Data type of the matrix
4366  , size_t M // Number of rows
4367  , size_t N > // Number of columns
4369  HybridMatrix<Type,M,N,true>::cbegin( size_t j ) const noexcept
4370 {
4371  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4372  return ConstIterator( v_ + j*MM );
4373 }
4375 //*************************************************************************************************
4376 
4377 
4378 //*************************************************************************************************
4385 template< typename Type // Data type of the matrix
4386  , size_t M // Number of rows
4387  , size_t N > // Number of columns
4389  HybridMatrix<Type,M,N,true>::end( size_t j ) noexcept
4390 {
4391  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4392  return Iterator( v_ + j*MM + M );
4393 }
4395 //*************************************************************************************************
4396 
4397 
4398 //*************************************************************************************************
4405 template< typename Type // Data type of the matrix
4406  , size_t M // Number of rows
4407  , size_t N > // Number of columns
4409  HybridMatrix<Type,M,N,true>::end( size_t j ) const noexcept
4410 {
4411  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4412  return ConstIterator( v_ + j*MM + M );
4413 }
4415 //*************************************************************************************************
4416 
4417 
4418 //*************************************************************************************************
4425 template< typename Type // Data type of the matrix
4426  , size_t M // Number of rows
4427  , size_t N > // Number of columns
4429  HybridMatrix<Type,M,N,true>::cend( size_t j ) const noexcept
4430 {
4431  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4432  return ConstIterator( v_ + j*MM + M );
4433 }
4435 //*************************************************************************************************
4436 
4437 
4438 
4439 
4440 //=================================================================================================
4441 //
4442 // ASSIGNMENT OPERATORS
4443 //
4444 //=================================================================================================
4445 
4446 //*************************************************************************************************
4453 template< typename Type // Data type of the matrix
4454  , size_t M // Number of rows
4455  , size_t N > // Number of columns
4457  HybridMatrix<Type,M,N,true>::operator=( const Type& set )
4458 {
4459  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
4460  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
4461 
4462  for( size_t j=0UL; j<n_; ++j )
4463  for( size_t i=0UL; i<m_; ++i )
4464  v_[i+j*MM] = set;
4465 
4466  return *this;
4467 }
4469 //*************************************************************************************************
4470 
4471 
4472 //*************************************************************************************************
4498 template< typename Type // Data type of the matrix
4499  , size_t M // Number of rows
4500  , size_t N > // Number of columns
4503 {
4504  const size_t m( list.size() );
4505  const size_t n( determineColumns( list ) );
4506 
4507  if( m > M ) {
4508  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4509  }
4510 
4511  if( n > N ) {
4512  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4513  }
4514 
4515  resize( m, n, false );
4516 
4517  size_t i( 0UL );
4518 
4519  for( const auto& rowList : list ) {
4520  size_t j( 0UL );
4521  for( const auto& element : rowList ) {
4522  v_[i+j*MM] = element;
4523  ++j;
4524  }
4525  for( ; j<n_; ++j ) {
4526  v_[i+j*MM] = Type();
4527  }
4528  ++i;
4529  }
4530 
4531  return *this;
4532 }
4534 //*************************************************************************************************
4535 
4536 
4537 //*************************************************************************************************
4559 template< typename Type // Data type of the matrix
4560  , size_t M // Number of rows
4561  , size_t N > // Number of columns
4562 template< typename Other // Data type of the initialization array
4563  , size_t Rows // Number of rows of the initialization array
4564  , size_t Cols > // Number of columns of the initialization array
4566  HybridMatrix<Type,M,N,true>::operator=( const Other (&array)[Rows][Cols] )
4567 {
4568  BLAZE_STATIC_ASSERT( Rows <= M );
4569  BLAZE_STATIC_ASSERT( Cols <= N );
4570 
4571  resize( Rows, Cols );
4572 
4573  for( size_t j=0UL; j<Cols; ++j )
4574  for( size_t i=0UL; i<Rows; ++i )
4575  v_[i+j*MM] = array[i][j];
4576 
4577  return *this;
4578 }
4580 //*************************************************************************************************
4581 
4582 
4583 //*************************************************************************************************
4592 template< typename Type // Data type of the matrix
4593  , size_t M // Number of rows
4594  , size_t N > // Number of columns
4597 {
4598  using blaze::assign;
4599 
4600  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
4601  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
4602 
4603  resize( rhs.rows(), rhs.columns() );
4604  assign( *this, ~rhs );
4605 
4606  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4607 
4608  return *this;
4609 }
4611 //*************************************************************************************************
4612 
4613 
4614 //*************************************************************************************************
4626 template< typename Type // Data type of the matrix
4627  , size_t M // Number of rows
4628  , size_t N > // Number of columns
4629 template< typename MT // Type of the right-hand side matrix
4630  , bool SO > // Storage order of the right-hand side matrix
4632 {
4633  using blaze::assign;
4634 
4635  using TT = TransExprTrait_<This>;
4636  using CT = CTransExprTrait_<This>;
4637  using IT = InvExprTrait_<This>;
4638 
4639  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
4640  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
4641  }
4642 
4643  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4644  transpose();
4645  }
4646  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4647  ctranspose();
4648  }
4649  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4650  HybridMatrix tmp( ~rhs );
4651  resize( tmp.rows(), tmp.columns() );
4652  assign( *this, tmp );
4653  }
4654  else {
4655  resize( (~rhs).rows(), (~rhs).columns() );
4657  reset();
4658  assign( *this, ~rhs );
4659  }
4660 
4661  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4662 
4663  return *this;
4664 }
4666 //*************************************************************************************************
4667 
4668 
4669 //*************************************************************************************************
4680 template< typename Type // Data type of the matrix
4681  , size_t M // Number of rows
4682  , size_t N > // Number of columns
4683 template< typename MT // Type of the right-hand side matrix
4684  , bool SO > // Storage order of the right-hand side matrix
4686 {
4687  using blaze::addAssign;
4688 
4689  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4690  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4691  }
4692 
4693  if( (~rhs).canAlias( this ) ) {
4694  const ResultType_<MT> tmp( ~rhs );
4695  addAssign( *this, tmp );
4696  }
4697  else {
4698  addAssign( *this, ~rhs );
4699  }
4700 
4701  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4702 
4703  return *this;
4704 }
4706 //*************************************************************************************************
4707 
4708 
4709 //*************************************************************************************************
4720 template< typename Type // Data type of the matrix
4721  , size_t M // Number of rows
4722  , size_t N > // Number of columns
4723 template< typename MT // Type of the right-hand side matrix
4724  , bool SO > // Storage order of the right-hand side matrix
4726 {
4727  using blaze::subAssign;
4728 
4729  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4730  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4731  }
4732 
4733  if( (~rhs).canAlias( this ) ) {
4734  const ResultType_<MT> tmp( ~rhs );
4735  subAssign( *this, tmp );
4736  }
4737  else {
4738  subAssign( *this, ~rhs );
4739  }
4740 
4741  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4742 
4743  return *this;
4744 }
4746 //*************************************************************************************************
4747 
4748 
4749 //*************************************************************************************************
4760 template< typename Type // Data type of the matrix
4761  , size_t M // Number of rows
4762  , size_t N > // Number of columns
4763 template< typename MT // Type of the right-hand side matrix
4764  , bool SO > // Storage order of the right-hand side matrix
4766 {
4767  using blaze::schurAssign;
4768 
4769  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4770  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4771  }
4772 
4773  if( (~rhs).canAlias( this ) ) {
4774  const ResultType_<MT> tmp( ~rhs );
4775  schurAssign( *this, tmp );
4776  }
4777  else {
4778  schurAssign( *this, ~rhs );
4779  }
4780 
4781  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4782 
4783  return *this;
4784 }
4786 //*************************************************************************************************
4787 
4788 
4789 //*************************************************************************************************
4800 template< typename Type // Data type of the matrix
4801  , size_t M // Number of rows
4802  , size_t N > // Number of columns
4803 template< typename MT // Type of the right-hand side matrix
4804  , bool SO > // Storage order of the right-hand side matrix
4806 {
4807  using blaze::assign;
4808 
4809  if( n_ != (~rhs).rows() || (~rhs).columns() > N ) {
4810  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4811  }
4812 
4813  const HybridMatrix tmp( *this * (~rhs) );
4814  resize( tmp.rows(), tmp.columns() );
4815  assign( *this, tmp );
4816 
4817  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4818 
4819  return *this;
4820 }
4822 //*************************************************************************************************
4823 
4824 
4825 //*************************************************************************************************
4833 template< typename Type // Data type of the matrix
4834  , size_t M // Number of rows
4835  , size_t N > // Number of columns
4836 template< typename Other > // Data type of the right-hand side scalar
4837 inline EnableIf_<IsNumeric<Other>, HybridMatrix<Type,M,N,true> >&
4839 {
4840  using blaze::assign;
4841 
4842  assign( *this, (*this) * rhs );
4843 
4844  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4845 
4846  return *this;
4847 }
4849 //*************************************************************************************************
4850 
4851 
4852 //*************************************************************************************************
4862 template< typename Type // Data type of the matrix
4863  , size_t M // Number of rows
4864  , size_t N > // Number of columns
4865 template< typename Other > // Data type of the right-hand side scalar
4866 inline EnableIf_<IsNumeric<Other>, HybridMatrix<Type,M,N,true> >&
4868 {
4869  using blaze::assign;
4870 
4871  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4872 
4873  assign( *this, (*this) / rhs );
4874 
4875  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4876 
4877  return *this;
4878 }
4880 //*************************************************************************************************
4881 
4882 
4883 
4884 
4885 //=================================================================================================
4886 //
4887 // UTILITY FUNCTIONS
4888 //
4889 //=================================================================================================
4890 
4891 //*************************************************************************************************
4897 template< typename Type // Data type of the matrix
4898  , size_t M // Number of rows
4899  , size_t N > // Number of columns
4900 inline size_t HybridMatrix<Type,M,N,true>::rows() const noexcept
4901 {
4902  return m_;
4903 }
4905 //*************************************************************************************************
4906 
4907 
4908 //*************************************************************************************************
4914 template< typename Type // Data type of the matrix
4915  , size_t M // Number of rows
4916  , size_t N > // Number of columns
4917 inline size_t HybridMatrix<Type,M,N,true>::columns() const noexcept
4918 {
4919  return n_;
4920 }
4922 //*************************************************************************************************
4923 
4924 
4925 //*************************************************************************************************
4934 template< typename Type // Data type of the matrix
4935  , size_t M // Number of rows
4936  , size_t N > // Number of columns
4937 inline constexpr size_t HybridMatrix<Type,M,N,true>::spacing() const noexcept
4938 {
4939  return MM;
4940 }
4942 //*************************************************************************************************
4943 
4944 
4945 //*************************************************************************************************
4951 template< typename Type // Data type of the matrix
4952  , size_t M // Number of rows
4953  , size_t N > // Number of columns
4954 inline constexpr size_t HybridMatrix<Type,M,N,true>::capacity() const noexcept
4955 {
4956  return MM*N;
4957 }
4959 //*************************************************************************************************
4960 
4961 
4962 //*************************************************************************************************
4969 template< typename Type // Data type of the matrix
4970  , size_t M // Number of rows
4971  , size_t N > // Number of columns
4972 inline size_t HybridMatrix<Type,M,N,true>::capacity( size_t j ) const noexcept
4973 {
4974  UNUSED_PARAMETER( j );
4975 
4976  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4977 
4978  return MM;
4979 }
4981 //*************************************************************************************************
4982 
4983 
4984 //*************************************************************************************************
4990 template< typename Type // Data type of the matrix
4991  , size_t M // Number of rows
4992  , size_t N > // Number of columns
4993 inline size_t HybridMatrix<Type,M,N,true>::nonZeros() const
4994 {
4995  size_t nonzeros( 0UL );
4996 
4997  for( size_t j=0UL; j<n_; ++j )
4998  for( size_t i=0UL; i<m_; ++i )
4999  if( !isDefault( v_[i+j*MM] ) )
5000  ++nonzeros;
5001 
5002  return nonzeros;
5003 }
5005 //*************************************************************************************************
5006 
5007 
5008 //*************************************************************************************************
5015 template< typename Type // Data type of the matrix
5016  , size_t M // Number of rows
5017  , size_t N > // Number of columns
5018 inline size_t HybridMatrix<Type,M,N,true>::nonZeros( size_t j ) const
5019 {
5020  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5021 
5022  const size_t iend( j*MM + m_ );
5023  size_t nonzeros( 0UL );
5024 
5025  for( size_t i=j*MM; i<iend; ++i )
5026  if( !isDefault( v_[i] ) )
5027  ++nonzeros;
5028 
5029  return nonzeros;
5030 }
5032 //*************************************************************************************************
5033 
5034 
5035 //*************************************************************************************************
5041 template< typename Type // Data type of the matrix
5042  , size_t M // Number of rows
5043  , size_t N > // Number of columns
5045 {
5046  using blaze::clear;
5047 
5048  for( size_t j=0UL; j<n_; ++j )
5049  for( size_t i=0UL; i<m_; ++i )
5050  clear( v_[i+j*MM] );
5051 }
5053 //*************************************************************************************************
5054 
5055 
5056 //*************************************************************************************************
5066 template< typename Type // Data type of the matrix
5067  , size_t M // Number of rows
5068  , size_t N > // Number of columns
5069 inline void HybridMatrix<Type,M,N,true>::reset( size_t j )
5070 {
5071  using blaze::clear;
5072 
5073  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
5074  for( size_t i=0UL; i<m_; ++i )
5075  clear( v_[i+j*MM] );
5076 }
5078 //*************************************************************************************************
5079 
5080 
5081 //*************************************************************************************************
5089 template< typename Type // Data type of the matrix
5090  , size_t M // Number of rows
5091  , size_t N > // Number of columns
5093 {
5094  resize( 0UL, 0UL );
5095 }
5097 //*************************************************************************************************
5098 
5099 
5100 //*************************************************************************************************
5137 template< typename Type // Data type of the matrix
5138  , size_t M // Number of rows
5139  , size_t N > // Number of columns
5140 void HybridMatrix<Type,M,N,true>::resize( size_t m, size_t n, bool preserve )
5141 {
5142  UNUSED_PARAMETER( preserve );
5143 
5144  if( m > M ) {
5145  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
5146  }
5147 
5148  if( n > N ) {
5149  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
5150  }
5151 
5152  if( IsVectorizable<Type>::value && m < m_ ) {
5153  for( size_t j=0UL; j<n; ++j )
5154  for( size_t i=m; i<m_; ++i )
5155  v_[i+j*MM] = Type();
5156  }
5157 
5158  if( IsVectorizable<Type>::value && n < n_ ) {
5159  for( size_t j=n; j<n_; ++j )
5160  for( size_t i=0UL; i<m_; ++i )
5161  v_[i+j*MM] = Type();
5162  }
5163 
5164  m_ = m;
5165  n_ = n;
5166 }
5168 //*************************************************************************************************
5169 
5170 
5171 //*************************************************************************************************
5187 template< typename Type // Data type of the matrix
5188  , size_t M // Number of rows
5189  , size_t N > // Number of columns
5190 inline void HybridMatrix<Type,M,N,true>::extend( size_t m, size_t n, bool preserve )
5191 {
5192  UNUSED_PARAMETER( preserve );
5193  resize( m_+m, n_+n );
5194 }
5196 //*************************************************************************************************
5197 
5198 
5199 //*************************************************************************************************
5206 template< typename Type // Data type of the matrix
5207  , size_t M // Number of rows
5208  , size_t N > // Number of columns
5209 inline void HybridMatrix<Type,M,N,true>::swap( HybridMatrix& m ) noexcept
5210 {
5211  using std::swap;
5212 
5213  const size_t maxrows( max( m_, m.m_ ) );
5214  const size_t maxcols( max( n_, m.n_ ) );
5215 
5216  for( size_t j=0UL; j<maxcols; ++j ) {
5217  for( size_t i=0UL; i<maxrows; ++i ) {
5218  swap( v_[i+j*MM], m(i,j) );
5219  }
5220  }
5221 
5222  swap( m_, m.m_ );
5223  swap( n_, m.n_ );
5224 }
5226 //*************************************************************************************************
5227 
5228 
5229 
5230 
5231 //=================================================================================================
5232 //
5233 // NUMERIC FUNCTIONS
5234 //
5235 //=================================================================================================
5236 
5237 //*************************************************************************************************
5249 template< typename Type // Data type of the matrix
5250  , size_t M // Number of rows
5251  , size_t N > // Number of columns
5253 {
5254  using std::swap;
5255 
5256  if( m_ > N || n_ > M ) {
5257  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
5258  }
5259 
5260  const size_t maxsize( max( m_, n_ ) );
5261  for( size_t j=1UL; j<maxsize; ++j ) {
5262  for( size_t i=0UL; i<j; ++i ) {
5263  swap( v_[i+j*MM], v_[j+i*MM] );
5264  }
5265  }
5266 
5267  if( IsVectorizable<Type>::value && n_ < m_ ) {
5268  for( size_t j=0UL; j<n_; ++j ) {
5269  for( size_t i=n_; i<m_; ++i ) {
5270  v_[i+j*MM] = Type();
5271  }
5272  }
5273  }
5274 
5275  if( IsVectorizable<Type>::value && n_ > m_ ) {
5276  for( size_t j=m_; j<n_; ++j ) {
5277  for( size_t i=0UL; i<m_; ++i ) {
5278  v_[i+j*MM] = Type();
5279  }
5280  }
5281  }
5282 
5283  swap( m_, n_ );
5284 
5285  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5286 
5287  return *this;
5288 }
5290 //*************************************************************************************************
5291 
5292 
5293 //*************************************************************************************************
5305 template< typename Type // Data type of the matrix
5306  , size_t M // Number of rows
5307  , size_t N > // Number of columns
5309 {
5310  using std::swap;
5311 
5312  if( m_ > N || n_ > M ) {
5313  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
5314  }
5315 
5316  const size_t maxsize( max( m_, n_ ) );
5317  for( size_t j=0UL; j<maxsize; ++j ) {
5318  for( size_t i=0UL; i<j; ++i ) {
5319  cswap( v_[i+j*MM], v_[j+i*MM] );
5320  }
5321  conjugate( v_[j+j*MM] );
5322  }
5323 
5324  if( IsVectorizable<Type>::value && n_ < m_ ) {
5325  for( size_t j=0UL; j<n_; ++j ) {
5326  for( size_t i=n_; i<m_; ++i ) {
5327  v_[i+j*MM] = Type();
5328  }
5329  }
5330  }
5331 
5332  if( IsVectorizable<Type>::value && n_ > m_ ) {
5333  for( size_t j=m_; j<n_; ++j ) {
5334  for( size_t i=0UL; i<m_; ++i ) {
5335  v_[i+j*MM] = Type();
5336  }
5337  }
5338  }
5339 
5340  swap( m_, n_ );
5341 
5342  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5343 
5344  return *this;
5345 }
5347 //*************************************************************************************************
5348 
5349 
5350 //*************************************************************************************************
5368 template< typename Type // Data type of the matrix
5369  , size_t M // Number of rows
5370  , size_t N > // Number of columns
5371 template< typename Other > // Data type of the scalar value
5373  HybridMatrix<Type,M,N,true>::scale( const Other& scalar )
5374 {
5375  for( size_t j=0UL; j<n_; ++j )
5376  for( size_t i=0UL; i<m_; ++i )
5377  v_[i+j*MM] *= scalar;
5378 
5379  return *this;
5380 }
5382 //*************************************************************************************************
5383 
5384 
5385 
5386 
5387 //=================================================================================================
5388 //
5389 // MEMORY FUNCTIONS
5390 //
5391 //=================================================================================================
5392 
5393 //*************************************************************************************************
5404 template< typename Type // Data type of the matrix
5405  , size_t M // Number of rows
5406  , size_t N > // Number of columns
5407 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size )
5408 {
5409  UNUSED_PARAMETER( size );
5410 
5411  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5412 
5413  return allocate<HybridMatrix>( 1UL );
5414 }
5416 //*************************************************************************************************
5417 
5418 
5419 //*************************************************************************************************
5430 template< typename Type // Data type of the matrix
5431  , size_t M // Number of rows
5432  , size_t N > // Number of columns
5433 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size )
5434 {
5435  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5436  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5437 
5438  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5439 }
5441 //*************************************************************************************************
5442 
5443 
5444 //*************************************************************************************************
5455 template< typename Type // Data type of the matrix
5456  , size_t M // Number of rows
5457  , size_t N > // Number of columns
5458 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
5459 {
5460  UNUSED_PARAMETER( size );
5461 
5462  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5463 
5464  return allocate<HybridMatrix>( 1UL );
5465 }
5467 //*************************************************************************************************
5468 
5469 
5470 //*************************************************************************************************
5481 template< typename Type // Data type of the matrix
5482  , size_t M // Number of rows
5483  , size_t N > // Number of columns
5484 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
5485 {
5486  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5487  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5488 
5489  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5490 }
5492 //*************************************************************************************************
5493 
5494 
5495 //*************************************************************************************************
5502 template< typename Type // Data type of the matrix
5503  , size_t M // Number of rows
5504  , size_t N > // Number of columns
5505 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr )
5506 {
5507  deallocate( static_cast<HybridMatrix*>( ptr ) );
5508 }
5510 //*************************************************************************************************
5511 
5512 
5513 //*************************************************************************************************
5520 template< typename Type // Data type of the matrix
5521  , size_t M // Number of rows
5522  , size_t N > // Number of columns
5523 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr )
5524 {
5525  deallocate( static_cast<HybridMatrix*>( ptr ) );
5526 }
5528 //*************************************************************************************************
5529 
5530 
5531 //*************************************************************************************************
5538 template< typename Type // Data type of the matrix
5539  , size_t M // Number of rows
5540  , size_t N > // Number of columns
5541 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
5542 {
5543  deallocate( static_cast<HybridMatrix*>( ptr ) );
5544 }
5546 //*************************************************************************************************
5547 
5548 
5549 //*************************************************************************************************
5556 template< typename Type // Data type of the matrix
5557  , size_t M // Number of rows
5558  , size_t N > // Number of columns
5559 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
5560 {
5561  deallocate( static_cast<HybridMatrix*>( ptr ) );
5562 }
5564 //*************************************************************************************************
5565 
5566 
5567 
5568 
5569 //=================================================================================================
5570 //
5571 // DEBUGGING FUNCTIONS
5572 //
5573 //=================================================================================================
5574 
5575 //*************************************************************************************************
5585 template< typename Type // Data type of the matrix
5586  , size_t M // Number of rows
5587  , size_t N > // Number of columns
5588 inline bool HybridMatrix<Type,M,N,true>::isIntact() const noexcept
5589 {
5590  if( m_ > M || n_ > N )
5591  return false;
5592 
5594  {
5595  for( size_t j=0UL; j<n_; ++j ) {
5596  for( size_t i=m_; i<MM; ++i ) {
5597  if( v_[i+j*MM] != Type() )
5598  return false;
5599  }
5600  }
5601 
5602  for( size_t j=n_; j<N; ++j ) {
5603  for( size_t i=0UL; i<MM; ++i ) {
5604  if( v_[i+j*MM] != Type() )
5605  return false;
5606  }
5607  }
5608  }
5609 
5610  return true;
5611 }
5613 //*************************************************************************************************
5614 
5615 
5616 
5617 
5618 //=================================================================================================
5619 //
5620 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5621 //
5622 //=================================================================================================
5623 
5624 //*************************************************************************************************
5635 template< typename Type // Data type of the matrix
5636  , size_t M // Number of rows
5637  , size_t N > // Number of columns
5638 template< typename Other > // Data type of the foreign expression
5639 inline bool HybridMatrix<Type,M,N,true>::canAlias( const Other* alias ) const noexcept
5640 {
5641  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5642 }
5644 //*************************************************************************************************
5645 
5646 
5647 //*************************************************************************************************
5658 template< typename Type // Data type of the matrix
5659  , size_t M // Number of rows
5660  , size_t N > // Number of columns
5661 template< typename Other > // Data type of the foreign expression
5662 inline bool HybridMatrix<Type,M,N,true>::isAliased( const Other* alias ) const noexcept
5663 {
5664  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5665 }
5667 //*************************************************************************************************
5668 
5669 
5670 //*************************************************************************************************
5680 template< typename Type // Data type of the matrix
5681  , size_t M // Number of rows
5682  , size_t N > // Number of columns
5683 inline bool HybridMatrix<Type,M,N,true>::isAligned() const noexcept
5684 {
5685  return ( usePadding || rows() % SIMDSIZE == 0UL );
5686 }
5688 //*************************************************************************************************
5689 
5690 
5691 //*************************************************************************************************
5706 template< typename Type // Data type of the matrix
5707  , size_t M // Number of rows
5708  , size_t N > // Number of columns
5710  HybridMatrix<Type,M,N,true>::load( size_t i, size_t j ) const noexcept
5711 {
5712  if( usePadding )
5713  return loada( i, j );
5714  else
5715  return loadu( i, j );
5716 }
5718 //*************************************************************************************************
5719 
5720 
5721 //*************************************************************************************************
5736 template< typename Type // Data type of the matrix
5737  , size_t M // Number of rows
5738  , size_t N > // Number of columns
5740  HybridMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const noexcept
5741 {
5742  using blaze::loada;
5743 
5745 
5746  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5747  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5748  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5749  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5750  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5751 
5752  return loada( &v_[i+j*MM] );
5753 }
5755 //*************************************************************************************************
5756 
5757 
5758 //*************************************************************************************************
5773 template< typename Type // Data type of the matrix
5774  , size_t M // Number of rows
5775  , size_t N > // Number of columns
5777  HybridMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const noexcept
5778 {
5779  using blaze::loadu;
5780 
5782 
5783  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5784  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5785  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5786 
5787  return loadu( &v_[i+j*MM] );
5788 }
5790 //*************************************************************************************************
5791 
5792 
5793 //*************************************************************************************************
5809 template< typename Type // Data type of the matrix
5810  , size_t M // Number of rows
5811  , size_t N > // Number of columns
5813  HybridMatrix<Type,M,N,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5814 {
5815  if( usePadding )
5816  storea( i, j, value );
5817  else
5818  storeu( i, j, value );
5819 }
5821 //*************************************************************************************************
5822 
5823 
5824 //*************************************************************************************************
5840 template< typename Type // Data type of the matrix
5841  , size_t M // Number of rows
5842  , size_t N > // Number of columns
5844  HybridMatrix<Type,M,N,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5845 {
5846  using blaze::storea;
5847 
5849 
5850  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5851  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5852  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5853  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5854  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5855 
5856  storea( &v_[i+j*MM], value );
5857 }
5859 //*************************************************************************************************
5860 
5861 
5862 //*************************************************************************************************
5878 template< typename Type // Data type of the matrix
5879  , size_t M // Number of rows
5880  , size_t N > // Number of columns
5882  HybridMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5883 {
5884  using blaze::storeu;
5885 
5887 
5888  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5889  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5890  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5891 
5892  storeu( &v_[i+j*MM], value );
5893 }
5895 //*************************************************************************************************
5896 
5897 
5898 //*************************************************************************************************
5915 template< typename Type // Data type of the matrix
5916  , size_t M // Number of rows
5917  , size_t N > // Number of columns
5919  HybridMatrix<Type,M,N,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5920 {
5921  using blaze::stream;
5922 
5924 
5925  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5926  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5927  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5928  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5929  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5930 
5931  stream( &v_[i+j*MM], value );
5932 }
5934 //*************************************************************************************************
5935 
5936 
5937 //*************************************************************************************************
5949 template< typename Type // Data type of the matrix
5950  , size_t M // Number of rows
5951  , size_t N > // Number of columns
5952 template< typename MT // Type of the right-hand side dense matrix
5953  , bool SO > // Storage order of the right-hand side dense matrix
5956 {
5957  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5958 
5959  for( size_t j=0UL; j<n_; ++j ) {
5960  for( size_t i=0UL; i<m_; ++i ) {
5961  v_[i+j*MM] = (~rhs)(i,j);
5962  }
5963  }
5964 }
5966 //*************************************************************************************************
5967 
5968 
5969 //*************************************************************************************************
5981 template< typename Type // Data type of the matrix
5982  , size_t M // Number of rows
5983  , size_t N > // Number of columns
5984 template< typename MT // Type of the right-hand side dense matrix
5985  , bool SO > // Storage order of the right-hand side dense matrix
5988 {
5990 
5991  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5992 
5993  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
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  for( size_t j=0UL; j<n_; ++j )
5999  {
6000  size_t i( 0UL );
6001 
6002  for( ; i<ipos; i+=SIMDSIZE ) {
6003  store( i, j, (~rhs).load(i,j) );
6004  }
6005  for( ; remainder && i<m_; ++i ) {
6006  v_[i+j*MM] = (~rhs)(i,j);
6007  }
6008  }
6009 }
6011 //*************************************************************************************************
6012 
6013 
6014 //*************************************************************************************************
6026 template< typename Type // Data type of the matrix
6027  , size_t M // Number of rows
6028  , size_t N > // Number of columns
6029 template< typename MT > // Type of the right-hand side sparse matrix
6031 {
6032  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6033 
6034  for( size_t j=0UL; j<n_; ++j )
6035  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6036  v_[element->index()+j*MM] = element->value();
6037 }
6039 //*************************************************************************************************
6040 
6041 
6042 //*************************************************************************************************
6054 template< typename Type // Data type of the matrix
6055  , size_t M // Number of rows
6056  , size_t N > // Number of columns
6057 template< typename MT > // Type of the right-hand side sparse matrix
6059 {
6061 
6062  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6063 
6064  for( size_t i=0UL; i<m_; ++i )
6065  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6066  v_[i+element->index()*MM] = element->value();
6067 }
6069 //*************************************************************************************************
6070 
6071 
6072 //*************************************************************************************************
6084 template< typename Type // Data type of the matrix
6085  , size_t M // Number of rows
6086  , size_t N > // Number of columns
6087 template< typename MT // Type of the right-hand side dense matrix
6088  , bool SO > // Storage order of the right-hand side dense matrix
6091 {
6092  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6093 
6094  for( size_t j=0UL; j<n_; ++j )
6095  {
6096  if( IsDiagonal<MT>::value )
6097  {
6098  v_[j+j*MM] += (~rhs)(j,j);
6099  }
6100  else
6101  {
6102  const size_t ibegin( ( IsLower<MT>::value )
6103  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
6104  :( 0UL ) );
6105  const size_t iend ( ( IsUpper<MT>::value )
6106  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6107  :( m_ ) );
6108  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6109 
6110  for( size_t i=ibegin; i<iend; ++i ) {
6111  v_[i+j*MM] += (~rhs)(i,j);
6112  }
6113  }
6114  }
6115 }
6117 //*************************************************************************************************
6118 
6119 
6120 //*************************************************************************************************
6132 template< typename Type // Data type of the matrix
6133  , size_t M // Number of rows
6134  , size_t N > // Number of columns
6135 template< typename MT // Type of the right-hand side dense matrix
6136  , bool SO > // Storage order of the right-hand side dense matrix
6139 {
6142 
6143  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6144 
6145  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
6146 
6147  for( size_t j=0UL; j<n_; ++j )
6148  {
6149  const size_t ibegin( ( IsLower<MT>::value )
6150  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
6151  :( 0UL ) );
6152  const size_t iend ( ( IsUpper<MT>::value )
6153  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6154  :( m_ ) );
6155  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6156 
6157  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
6158  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6159 
6160  size_t i( ibegin );
6161 
6162  for( ; i<ipos; i+=SIMDSIZE ) {
6163  store( i, j, load(i,j) + (~rhs).load(i,j) );
6164  }
6165  for( ; remainder && i<iend; ++i ) {
6166  v_[i+j*MM] += (~rhs)(i,j);
6167  }
6168  }
6169 }
6171 //*************************************************************************************************
6172 
6173 
6174 //*************************************************************************************************
6186 template< typename Type // Data type of the matrix
6187  , size_t M // Number of rows
6188  , size_t N > // Number of columns
6189 template< typename MT > // Type of the right-hand side sparse matrix
6191 {
6192  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6193 
6194  for( size_t j=0UL; j<n_; ++j )
6195  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6196  v_[element->index()+j*MM] += element->value();
6197 }
6199 //*************************************************************************************************
6200 
6201 
6202 //*************************************************************************************************
6214 template< typename Type // Data type of the matrix
6215  , size_t M // Number of rows
6216  , size_t N > // Number of columns
6217 template< typename MT > // Type of the right-hand side sparse matrix
6219 {
6221 
6222  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6223 
6224  for( size_t i=0UL; i<m_; ++i )
6225  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6226  v_[i+element->index()*MM] += element->value();
6227 }
6229 //*************************************************************************************************
6230 
6231 
6232 //*************************************************************************************************
6244 template< typename Type // Data type of the matrix
6245  , size_t M // Number of rows
6246  , size_t N > // Number of columns
6247 template< typename MT // Type of the right-hand side dense matrix
6248  , bool SO > // Storage order of the right-hand side dense matrix
6251 {
6252  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6253 
6254  for( size_t j=0UL; j<n_; ++j )
6255  {
6256  if( IsDiagonal<MT>::value )
6257  {
6258  v_[j+j*MM] -= (~rhs)(j,j);
6259  }
6260  else
6261  {
6262  const size_t ibegin( ( IsLower<MT>::value )
6263  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
6264  :( 0UL ) );
6265  const size_t iend ( ( IsUpper<MT>::value )
6266  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6267  :( m_ ) );
6268  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6269 
6270  for( size_t i=ibegin; i<iend; ++i ) {
6271  v_[i+j*MM] -= (~rhs)(i,j);
6272  }
6273  }
6274  }
6275 }
6277 //*************************************************************************************************
6278 
6279 
6280 //*************************************************************************************************
6292 template< typename Type // Data type of the matrix
6293  , size_t M // Number of rows
6294  , size_t N > // Number of columns
6295 template< typename MT // Type of the right-hand side dense matrix
6296  , bool SO > // Storage order of the right-hand side dense matrix
6299 {
6302 
6303  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6304 
6305  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
6306 
6307  for( size_t j=0UL; j<n_; ++j )
6308  {
6309  const size_t ibegin( ( IsLower<MT>::value )
6310  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
6311  :( 0UL ) );
6312  const size_t iend ( ( IsUpper<MT>::value )
6313  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6314  :( m_ ) );
6315  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6316 
6317  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
6318  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6319 
6320  size_t i( ibegin );
6321 
6322  for( ; i<ipos; i+=SIMDSIZE ) {
6323  store( i, j, load(i,j) - (~rhs).load(i,j) );
6324  }
6325  for( ; remainder && i<iend; ++i ) {
6326  v_[i+j*MM] -= (~rhs)(i,j);
6327  }
6328  }
6329 }
6331 //*************************************************************************************************
6332 
6333 
6334 //*************************************************************************************************
6346 template< typename Type // Data type of the matrix
6347  , size_t M // Number of rows
6348  , size_t N > // Number of columns
6349 template< typename MT > // Type of the right-hand side sparse matrix
6351 {
6352  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6353 
6354  for( size_t j=0UL; j<n_; ++j )
6355  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6356  v_[element->index()+j*MM] -= element->value();
6357 }
6359 //*************************************************************************************************
6360 
6361 
6362 //*************************************************************************************************
6374 template< typename Type // Data type of the matrix
6375  , size_t M // Number of rows
6376  , size_t N > // Number of columns
6377 template< typename MT > // Type of the right-hand side sparse matrix
6379 {
6381 
6382  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6383 
6384  for( size_t i=0UL; i<m_; ++i )
6385  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6386  v_[i+element->index()*MM] -= element->value();
6387 }
6389 //*************************************************************************************************
6390 
6391 
6392 //*************************************************************************************************
6404 template< typename Type // Data type of the matrix
6405  , size_t M // Number of rows
6406  , size_t N > // Number of columns
6407 template< typename MT // Type of the right-hand side dense matrix
6408  , bool SO > // Storage order of the right-hand side dense matrix
6409 inline DisableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
6411 {
6412  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6413 
6414  for( size_t j=0UL; j<n_; ++j ) {
6415  for( size_t i=0UL; i<m_; ++i ) {
6416  v_[i+j*MM] *= (~rhs)(i,j);
6417  }
6418  }
6419 }
6421 //*************************************************************************************************
6422 
6423 
6424 //*************************************************************************************************
6436 template< typename Type // Data type of the matrix
6437  , size_t M // Number of rows
6438  , size_t N > // Number of columns
6439 template< typename MT // Type of the right-hand side dense matrix
6440  , bool SO > // Storage order of the right-hand side dense matrix
6441 inline EnableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
6443 {
6445 
6446  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6447 
6448  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
6449 
6450  for( size_t j=0UL; j<n_; ++j )
6451  {
6452  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
6453  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6454 
6455  size_t i( 0UL );
6456 
6457  for( ; i<ipos; i+=SIMDSIZE ) {
6458  store( i, j, load(i,j) * (~rhs).load(i,j) );
6459  }
6460  for( ; remainder && i<m_; ++i ) {
6461  v_[i+j*MM] *= (~rhs)(i,j);
6462  }
6463  }
6464 }
6466 //*************************************************************************************************
6467 
6468 
6469 //*************************************************************************************************
6481 template< typename Type // Data type of the matrix
6482  , size_t M // Number of rows
6483  , size_t N > // Number of columns
6484 template< typename MT > // Type of the right-hand side sparse matrix
6486 {
6487  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6488 
6489  const HybridMatrix tmp( serial( *this ) );
6490 
6491  reset();
6492 
6493  for( size_t j=0UL; j<n_; ++j )
6494  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6495  v_[element->index()+j*MM] = tmp.v_[element->index()+j*MM] * element->value();
6496 }
6498 //*************************************************************************************************
6499 
6500 
6501 //*************************************************************************************************
6513 template< typename Type // Data type of the matrix
6514  , size_t M // Number of rows
6515  , size_t N > // Number of columns
6516 template< typename MT > // Type of the right-hand side sparse matrix
6518 {
6520 
6521  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6522 
6523  const HybridMatrix tmp( serial( *this ) );
6524 
6525  reset();
6526 
6527  for( size_t i=0UL; i<m_; ++i )
6528  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6529  v_[i+element->index()*MM] = tmp.v_[i+element->index()*MM] * element->value();
6530 }
6532 //*************************************************************************************************
6533 
6534 
6535 
6536 
6537 
6538 
6539 
6540 
6541 //=================================================================================================
6542 //
6543 // STATICMATRIX OPERATORS
6544 //
6545 //=================================================================================================
6546 
6547 //*************************************************************************************************
6550 template< typename Type, size_t M, size_t N, bool SO >
6551 inline void reset( HybridMatrix<Type,M,N,SO>& m );
6552 
6553 template< typename Type, size_t M, size_t N, bool SO >
6554 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i );
6555 
6556 template< typename Type, size_t M, size_t N, bool SO >
6557 inline void clear( HybridMatrix<Type,M,N,SO>& m );
6558 
6559 template< bool RF, typename Type, size_t M, size_t N, bool SO >
6560 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m );
6561 
6562 template< typename Type, size_t M, size_t N, bool SO >
6563 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m ) noexcept;
6564 
6565 template< typename Type, size_t M, size_t N, bool SO >
6566 inline void swap( HybridMatrix<Type,M,N,SO>& a, HybridMatrix<Type,M,N,SO>& b ) noexcept;
6568 //*************************************************************************************************
6569 
6570 
6571 //*************************************************************************************************
6578 template< typename Type // Data type of the matrix
6579  , size_t M // Number of rows
6580  , size_t N // Number of columns
6581  , bool SO > // Storage order
6583 {
6584  m.reset();
6585 }
6586 //*************************************************************************************************
6587 
6588 
6589 //*************************************************************************************************
6602 template< typename Type // Data type of the matrix
6603  , size_t M // Number of rows
6604  , size_t N // Number of columns
6605  , bool SO > // Storage order
6606 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i )
6607 {
6608  m.reset( i );
6609 }
6610 //*************************************************************************************************
6611 
6612 
6613 //*************************************************************************************************
6620 template< typename Type // Data type of the matrix
6621  , size_t M // Number of rows
6622  , size_t N // Number of columns
6623  , bool SO > // Storage order
6625 {
6626  m.clear();
6627 }
6628 //*************************************************************************************************
6629 
6630 
6631 //*************************************************************************************************
6656 template< bool RF // Relaxation flag
6657  , typename Type // Data type of the matrix
6658  , size_t M // Number of rows
6659  , size_t N // Number of columns
6660  , bool SO > // Storage order
6661 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m )
6662 {
6663  return ( m.rows() == 0UL && m.columns() == 0UL );
6664 }
6665 //*************************************************************************************************
6666 
6667 
6668 //*************************************************************************************************
6686 template< typename Type // Data type of the matrix
6687  , size_t M // Number of rows
6688  , size_t N // Number of columns
6689  , bool SO > // Storage order
6690 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m ) noexcept
6691 {
6692  return m.isIntact();
6693 }
6694 //*************************************************************************************************
6695 
6696 
6697 //*************************************************************************************************
6705 template< typename Type // Data type of the matrix
6706  , size_t M // Number of rows
6707  , size_t N // Number of columns
6708  , bool SO > // Storage order
6710 {
6711  a.swap( b );
6712 }
6713 //*************************************************************************************************
6714 
6715 
6716 
6717 
6718 //=================================================================================================
6719 //
6720 // HASCONSTDATAACCESS SPECIALIZATIONS
6721 //
6722 //=================================================================================================
6723 
6724 //*************************************************************************************************
6726 template< typename T, size_t M, size_t N, bool SO >
6727 struct HasConstDataAccess< HybridMatrix<T,M,N,SO> >
6728  : public TrueType
6729 {};
6731 //*************************************************************************************************
6732 
6733 
6734 
6735 
6736 //=================================================================================================
6737 //
6738 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6739 //
6740 //=================================================================================================
6741 
6742 //*************************************************************************************************
6744 template< typename T, size_t M, size_t N, bool SO >
6745 struct HasMutableDataAccess< HybridMatrix<T,M,N,SO> >
6746  : public TrueType
6747 {};
6749 //*************************************************************************************************
6750 
6751 
6752 
6753 
6754 //=================================================================================================
6755 //
6756 // ISALIGNED SPECIALIZATIONS
6757 //
6758 //=================================================================================================
6759 
6760 //*************************************************************************************************
6762 template< typename T, size_t M, size_t N, bool SO >
6763 struct IsAligned< HybridMatrix<T,M,N,SO> >
6764  : public BoolConstant<usePadding>
6765 {};
6767 //*************************************************************************************************
6768 
6769 
6770 
6771 
6772 //=================================================================================================
6773 //
6774 // ISPADDED SPECIALIZATIONS
6775 //
6776 //=================================================================================================
6777 
6778 //*************************************************************************************************
6780 template< typename T, size_t M, size_t N, bool SO >
6781 struct IsPadded< HybridMatrix<T,M,N,SO> >
6782  : public BoolConstant<usePadding>
6783 {};
6785 //*************************************************************************************************
6786 
6787 
6788 
6789 
6790 //=================================================================================================
6791 //
6792 // ISRESIZABLE SPECIALIZATIONS
6793 //
6794 //=================================================================================================
6795 
6796 //*************************************************************************************************
6798 template< typename T, size_t M, size_t N, bool SO >
6799 struct IsResizable< HybridMatrix<T,M,N,SO> >
6800  : public TrueType
6801 {};
6803 //*************************************************************************************************
6804 
6805 
6806 
6807 
6808 //=================================================================================================
6809 //
6810 // ADDTRAIT SPECIALIZATIONS
6811 //
6812 //=================================================================================================
6813 
6814 //*************************************************************************************************
6816 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6817 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6818 {
6819  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, SO >;
6820 };
6821 
6822 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6823 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6824 {
6825  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, false >;
6826 };
6827 
6828 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6829 struct AddTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6830 {
6831  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, SO >;
6832 };
6833 
6834 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6835 struct AddTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6836 {
6837  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, false >;
6838 };
6839 
6840 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6841 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6842 {
6843  using Type = HybridMatrix< AddTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6844 };
6845 
6846 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6847 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6848 {
6849  using Type = HybridMatrix< AddTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6850 };
6852 //*************************************************************************************************
6853 
6854 
6855 
6856 
6857 //=================================================================================================
6858 //
6859 // SUBTRAIT SPECIALIZATIONS
6860 //
6861 //=================================================================================================
6862 
6863 //*************************************************************************************************
6865 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6866 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6867 {
6868  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, SO >;
6869 };
6870 
6871 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6872 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6873 {
6874  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, false >;
6875 };
6876 
6877 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6878 struct SubTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6879 {
6880  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, SO >;
6881 };
6882 
6883 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6884 struct SubTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6885 {
6886  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, false >;
6887 };
6888 
6889 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6890 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6891 {
6892  using Type = HybridMatrix< SubTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6893 };
6894 
6895 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6896 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6897 {
6898  using Type = HybridMatrix< SubTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6899 };
6901 //*************************************************************************************************
6902 
6903 
6904 
6905 
6906 //=================================================================================================
6907 //
6908 // SCHURTRAIT SPECIALIZATIONS
6909 //
6910 //=================================================================================================
6911 
6912 //*************************************************************************************************
6914 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6915 struct SchurTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6916 {
6917  using Type = StaticMatrix< MultTrait_<T1,T2>, M2, N2, SO >;
6918 };
6919 
6920 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6921 struct SchurTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6922 {
6923  using Type = StaticMatrix< MultTrait_<T1,T2>, M2, N2, false >;
6924 };
6925 
6926 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6927 struct SchurTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6928 {
6929  using Type = StaticMatrix< MultTrait_<T1,T2>, M2, N2, SO >;
6930 };
6931 
6932 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6933 struct SchurTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6934 {
6935  using Type = StaticMatrix< MultTrait_<T1,T2>, M2, N2, false >;
6936 };
6937 
6938 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6939 struct SchurTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6940 {
6941  using Type = HybridMatrix< MultTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6942 };
6943 
6944 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6945 struct SchurTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6946 {
6947  using Type = HybridMatrix< MultTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6948 };
6950 //*************************************************************************************************
6951 
6952 
6953 
6954 
6955 //=================================================================================================
6956 //
6957 // MULTTRAIT SPECIALIZATIONS
6958 //
6959 //=================================================================================================
6960 
6961 //*************************************************************************************************
6963 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6964 struct MultTrait< HybridMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6965 {
6966  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6967 };
6968 
6969 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6970 struct MultTrait< T1, HybridMatrix<T2,M,N,SO>, EnableIf_<IsNumeric<T1> > >
6971 {
6972  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6973 };
6974 
6975 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6976 struct MultTrait< HybridMatrix<T1,M,N,SO>, StaticVector<T2,K,false> >
6977 {
6978  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6979 };
6980 
6981 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6982 struct MultTrait< StaticVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6983 {
6984  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6985 };
6986 
6987 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6988 struct MultTrait< HybridMatrix<T1,M,N,SO>, HybridVector<T2,K,false> >
6989 {
6990  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6991 };
6992 
6993 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6994 struct MultTrait< HybridVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6995 {
6996  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6997 };
6998 
6999 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
7000 struct MultTrait< HybridMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
7001 {
7002  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
7003 };
7004 
7005 template< typename T1, typename T2, size_t M, size_t N, bool SO >
7006 struct MultTrait< DynamicVector<T1,true>, HybridMatrix<T2,M,N,SO> >
7007 {
7008  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
7009 };
7010 
7011 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
7012 struct MultTrait< HybridMatrix<T1,M,N,SO>, CustomVector<T2,AF,PF,false> >
7013 {
7014  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
7015 };
7016 
7017 template< typename T1, bool AF, bool PF, typename T2, size_t M, size_t N, bool SO >
7018 struct MultTrait< CustomVector<T1,AF,PF,true>, HybridMatrix<T2,M,N,SO> >
7019 {
7020  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
7021 };
7022 
7023 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
7024 struct MultTrait< HybridMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
7025 {
7026  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
7027 };
7028 
7029 template< typename T1, typename T2, size_t M, size_t N, bool SO >
7030 struct MultTrait< CompressedVector<T1,true>, HybridMatrix<T2,M,N,SO> >
7031 {
7032  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
7033 };
7034 
7035 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
7036 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
7037 {
7038  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
7039 };
7040 
7041 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
7042 struct MultTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
7043 {
7044  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
7045 };
7046 
7047 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
7048 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
7049 {
7050  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
7051 };
7053 //*************************************************************************************************
7054 
7055 
7056 
7057 
7058 //=================================================================================================
7059 //
7060 // DIVTRAIT SPECIALIZATIONS
7061 //
7062 //=================================================================================================
7063 
7064 //*************************************************************************************************
7066 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
7067 struct DivTrait< HybridMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
7068 {
7069  using Type = HybridMatrix< DivTrait_<T1,T2>, M, N, SO >;
7070 };
7072 //*************************************************************************************************
7073 
7074 
7075 
7076 
7077 //=================================================================================================
7078 //
7079 // UNARYMAPTRAIT SPECIALIZATIONS
7080 //
7081 //=================================================================================================
7082 
7083 //*************************************************************************************************
7085 template< typename T, size_t M, size_t N, bool SO, typename OP >
7086 struct UnaryMapTrait< HybridMatrix<T,M,N,SO>, OP >
7087 {
7088  using Type = HybridMatrix< UnaryMapTrait_<T,OP>, M, N, SO >;
7089 };
7091 //*************************************************************************************************
7092 
7093 
7094 
7095 
7096 //=================================================================================================
7097 //
7098 // BINARYMAPTRAIT SPECIALIZATIONS
7099 //
7100 //=================================================================================================
7101 
7102 //*************************************************************************************************
7104 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2, typename OP >
7105 struct BinaryMapTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO>, OP >
7106 {
7107  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M2, N2, SO >;
7108 };
7109 
7110 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2, typename OP >
7111 struct BinaryMapTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2>, OP >
7112 {
7113  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M2, N2, false >;
7114 };
7115 
7116 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2, typename OP >
7117 struct BinaryMapTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO>, OP >
7118 {
7119  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M2, N2, SO >;
7120 };
7121 
7122 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2, typename OP >
7123 struct BinaryMapTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2>, OP >
7124 {
7125  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M2, N2, false >;
7126 };
7127 
7128 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2, typename OP >
7129 struct BinaryMapTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO>, OP >
7130 {
7131  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
7132 };
7133 
7134 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2, typename OP >
7135 struct BinaryMapTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2>, OP >
7136 {
7137  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
7138 };
7140 //*************************************************************************************************
7141 
7142 
7143 
7144 
7145 //=================================================================================================
7146 //
7147 // HIGHTYPE SPECIALIZATIONS
7148 //
7149 //=================================================================================================
7150 
7151 //*************************************************************************************************
7153 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
7154 struct HighType< HybridMatrix<T1,M,N,SO>, HybridMatrix<T2,M,N,SO> >
7155 {
7156  using Type = HybridMatrix< typename HighType<T1,T2>::Type, M, N, SO >;
7157 };
7159 //*************************************************************************************************
7160 
7161 
7162 
7163 
7164 //=================================================================================================
7165 //
7166 // LOWTYPE SPECIALIZATIONS
7167 //
7168 //=================================================================================================
7169 
7170 //*************************************************************************************************
7172 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
7173 struct LowType< HybridMatrix<T1,M,N,SO>, HybridMatrix<T2,M,N,SO> >
7174 {
7175  using Type = HybridMatrix< typename LowType<T1,T2>::Type, M, N, SO >;
7176 };
7178 //*************************************************************************************************
7179 
7180 
7181 
7182 
7183 //=================================================================================================
7184 //
7185 // SUBMATRIXTRAIT SPECIALIZATIONS
7186 //
7187 //=================================================================================================
7188 
7189 //*************************************************************************************************
7191 template< typename T, size_t M, size_t N, bool SO >
7192 struct SubmatrixTrait< HybridMatrix<T,M,N,SO> >
7193 {
7194  using Type = HybridMatrix<T,M,N,SO>;
7195 };
7197 //*************************************************************************************************
7198 
7199 
7200 
7201 
7202 //=================================================================================================
7203 //
7204 // ROWTRAIT SPECIALIZATIONS
7205 //
7206 //=================================================================================================
7207 
7208 //*************************************************************************************************
7210 template< typename T, size_t M, size_t N, bool SO >
7211 struct RowTrait< HybridMatrix<T,M,N,SO> >
7212 {
7213  using Type = HybridVector<T,N,true>;
7214 };
7216 //*************************************************************************************************
7217 
7218 
7219 
7220 
7221 //=================================================================================================
7222 //
7223 // COLUMNTRAIT SPECIALIZATIONS
7224 //
7225 //=================================================================================================
7226 
7227 //*************************************************************************************************
7229 template< typename T, size_t M, size_t N, bool SO >
7230 struct ColumnTrait< HybridMatrix<T,M,N,SO> >
7231 {
7232  using Type = HybridVector<T,M,false>;
7233 };
7235 //*************************************************************************************************
7236 
7237 } // namespace blaze
7238 
7239 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:135
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:79
Availability of a SIMD subtraction for the given data types.Depending on the available instruction se...
Definition: HasSIMDSub.h:171
Header file for mathematical functions.
Header file for the Schur product trait.
Compile time check for low-level access to constant data.This type trait tests whether the given data...
Definition: HasConstDataAccess.h:75
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the alignment flag values.
Header file for the UNUSED_PARAMETER function template.
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1293
Header file for the subtraction trait.
Header file for basic type definitions.
Header file for the row trait.
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:128
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:127
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
Header file for the IsSparseMatrix type trait.
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: HybridMatrix.h:237
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1411
Header file for the IsSame and IsStrictlySame type traits.
Base template for the SchurTrait class.
Definition: SchurTrait.h:124
Availability of a SIMD multiplication for the given data types.Depending on the available instruction...
Definition: HasSIMDMult.h:172
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:316
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1173
Header file for the IsColumnMajorMatrix type trait.
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: HybridMatrix.h:1025
constexpr size_t spacing() const noexcept
Returns the spacing between the beginning of two rows.
Definition: HybridMatrix.h:1777
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:171
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1245
#define BLAZE_CONSTRAINT_MUST_NOT_BE_VOLATILE(T)
Constraint on the data type.In case the given data type is a volatile-qualified type, a compilation error is created.
Definition: Volatile.h:79
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member constant is set to true, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to false, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:140
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: HybridMatrix.h:1742
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
Header file for memory allocation and deallocation functionality.
System settings for performance optimizations.
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1221
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1393
Compile time check for data types.This type trait tests whether or not the given types can be combine...
Definition: IsSIMDCombinable.h:120
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:343
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1809
Type ElementType
Type of the matrix elements.
Definition: HybridMatrix.h:227
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:78
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
Constraint on the data type.
Header file for the std::initializer_list aliases.
Header file for the SparseMatrix base class.
Efficient implementation of a dynamically sized vector with static memory.The HybridVector class temp...
Definition: Forward.h:59
Compile time check for low-level access to mutable data.This type trait tests whether the given data ...
Definition: HasMutableDataAccess.h:75
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: HybridMatrix.h:2509
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: HybridMatrix.h:1984
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: HybridMatrix.h:1835
Base template for the RowTrait class.
Definition: RowTrait.h:127
Headerfile for the generic max algorithm.
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:112
Header file for the DisableIf class template.
Header file for the LowType type trait.
Base template for the HighType type trait.
Definition: HighType.h:133
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the unary map trait.
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:112
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5924
HybridMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: HybridMatrix.h:1319
Compile time assertion.
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: HybridMatrix.h:2708
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:110
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const SIMDType &value) noexcept
Store of a SIMD element of the matrix.
Definition: HybridMatrix.h:2639
Header file for all forward declarations of the math module.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:76
#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: HybridMatrix.h:234
Header file for the HasSIMDAdd type trait.
Efficient implementation of a fixed-sized matrix.The StaticMatrix class template is the representatio...
Definition: Forward.h:60
Header file for the DenseMatrix base class.
Header file for the DenseIterator class template.
Header file for all SIMD functionality.
HybridMatrix()
The default constructor for HybridMatrix.
Definition: HybridMatrix.h:567
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_DIAGONAL_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a diagonal matrix type, a compilation error is created.
Definition: Diagonal.h:79
Reference operator()(size_t i, size_t j) noexcept
2D-access to the matrix elements.
Definition: HybridMatrix.h:976
Header file for the IsLower type trait.
size_t m_
The current number of rows of the matrix.
Definition: HybridMatrix.h:531
Header file for the IsAligned type trait.
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
Type & Reference
Reference to a non-constant matrix value.
Definition: HybridMatrix.h:232
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: HybridMatrix.h:235
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Header file for the default storage order for all vectors of the Blaze library.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
void reset()
Reset to the default initial values.
Definition: HybridMatrix.h:1889
Header file for the exception macros of the math module.
HybridMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: HybridMatrix.h:2148
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Resize mechanism to obtain a HybridMatrix with different fixed dimensions.
Definition: HybridMatrix.h:255
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:580
Header file for the IsPadded type trait.
Header file for the IsVectorizable 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: HybridMatrix.h:2745
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
Base template for the LowType type trait.
Definition: LowType.h:133
Header file for the HasConstDataAccess type trait.
Compile time check for resizable data types.This type trait tests whether the given data type is a re...
Definition: IsResizable.h:75
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
void swap(HybridMatrix &m) noexcept
Swapping the contents of two hybrid matrices.
Definition: HybridMatrix.h:2051
Header file for the IsSIMDCombinable type trait.
AlignedArray< Type, M *NN > v_
The statically allocated matrix elements.
Definition: HybridMatrix.h:521
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: HybridMatrix.h:2670
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
Header file for the HasSIMDMult type trait.
Header file for the binary map trait.
BLAZE_ALWAYS_INLINE constexpr auto nextMultiple(T1 value, T2 factor) noexcept
Rounds up an integral value to the next multiple of a given factor.
Definition: Functions.h:156
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: HybridMatrix.h:1084
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determine the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:80
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:139
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:110
HybridMatrix & transpose()
In-place transpose of the matrix.
Definition: HybridMatrix.h:2093
Base template for the MultTrait class.
Definition: MultTrait.h:139
const Type & ConstReference
Reference to a constant matrix value.
Definition: HybridMatrix.h:233
Header file for the addition trait.
BLAZE_ALWAYS_INLINE SIMDType loadu(size_t i, size_t j) const noexcept
Unaligned load of a SIMD element of the matrix.
Definition: HybridMatrix.h:2603
Header file for the division trait.
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
Constraint on the data type.
Constraint on the data type.
Header file for the AlignedArray implementation.
SIMD characteristics of data types.The SIMDTrait class template provides the SIMD characteristics of ...
Definition: SIMDTrait.h:296
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: HybridMatrix.h:2467
Efficient implementation of a dynamically sized matrix with static memory.The HybridMatrix class temp...
Definition: Forward.h:58
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the column trait.
Header file for the isDefault shim.
Header file for the TransExprTrait class template.
Constraint on the data type.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:101
HybridMatrix< Type, M, N, SO > This
Type of this HybridMatrix instance.
Definition: HybridMatrix.h:222
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric< T >::value)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
Header file for the HasMutableDataAccess type trait.
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:230
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: HybridMatrix.h:2536
Base template for the DivTrait class.
Definition: DivTrait.h:139
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric< T >::value)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
Rebind mechanism to obtain a HybridMatrix with different data/element type.
Definition: HybridMatrix.h:245
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
DenseIterator< const Type, usePadding > ConstIterator
Iterator over constant elements.
Definition: HybridMatrix.h:238
Header file for the IsRowMajorMatrix type trait.
Initializer list type of the Blaze library.
Header file for the alignment check function.
typename InvExprTrait< T >::Type InvExprTrait_
Auxiliary alias declaration for the InvExprTrait class template.The InvExprTrait_ alias declaration p...
Definition: InvExprTrait.h:123
BLAZE_ALWAYS_INLINE SIMDType loada(size_t i, size_t j) const noexcept
Aligned load of a SIMD element of the matrix.
Definition: HybridMatrix.h:2566
size_t n_
The current number of columns of the matrix.
Definition: HybridMatrix.h:532
Header file for the IntegralConstant class template.
const Type & ReturnType
Return type for expression template evaluations.
Definition: HybridMatrix.h:229
Compile time evaluation of the number of rows of a matrix.The Rows type trait evaluates the number of...
Definition: Rows.h:75
void clear()
Clearing the hybrid matrix.
Definition: HybridMatrix.h:1937
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
Base template for the SubTrait class.
Definition: SubTrait.h:139
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the CTransExprTrait class template.
void extend(size_t m, size_t n, bool preserve=true)
Extending the size of the matrix.
Definition: HybridMatrix.h:2033
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:112
Base template for the BinaryMapTrait class.
Definition: BinaryMapTrait.h:119
Header file for the IsResizable type trait.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: HybridMatrix.h:1758
Base template for the UnaryMapTrait class.
Definition: UnaryMapTrait.h:117
System settings for the inline keywords.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
constexpr size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: HybridMatrix.h:1793
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: HybridMatrix.h:228
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: HybridMatrix.h:2489
bool isIntact() const noexcept
Returns whether the invariants of the hybrid matrix are intact.
Definition: HybridMatrix.h:2417
Header file for the HighType type trait.
Header file for the TrueType type/value trait base class.