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>
96 #include <blaze/system/Inline.h>
102 #include <blaze/util/AlignedArray.h>
104 #include <blaze/util/Assert.h>
111 #include <blaze/util/DisableIf.h>
112 #include <blaze/util/EnableIf.h>
114 #include <blaze/util/Memory.h>
115 #include <blaze/util/StaticAssert.h>
116 #include <blaze/util/Template.h>
117 #include <blaze/util/TrueType.h>
118 #include <blaze/util/Types.h>
122 #include <blaze/util/Unused.h>
123 
124 
125 namespace blaze {
126 
127 //=================================================================================================
128 //
129 // CLASS DEFINITION
130 //
131 //=================================================================================================
132 
133 //*************************************************************************************************
219 template< typename Type // Data type of the matrix
220  , size_t M // Number of rows
221  , size_t N // Number of columns
222  , bool SO = defaultStorageOrder > // Storage order
223 class HybridMatrix
224  : public DenseMatrix< HybridMatrix<Type,M,N,SO>, SO >
225 {
226  public:
227  //**Type definitions****************************************************************************
230  using ResultType = This;
233  using ElementType = Type;
235  using ReturnType = const Type&;
236  using CompositeType = const This&;
237 
238  using Reference = Type&;
239  using ConstReference = const Type&;
240  using Pointer = Type*;
241  using ConstPointer = const Type*;
242 
245  //**********************************************************************************************
246 
247  //**Rebind struct definition********************************************************************
250  template< typename NewType > // Data type of the other matrix
251  struct Rebind {
253  };
254  //**********************************************************************************************
255 
256  //**Resize struct definition********************************************************************
259  template< size_t NewM // Number of rows of the other matrix
260  , size_t NewN > // Number of columns of the other matrix
261  struct Resize {
263  };
264  //**********************************************************************************************
265 
266  //**Compilation flags***************************************************************************
268 
272  enum : bool { simdEnabled = IsVectorizable<Type>::value };
273 
275 
278  enum : bool { smpAssignable = false };
279  //**********************************************************************************************
280 
281  //**Constructors********************************************************************************
284  explicit inline HybridMatrix();
285  explicit inline HybridMatrix( size_t m, size_t n );
286  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
287  explicit inline HybridMatrix( initializer_list< initializer_list<Type> > list );
288 
289  template< typename Other >
290  explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
291 
292  template< typename Other, size_t Rows, size_t Cols >
293  explicit inline HybridMatrix( const Other (&array)[Rows][Cols] );
294 
295  inline HybridMatrix( const HybridMatrix& m );
296  template< typename MT, bool SO2 > inline HybridMatrix( const Matrix<MT,SO2>& m );
298  //**********************************************************************************************
299 
300  //**Destructor**********************************************************************************
301  // No explicitly declared destructor.
302  //**********************************************************************************************
303 
304  //**Data access functions***********************************************************************
307  inline Reference operator()( size_t i, size_t j ) noexcept;
308  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
309  inline Reference at( size_t i, size_t j );
310  inline ConstReference at( size_t i, size_t j ) const;
311  inline Pointer data () noexcept;
312  inline ConstPointer data () const noexcept;
313  inline Pointer data ( size_t i ) noexcept;
314  inline ConstPointer data ( size_t i ) const noexcept;
315  inline Iterator begin ( size_t i ) noexcept;
316  inline ConstIterator begin ( size_t i ) const noexcept;
317  inline ConstIterator cbegin( size_t i ) const noexcept;
318  inline Iterator end ( size_t i ) noexcept;
319  inline ConstIterator end ( size_t i ) const noexcept;
320  inline ConstIterator cend ( size_t i ) const noexcept;
322  //**********************************************************************************************
323 
324  //**Assignment operators************************************************************************
327  inline HybridMatrix& operator=( const Type& set );
328  inline HybridMatrix& operator=( initializer_list< initializer_list<Type> > list );
329 
330  template< typename Other, size_t Rows, size_t Cols >
331  inline HybridMatrix& operator=( const Other (&array)[Rows][Cols] );
332 
333  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
334  template< typename MT, bool SO2 > inline HybridMatrix& operator= ( const Matrix<MT,SO2>& rhs );
335  template< typename MT, bool SO2 > inline HybridMatrix& operator+=( const Matrix<MT,SO2>& rhs );
336  template< typename MT, bool SO2 > inline HybridMatrix& operator-=( const Matrix<MT,SO2>& rhs );
337  template< typename MT, bool SO2 > inline HybridMatrix& operator%=( const Matrix<MT,SO2>& rhs );
339  //**********************************************************************************************
340 
341  //**Utility functions***************************************************************************
344  inline size_t rows() const noexcept;
345  inline size_t columns() const noexcept;
346  inline constexpr size_t spacing() const noexcept;
347  inline constexpr size_t capacity() const noexcept;
348  inline size_t capacity( size_t i ) const noexcept;
349  inline size_t nonZeros() const;
350  inline size_t nonZeros( size_t i ) const;
351  inline void reset();
352  inline void reset( size_t i );
353  inline void clear();
354  void resize ( size_t m, size_t n, bool preserve=true );
355  inline void extend ( size_t m, size_t n, bool preserve=true );
356  inline void swap( HybridMatrix& m ) noexcept;
358  //**********************************************************************************************
359 
360  //**Numeric functions***************************************************************************
363  inline HybridMatrix& transpose();
364  inline HybridMatrix& ctranspose();
365 
366  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
368  //**********************************************************************************************
369 
370  //**Memory functions****************************************************************************
373  static inline void* operator new ( std::size_t size );
374  static inline void* operator new[]( std::size_t size );
375  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
376  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
377 
378  static inline void operator delete ( void* ptr );
379  static inline void operator delete[]( void* ptr );
380  static inline void operator delete ( void* ptr, const std::nothrow_t& );
381  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
383  //**********************************************************************************************
384 
385  private:
386  //**********************************************************************************************
388  template< typename MT >
390  struct VectorizedAssign {
391  enum : bool { value = useOptimizedKernels &&
392  simdEnabled && MT::simdEnabled &&
395  };
397  //**********************************************************************************************
398 
399  //**********************************************************************************************
401  template< typename MT >
403  struct VectorizedAddAssign {
404  enum : bool { value = useOptimizedKernels &&
405  simdEnabled && MT::simdEnabled &&
410  };
412  //**********************************************************************************************
413 
414  //**********************************************************************************************
416  template< typename MT >
418  struct VectorizedSubAssign {
419  enum : bool { value = useOptimizedKernels &&
420  simdEnabled && MT::simdEnabled &&
425  };
427  //**********************************************************************************************
428 
429  //**********************************************************************************************
431  template< typename MT >
433  struct VectorizedSchurAssign {
434  enum : bool { value = useOptimizedKernels &&
435  simdEnabled && MT::simdEnabled &&
439  };
441  //**********************************************************************************************
442 
443  //**********************************************************************************************
445  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
446  //**********************************************************************************************
447 
448  public:
449  //**Debugging functions*************************************************************************
452  inline bool isIntact() const noexcept;
454  //**********************************************************************************************
455 
456  //**Expression template evaluation functions****************************************************
459  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
460  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
461 
462  inline bool isAligned() const noexcept;
463 
464  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
465  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
466  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
467 
468  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
469  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
470  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
471  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
472 
473  template< typename MT, bool SO2 >
474  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
475 
476  template< typename MT, bool SO2 >
477  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
478 
479  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
480  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
481 
482  template< typename MT, bool SO2 >
483  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
484 
485  template< typename MT, bool SO2 >
486  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
487 
488  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
489  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
490 
491  template< typename MT, bool SO2 >
492  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
493 
494  template< typename MT, bool SO2 >
495  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
496 
497  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
498  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
499 
500  template< typename MT, bool SO2 >
501  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO2>& rhs );
502 
503  template< typename MT, bool SO2 >
504  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO2>& rhs );
505 
506  template< typename MT > inline void schurAssign( const SparseMatrix<MT,SO>& rhs );
507  template< typename MT > inline void schurAssign( const SparseMatrix<MT,!SO>& rhs );
509  //**********************************************************************************************
510 
511  private:
512  //**********************************************************************************************
514  enum : size_t { NN = ( usePadding )?( nextMultiple( N, SIMDSIZE ) ):( N ) };
515  //**********************************************************************************************
516 
517  //**Member variables****************************************************************************
521 
530  size_t m_;
531  size_t n_;
532 
533  //**********************************************************************************************
534 
535  //**Compile time checks*************************************************************************
541  BLAZE_STATIC_ASSERT( !usePadding || NN % SIMDSIZE == 0UL );
542  BLAZE_STATIC_ASSERT( NN >= N );
544  //**********************************************************************************************
545 };
546 //*************************************************************************************************
547 
548 
549 
550 
551 //=================================================================================================
552 //
553 // CONSTRUCTORS
554 //
555 //=================================================================================================
556 
557 //*************************************************************************************************
562 template< typename Type // Data type of the matrix
563  , size_t M // Number of rows
564  , size_t N // Number of columns
565  , bool SO > // Storage order
567  : v_() // The statically allocated matrix elements
568  , m_( 0UL ) // The current number of rows of the matrix
569  , n_( 0UL ) // The current number of columns of the matrix
570 {
572 
573  if( IsNumeric<Type>::value ) {
574  for( size_t i=0UL; i<M*NN; ++i )
575  v_[i] = Type();
576  }
577 
578  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
579 }
580 //*************************************************************************************************
581 
582 
583 //*************************************************************************************************
596 template< typename Type // Data type of the matrix
597  , size_t M // Number of rows
598  , size_t N // Number of columns
599  , bool SO > // Storage order
600 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n )
601  : v_() // The statically allocated matrix elements
602  , m_( m ) // The current number of rows of the matrix
603  , n_( n ) // The current number of columns of the matrix
604 {
606 
607  if( m > M ) {
608  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
609  }
610 
611  if( n > N ) {
612  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
613  }
614 
615  if( IsNumeric<Type>::value ) {
616  for( size_t i=0UL; i<M*NN; ++i )
617  v_[i] = Type();
618  }
619 
620  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
621 }
622 //*************************************************************************************************
623 
624 
625 //*************************************************************************************************
639 template< typename Type // Data type of the matrix
640  , size_t M // Number of rows
641  , size_t N // Number of columns
642  , bool SO > // Storage order
643 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Type& init )
644  : v_() // The statically allocated matrix elements
645  , m_( m ) // The current number of rows of the matrix
646  , n_( n ) // The current number of columns of the matrix
647 {
649 
650  if( m > M ) {
651  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
652  }
653 
654  if( n > N ) {
655  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
656  }
657 
658  for( size_t i=0UL; i<m; ++i ) {
659  for( size_t j=0UL; j<n; ++j )
660  v_[i*NN+j] = init;
661 
662  if( IsNumeric<Type>::value ) {
663  for( size_t j=n; j<NN; ++j )
664  v_[i*NN+j] = Type();
665  }
666  }
667 
668  if( IsNumeric<Type>::value ) {
669  for( size_t i=m; i<M; ++i )
670  for( size_t j=0UL; j<NN; ++j )
671  v_[i*NN+j] = Type();
672  }
673 
674  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
675 }
676 //*************************************************************************************************
677 
678 
679 //*************************************************************************************************
703 template< typename Type // Data type of the matrix
704  , size_t M // Number of rows
705  , size_t N // Number of columns
706  , bool SO > // Storage order
708  : v_() // The statically allocated matrix elements
709  , m_( list.size() ) // The current number of rows of the matrix
710  , n_( determineColumns( list ) ) // The current number of columns of the matrix
711 {
713 
714  if( m_ > M ) {
715  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
716  }
717 
718  if( n_ > N ) {
719  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
720  }
721 
722  size_t i( 0UL );
723 
724  for( const auto& rowList : list ) {
725  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
726  ++i;
727  }
728 
729  if( IsNumeric<Type>::value ) {
730  for( ; i<M; ++i )
731  for( size_t j=0UL; j<NN; ++j )
732  v_[i*NN+j] = Type();
733  }
734 
735  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
736 }
737 //*************************************************************************************************
738 
739 
740 //*************************************************************************************************
767 template< typename Type // Data type of the matrix
768  , size_t M // Number of rows
769  , size_t N // Number of columns
770  , bool SO > // Storage order
771 template< typename Other > // Data type of the initialization array
772 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Other* array )
773  : v_() // The statically allocated matrix elements
774  , m_( m ) // The current number of rows of the matrix
775  , n_( n ) // The current number of columns of the matrix
776 {
778 
779  if( m > M ) {
780  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
781  }
782 
783  if( n > N ) {
784  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
785  }
786 
787  for( size_t i=0UL; i<m; ++i ) {
788  for( size_t j=0UL; j<n; ++j )
789  v_[i*NN+j] = array[i*n+j];
790 
791  if( IsNumeric<Type>::value ) {
792  for( size_t j=n; j<NN; ++j )
793  v_[i*NN+j] = Type();
794  }
795  }
796 
797  if( IsNumeric<Type>::value ) {
798  for( size_t i=m; i<M; ++i )
799  for( size_t j=0UL; j<NN; ++j )
800  v_[i*NN+j] = Type();
801  }
802 
803  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
804 }
805 //*************************************************************************************************
806 
807 
808 //*************************************************************************************************
829 template< typename Type // Data type of the matrix
830  , size_t M // Number of rows
831  , size_t N // Number of columns
832  , bool SO > // Storage order
833 template< typename Other // Data type of the initialization array
834  , size_t Rows // Number of rows of the initialization array
835  , size_t Cols > // Number of columns of the initialization array
836 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( const Other (&array)[Rows][Cols] )
837  : v_() // The statically allocated matrix elements
838  , m_( Rows ) // The current number of rows of the matrix
839  , n_( Cols ) // The current number of columns of the matrix
840 {
841  BLAZE_STATIC_ASSERT( Rows <= M );
842  BLAZE_STATIC_ASSERT( Cols <= N );
844 
845  for( size_t i=0UL; i<Rows; ++i ) {
846  for( size_t j=0UL; j<Cols; ++j )
847  v_[i*NN+j] = array[i][j];
848 
849  if( IsNumeric<Type>::value ) {
850  for( size_t j=Cols; j<NN; ++j )
851  v_[i*NN+j] = Type();
852  }
853  }
854 
855  if( IsNumeric<Type>::value ) {
856  for( size_t i=Rows; i<M; ++i )
857  for( size_t j=0UL; j<NN; ++j )
858  v_[i*NN+j] = Type();
859  }
860 
861  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
862 }
863 //*************************************************************************************************
864 
865 
866 //*************************************************************************************************
874 template< typename Type // Data type of the matrix
875  , size_t M // Number of rows
876  , size_t N // Number of columns
877  , bool SO > // Storage order
879  : v_() // The statically allocated matrix elements
880  , m_( m.m_ ) // The current number of rows of the matrix
881  , n_( m.n_ ) // The current number of columns of the matrix
882 {
884 
885  for( size_t i=0UL; i<m_; ++i ) {
886  for( size_t j=0UL; j<n_; ++j )
887  v_[i*NN+j] = m.v_[i*NN+j];
888 
889  if( IsNumeric<Type>::value ) {
890  for( size_t j=n_; j<NN; ++j )
891  v_[i*NN+j] = Type();
892  }
893  }
894 
895  if( IsNumeric<Type>::value ) {
896  for( size_t i=m_; i<M; ++i )
897  for( size_t j=0UL; j<NN; ++j )
898  v_[i*NN+j] = Type();
899  }
900 
901  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
902 }
903 //*************************************************************************************************
904 
905 
906 //*************************************************************************************************
912 template< typename Type // Data type of the matrix
913  , size_t M // Number of rows
914  , size_t N // Number of columns
915  , bool SO > // Storage order
916 template< typename MT // Type of the foreign matrix
917  , bool SO2 > // Storage order of the foreign matrix
919  : v_() // The statically allocated matrix elements
920  , m_( (~m).rows() ) // The current number of rows of the matrix
921  , n_( (~m).columns() ) // The current number of columns of the matrix
922 {
923  using blaze::assign;
924 
926 
927  if( (~m).rows() > M || (~m).columns() > N ) {
928  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
929  }
930 
931  for( size_t i=0UL; i<m_; ++i ) {
932  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : n_ );
933  j<( IsNumeric<Type>::value ? NN : n_ );
934  ++j ) {
935  v_[i*NN+j] = Type();
936  }
937  }
938 
939  if( IsNumeric<Type>::value ) {
940  for( size_t i=m_; i<M; ++i )
941  for( size_t j=0UL; j<NN; ++j )
942  v_[i*NN+j] = Type();
943  }
944 
945  assign( *this, ~m );
946 
947  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
948 }
949 //*************************************************************************************************
950 
951 
952 
953 
954 //=================================================================================================
955 //
956 // DATA ACCESS FUNCTIONS
957 //
958 //=================================================================================================
959 
960 //*************************************************************************************************
970 template< typename Type // Data type of the matrix
971  , size_t M // Number of rows
972  , size_t N // Number of columns
973  , bool SO > // Storage order
975  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) noexcept
976 {
977  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
978  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
979  return v_[i*NN+j];
980 }
981 //*************************************************************************************************
982 
983 
984 //*************************************************************************************************
994 template< typename Type // Data type of the matrix
995  , size_t M // Number of rows
996  , size_t N // Number of columns
997  , bool SO > // Storage order
999  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const noexcept
1000 {
1001  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
1002  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
1003  return v_[i*NN+j];
1004 }
1005 //*************************************************************************************************
1006 
1007 
1008 //*************************************************************************************************
1019 template< typename Type // Data type of the matrix
1020  , size_t M // Number of rows
1021  , size_t N // Number of columns
1022  , bool SO > // Storage order
1024  HybridMatrix<Type,M,N,SO>::at( size_t i, size_t j )
1025 {
1026  if( i >= m_ ) {
1027  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1028  }
1029  if( j >= n_ ) {
1030  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1031  }
1032  return (*this)(i,j);
1033 }
1034 //*************************************************************************************************
1035 
1036 
1037 //*************************************************************************************************
1048 template< typename Type // Data type of the matrix
1049  , size_t M // Number of rows
1050  , size_t N // Number of columns
1051  , bool SO > // Storage order
1053  HybridMatrix<Type,M,N,SO>::at( size_t i, size_t j ) const
1054 {
1055  if( i >= m_ ) {
1056  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1057  }
1058  if( j >= n_ ) {
1059  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1060  }
1061  return (*this)(i,j);
1062 }
1063 //*************************************************************************************************
1064 
1065 
1066 //*************************************************************************************************
1078 template< typename Type // Data type of the matrix
1079  , size_t M // Number of rows
1080  , size_t N // Number of columns
1081  , bool SO > // Storage order
1082 inline typename HybridMatrix<Type,M,N,SO>::Pointer
1084 {
1085  return v_;
1086 }
1087 //*************************************************************************************************
1088 
1089 
1090 //*************************************************************************************************
1102 template< typename Type // Data type of the matrix
1103  , size_t M // Number of rows
1104  , size_t N // Number of columns
1105  , bool SO > // Storage order
1108 {
1109  return v_;
1110 }
1111 //*************************************************************************************************
1112 
1113 
1114 //*************************************************************************************************
1122 template< typename Type // Data type of the matrix
1123  , size_t M // Number of rows
1124  , size_t N // Number of columns
1125  , bool SO > // Storage order
1126 inline typename HybridMatrix<Type,M,N,SO>::Pointer
1127  HybridMatrix<Type,M,N,SO>::data( size_t i ) noexcept
1128 {
1129  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1130  return v_ + i*NN;
1131 }
1132 //*************************************************************************************************
1133 
1134 
1135 //*************************************************************************************************
1143 template< typename Type // Data type of the matrix
1144  , size_t M // Number of rows
1145  , size_t N // Number of columns
1146  , bool SO > // Storage order
1148  HybridMatrix<Type,M,N,SO>::data( size_t i ) const noexcept
1149 {
1150  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1151  return v_ + i*NN;
1152 }
1153 //*************************************************************************************************
1154 
1155 
1156 //*************************************************************************************************
1167 template< typename Type // Data type of the matrix
1168  , size_t M // Number of rows
1169  , size_t N // Number of columns
1170  , bool SO > // Storage order
1173 {
1174  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1175  return Iterator( v_ + i*NN );
1176 }
1177 //*************************************************************************************************
1178 
1179 
1180 //*************************************************************************************************
1191 template< typename Type // Data type of the matrix
1192  , size_t M // Number of rows
1193  , size_t N // Number of columns
1194  , bool SO > // Storage order
1196  HybridMatrix<Type,M,N,SO>::begin( size_t i ) const noexcept
1197 {
1198  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1199  return ConstIterator( v_ + i*NN );
1200 }
1201 //*************************************************************************************************
1202 
1203 
1204 //*************************************************************************************************
1215 template< typename Type // Data type of the matrix
1216  , size_t M // Number of rows
1217  , size_t N // Number of columns
1218  , bool SO > // Storage order
1220  HybridMatrix<Type,M,N,SO>::cbegin( size_t i ) const noexcept
1221 {
1222  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1223  return ConstIterator( v_ + i*NN );
1224 }
1225 //*************************************************************************************************
1226 
1227 
1228 //*************************************************************************************************
1239 template< typename Type // Data type of the matrix
1240  , size_t M // Number of rows
1241  , size_t N // Number of columns
1242  , bool SO > // Storage order
1244  HybridMatrix<Type,M,N,SO>::end( size_t i ) noexcept
1245 {
1246  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1247  return Iterator( v_ + i*NN + N );
1248 }
1249 //*************************************************************************************************
1250 
1251 
1252 //*************************************************************************************************
1263 template< typename Type // Data type of the matrix
1264  , size_t M // Number of rows
1265  , size_t N // Number of columns
1266  , bool SO > // Storage order
1268  HybridMatrix<Type,M,N,SO>::end( size_t i ) const noexcept
1269 {
1270  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1271  return ConstIterator( v_ + i*NN + N );
1272 }
1273 //*************************************************************************************************
1274 
1275 
1276 //*************************************************************************************************
1287 template< typename Type // Data type of the matrix
1288  , size_t M // Number of rows
1289  , size_t N // Number of columns
1290  , bool SO > // Storage order
1292  HybridMatrix<Type,M,N,SO>::cend( size_t i ) const noexcept
1293 {
1294  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1295  return ConstIterator( v_ + i*NN + N );
1296 }
1297 //*************************************************************************************************
1298 
1299 
1300 
1301 
1302 //=================================================================================================
1303 //
1304 // ASSIGNMENT OPERATORS
1305 //
1306 //=================================================================================================
1307 
1308 //*************************************************************************************************
1314 template< typename Type // Data type of the matrix
1315  , size_t M // Number of rows
1316  , size_t N // Number of columns
1317  , bool SO > // Storage order
1319 {
1320  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1321  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1322 
1323  for( size_t i=0UL; i<m_; ++i )
1324  for( size_t j=0UL; j<n_; ++j )
1325  v_[i*NN+j] = set;
1326 
1327  return *this;
1328 }
1329 //*************************************************************************************************
1330 
1331 
1332 //*************************************************************************************************
1357 template< typename Type // Data type of the matrix
1358  , size_t M // Number of rows
1359  , size_t N // Number of columns
1360  , bool SO > // Storage order
1363 {
1364  const size_t m( list.size() );
1365  const size_t n( determineColumns( list ) );
1366 
1367  if( m > M ) {
1368  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1369  }
1370 
1371  if( n > N ) {
1372  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1373  }
1374 
1375  resize( m, n, false );
1376 
1377  size_t i( 0UL );
1378 
1379  for( const auto& rowList : list ) {
1380  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
1381  ++i;
1382  }
1383 
1384  return *this;
1385 }
1386 //*************************************************************************************************
1387 
1388 
1389 //*************************************************************************************************
1410 template< typename Type // Data type of the matrix
1411  , size_t M // Number of rows
1412  , size_t N // Number of columns
1413  , bool SO > // Storage order
1414 template< typename Other // Data type of the initialization array
1415  , size_t Rows // Number of rows of the initialization array
1416  , size_t Cols > // Number of columns of the initialization array
1417 inline HybridMatrix<Type,M,N,SO>& HybridMatrix<Type,M,N,SO>::operator=( const Other (&array)[Rows][Cols] )
1418 {
1419  BLAZE_STATIC_ASSERT( Rows <= M );
1420  BLAZE_STATIC_ASSERT( Cols <= N );
1421 
1422  resize( Rows, Cols );
1423 
1424  for( size_t i=0UL; i<Rows; ++i )
1425  for( size_t j=0UL; j<Cols; ++j )
1426  v_[i*NN+j] = array[i][j];
1427 
1428  return *this;
1429 }
1430 //*************************************************************************************************
1431 
1432 
1433 //*************************************************************************************************
1441 template< typename Type // Data type of the matrix
1442  , size_t M // Number of rows
1443  , size_t N // Number of columns
1444  , bool SO > // Storage order
1446 {
1447  using blaze::assign;
1448 
1449  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1450  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1451 
1452  resize( rhs.rows(), rhs.columns() );
1453  assign( *this, ~rhs );
1454 
1455  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1456 
1457  return *this;
1458 }
1459 //*************************************************************************************************
1460 
1461 
1462 //*************************************************************************************************
1473 template< typename Type // Data type of the matrix
1474  , size_t M // Number of rows
1475  , size_t N // Number of columns
1476  , bool SO > // Storage order
1477 template< typename MT // Type of the right-hand side matrix
1478  , bool SO2 > // Storage order of the right-hand side matrix
1480 {
1481  using blaze::assign;
1482 
1483  using TT = TransExprTrait_<This>;
1484  using CT = CTransExprTrait_<This>;
1485  using IT = InvExprTrait_<This>;
1486 
1487  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
1488  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
1489  }
1490 
1491  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1492  transpose();
1493  }
1494  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1495  ctranspose();
1496  }
1497  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1498  HybridMatrix tmp( ~rhs );
1499  resize( tmp.rows(), tmp.columns() );
1500  assign( *this, tmp );
1501  }
1502  else {
1503  resize( (~rhs).rows(), (~rhs).columns() );
1505  reset();
1506  assign( *this, ~rhs );
1507  }
1508 
1509  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1510 
1511  return *this;
1512 }
1513 //*************************************************************************************************
1514 
1515 
1516 //*************************************************************************************************
1526 template< typename Type // Data type of the matrix
1527  , size_t M // Number of rows
1528  , size_t N // Number of columns
1529  , bool SO > // Storage order
1530 template< typename MT // Type of the right-hand side matrix
1531  , bool SO2 > // Storage order of the right-hand side matrix
1533 {
1534  using blaze::addAssign;
1535 
1536  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1537  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1538  }
1539 
1540  if( (~rhs).canAlias( this ) ) {
1541  const ResultType_<MT> tmp( ~rhs );
1542  addAssign( *this, tmp );
1543  }
1544  else {
1545  addAssign( *this, ~rhs );
1546  }
1547 
1548  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1549 
1550  return *this;
1551 }
1552 //*************************************************************************************************
1553 
1554 
1555 //*************************************************************************************************
1565 template< typename Type // Data type of the matrix
1566  , size_t M // Number of rows
1567  , size_t N // Number of columns
1568  , bool SO > // Storage order
1569 template< typename MT // Type of the right-hand side matrix
1570  , bool SO2 > // Storage order of the right-hand side matrix
1572 {
1573  using blaze::subAssign;
1574 
1575  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1576  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1577  }
1578 
1579  if( (~rhs).canAlias( this ) ) {
1580  const ResultType_<MT> tmp( ~rhs );
1581  subAssign( *this, tmp );
1582  }
1583  else {
1584  subAssign( *this, ~rhs );
1585  }
1586 
1587  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1588 
1589  return *this;
1590 }
1591 //*************************************************************************************************
1592 
1593 
1594 //*************************************************************************************************
1604 template< typename Type // Data type of the matrix
1605  , size_t M // Number of rows
1606  , size_t N // Number of columns
1607  , bool SO > // Storage order
1608 template< typename MT // Type of the right-hand side matrix
1609  , bool SO2 > // Storage order of the right-hand side matrix
1611 {
1612  using blaze::schurAssign;
1613 
1614  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1615  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1616  }
1617 
1618  if( (~rhs).canAlias( this ) ) {
1619  const ResultType_<MT> tmp( ~rhs );
1620  schurAssign( *this, tmp );
1621  }
1622  else {
1623  schurAssign( *this, ~rhs );
1624  }
1625 
1626  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1627 
1628  return *this;
1629 }
1630 //*************************************************************************************************
1631 
1632 
1633 
1634 
1635 //=================================================================================================
1636 //
1637 // UTILITY FUNCTIONS
1638 //
1639 //=================================================================================================
1640 
1641 //*************************************************************************************************
1646 template< typename Type // Data type of the matrix
1647  , size_t M // Number of rows
1648  , size_t N // Number of columns
1649  , bool SO > // Storage order
1650 inline size_t HybridMatrix<Type,M,N,SO>::rows() const noexcept
1651 {
1652  return m_;
1653 }
1654 //*************************************************************************************************
1655 
1656 
1657 //*************************************************************************************************
1662 template< typename Type // Data type of the matrix
1663  , size_t M // Number of rows
1664  , size_t N // Number of columns
1665  , bool SO > // Storage order
1666 inline size_t HybridMatrix<Type,M,N,SO>::columns() const noexcept
1667 {
1668  return n_;
1669 }
1670 //*************************************************************************************************
1671 
1672 
1673 //*************************************************************************************************
1681 template< typename Type // Data type of the matrix
1682  , size_t M // Number of rows
1683  , size_t N // Number of columns
1684  , bool SO > // Storage order
1685 inline constexpr size_t HybridMatrix<Type,M,N,SO>::spacing() const noexcept
1686 {
1687  return NN;
1688 }
1689 //*************************************************************************************************
1690 
1691 
1692 //*************************************************************************************************
1697 template< typename Type // Data type of the matrix
1698  , size_t M // Number of rows
1699  , size_t N // Number of columns
1700  , bool SO > // Storage order
1701 inline constexpr size_t HybridMatrix<Type,M,N,SO>::capacity() const noexcept
1702 {
1703  return M*NN;
1704 }
1705 //*************************************************************************************************
1706 
1707 
1708 //*************************************************************************************************
1719 template< typename Type // Data type of the matrix
1720  , size_t M // Number of rows
1721  , size_t N // Number of columns
1722  , bool SO > // Storage order
1723 inline size_t HybridMatrix<Type,M,N,SO>::capacity( size_t i ) const noexcept
1724 {
1725  UNUSED_PARAMETER( i );
1726 
1727  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1728 
1729  return NN;
1730 }
1731 //*************************************************************************************************
1732 
1733 
1734 //*************************************************************************************************
1739 template< typename Type // Data type of the matrix
1740  , size_t M // Number of rows
1741  , size_t N // Number of columns
1742  , bool SO > // Storage order
1744 {
1745  size_t nonzeros( 0UL );
1746 
1747  for( size_t i=0UL; i<m_; ++i )
1748  for( size_t j=0UL; j<n_; ++j )
1749  if( !isDefault( v_[i*NN+j] ) )
1750  ++nonzeros;
1751 
1752  return nonzeros;
1753 }
1754 //*************************************************************************************************
1755 
1756 
1757 //*************************************************************************************************
1768 template< typename Type // Data type of the matrix
1769  , size_t M // Number of rows
1770  , size_t N // Number of columns
1771  , bool SO > // Storage order
1772 inline size_t HybridMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1773 {
1774  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1775 
1776  const size_t jend( i*NN + n_ );
1777  size_t nonzeros( 0UL );
1778 
1779  for( size_t j=i*NN; j<jend; ++j )
1780  if( !isDefault( v_[j] ) )
1781  ++nonzeros;
1782 
1783  return nonzeros;
1784 }
1785 //*************************************************************************************************
1786 
1787 
1788 //*************************************************************************************************
1793 template< typename Type // Data type of the matrix
1794  , size_t M // Number of rows
1795  , size_t N // Number of columns
1796  , bool SO > // Storage order
1798 {
1799  using blaze::clear;
1800 
1801  for( size_t i=0UL; i<m_; ++i )
1802  for( size_t j=0UL; j<n_; ++j )
1803  clear( v_[i*NN+j] );
1804 }
1805 //*************************************************************************************************
1806 
1807 
1808 //*************************************************************************************************
1819 template< typename Type // Data type of the matrix
1820  , size_t M // Number of rows
1821  , size_t N // Number of columns
1822  , bool SO > // Storage order
1823 inline void HybridMatrix<Type,M,N,SO>::reset( size_t i )
1824 {
1825  using blaze::clear;
1826 
1827  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1828  for( size_t j=0UL; j<n_; ++j )
1829  clear( v_[i*NN+j] );
1830 }
1831 //*************************************************************************************************
1832 
1833 
1834 //*************************************************************************************************
1841 template< typename Type // Data type of the matrix
1842  , size_t M // Number of rows
1843  , size_t N // Number of columns
1844  , bool SO > // Storage order
1846 {
1847  resize( 0UL, 0UL );
1848 }
1849 //*************************************************************************************************
1850 
1851 
1852 //*************************************************************************************************
1888 template< typename Type // Data type of the matrix
1889  , size_t M // Number of rows
1890  , size_t N // Number of columns
1891  , bool SO > // Storage order
1892 void HybridMatrix<Type,M,N,SO>::resize( size_t m, size_t n, bool preserve )
1893 {
1894  UNUSED_PARAMETER( preserve );
1895 
1896  if( m > M ) {
1897  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1898  }
1899 
1900  if( n > N ) {
1901  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1902  }
1903 
1904  if( IsVectorizable<Type>::value && n < n_ ) {
1905  for( size_t i=0UL; i<m; ++i )
1906  for( size_t j=n; j<n_; ++j )
1907  v_[i*NN+j] = Type();
1908  }
1909 
1910  if( IsVectorizable<Type>::value && m < m_ ) {
1911  for( size_t i=m; i<m_; ++i )
1912  for( size_t j=0UL; j<n_; ++j )
1913  v_[i*NN+j] = Type();
1914  }
1915 
1916  m_ = m;
1917  n_ = n;
1918 }
1919 //*************************************************************************************************
1920 
1921 
1922 //*************************************************************************************************
1937 template< typename Type // Data type of the matrix
1938  , size_t M // Number of rows
1939  , size_t N // Number of columns
1940  , bool SO > // Storage order
1941 inline void HybridMatrix<Type,M,N,SO>::extend( size_t m, size_t n, bool preserve )
1942 {
1943  UNUSED_PARAMETER( preserve );
1944  resize( m_+m, n_+n );
1945 }
1946 //*************************************************************************************************
1947 
1948 
1949 //*************************************************************************************************
1955 template< typename Type // Data type of the matrix
1956  , size_t M // Number of rows
1957  , size_t N // Number of columns
1958  , bool SO > // Storage order
1960 {
1961  using std::swap;
1962 
1963  const size_t maxrows( max( m_, m.m_ ) );
1964  const size_t maxcols( max( n_, m.n_ ) );
1965 
1966  for( size_t i=0UL; i<maxrows; ++i ) {
1967  for( size_t j=0UL; j<maxcols; ++j ) {
1968  swap( v_[i*NN+j], m(i,j) );
1969  }
1970  }
1971 
1972  swap( m_, m.m_ );
1973  swap( n_, m.n_ );
1974 }
1975 //*************************************************************************************************
1976 
1977 
1978 
1979 
1980 //=================================================================================================
1981 //
1982 // NUMERIC FUNCTIONS
1983 //
1984 //=================================================================================================
1985 
1986 //*************************************************************************************************
1997 template< typename Type // Data type of the matrix
1998  , size_t M // Number of rows
1999  , size_t N // Number of columns
2000  , bool SO > // Storage order
2002 {
2003  using std::swap;
2004 
2005  if( m_ > N || n_ > M ) {
2006  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2007  }
2008 
2009  const size_t maxsize( max( m_, n_ ) );
2010  for( size_t i=1UL; i<maxsize; ++i ) {
2011  for( size_t j=0UL; j<i; ++j ) {
2012  swap( v_[i*NN+j], v_[j*NN+i] );
2013  }
2014  }
2015 
2016  if( IsVectorizable<Type>::value && m_ < n_ ) {
2017  for( size_t i=0UL; i<m_; ++i ) {
2018  for( size_t j=m_; j<n_; ++j ) {
2019  v_[i*NN+j] = Type();
2020  }
2021  }
2022  }
2023 
2024  if( IsVectorizable<Type>::value && m_ > n_ ) {
2025  for( size_t i=n_; i<m_; ++i ) {
2026  for( size_t j=0UL; j<n_; ++j ) {
2027  v_[i*NN+j] = Type();
2028  }
2029  }
2030  }
2031 
2032  swap( m_, n_ );
2033 
2034  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2035 
2036  return *this;
2037 }
2038 //*************************************************************************************************
2039 
2040 
2041 //*************************************************************************************************
2052 template< typename Type // Data type of the matrix
2053  , size_t M // Number of rows
2054  , size_t N // Number of columns
2055  , bool SO > // Storage order
2057 {
2058  using std::swap;
2059 
2060  if( m_ > N || n_ > M ) {
2061  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2062  }
2063 
2064  const size_t maxsize( max( m_, n_ ) );
2065  for( size_t i=0UL; i<maxsize; ++i ) {
2066  for( size_t j=0UL; j<i; ++j ) {
2067  cswap( v_[i*NN+j], v_[j*NN+i] );
2068  }
2069  conjugate( v_[i*NN+i] );
2070  }
2071 
2072  if( IsVectorizable<Type>::value && m_ < n_ ) {
2073  for( size_t i=0UL; i<m_; ++i ) {
2074  for( size_t j=m_; j<n_; ++j ) {
2075  v_[i*NN+j] = Type();
2076  }
2077  }
2078  }
2079 
2080  if( IsVectorizable<Type>::value && m_ > n_ ) {
2081  for( size_t i=n_; i<m_; ++i ) {
2082  for( size_t j=0UL; j<n_; ++j ) {
2083  v_[i*NN+j] = Type();
2084  }
2085  }
2086  }
2087 
2088  swap( m_, n_ );
2089 
2090  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2091 
2092  return *this;
2093 }
2094 //*************************************************************************************************
2095 
2096 
2097 //*************************************************************************************************
2114 template< typename Type // Data type of the matrix
2115  , size_t M // Number of rows
2116  , size_t N // Number of columns
2117  , bool SO > // Storage order
2118 template< typename Other > // Data type of the scalar value
2120 {
2121  for( size_t i=0UL; i<m_; ++i )
2122  for( size_t j=0UL; j<n_; ++j )
2123  v_[i*NN+j] *= scalar;
2124 
2125  return *this;
2126 }
2127 //*************************************************************************************************
2128 
2129 
2130 
2131 
2132 //=================================================================================================
2133 //
2134 // MEMORY FUNCTIONS
2135 //
2136 //=================================================================================================
2137 
2138 //*************************************************************************************************
2148 template< typename Type // Data type of the matrix
2149  , size_t M // Number of rows
2150  , size_t N // Number of columns
2151  , bool SO > // Storage order
2152 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size )
2153 {
2155 
2156  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2157 
2158  return allocate<HybridMatrix>( 1UL );
2159 }
2160 //*************************************************************************************************
2161 
2162 
2163 //*************************************************************************************************
2173 template< typename Type // Data type of the matrix
2174  , size_t M // Number of rows
2175  , size_t N // Number of columns
2176  , bool SO > // Storage order
2177 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
2178 {
2179  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2180  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2181 
2182  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2183 }
2184 //*************************************************************************************************
2185 
2186 
2187 //*************************************************************************************************
2197 template< typename Type // Data type of the matrix
2198  , size_t M // Number of rows
2199  , size_t N // Number of columns
2200  , bool SO > // Storage order
2201 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
2202 {
2203  UNUSED_PARAMETER( size );
2204 
2205  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2206 
2207  return allocate<HybridMatrix>( 1UL );
2208 }
2209 //*************************************************************************************************
2210 
2211 
2212 //*************************************************************************************************
2222 template< typename Type // Data type of the matrix
2223  , size_t M // Number of rows
2224  , size_t N // Number of columns
2225  , bool SO > // Storage order
2226 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2227 {
2228  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2229  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2230 
2231  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2232 }
2233 //*************************************************************************************************
2234 
2235 
2236 //*************************************************************************************************
2242 template< typename Type // Data type of the matrix
2243  , size_t M // Number of rows
2244  , size_t N // Number of columns
2245  , bool SO > // Storage order
2246 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr )
2247 {
2248  deallocate( static_cast<HybridMatrix*>( ptr ) );
2249 }
2250 //*************************************************************************************************
2251 
2252 
2253 //*************************************************************************************************
2259 template< typename Type // Data type of the matrix
2260  , size_t M // Number of rows
2261  , size_t N // Number of columns
2262  , bool SO > // Storage order
2263 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2264 {
2265  deallocate( static_cast<HybridMatrix*>( ptr ) );
2266 }
2267 //*************************************************************************************************
2268 
2269 
2270 //*************************************************************************************************
2276 template< typename Type // Data type of the matrix
2277  , size_t M // Number of rows
2278  , size_t N // Number of columns
2279  , bool SO > // Storage order
2280 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2281 {
2282  deallocate( static_cast<HybridMatrix*>( ptr ) );
2283 }
2284 //*************************************************************************************************
2285 
2286 
2287 //*************************************************************************************************
2293 template< typename Type // Data type of the matrix
2294  , size_t M // Number of rows
2295  , size_t N // Number of columns
2296  , bool SO > // Storage order
2297 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2298 {
2299  deallocate( static_cast<HybridMatrix*>( ptr ) );
2300 }
2301 //*************************************************************************************************
2302 
2303 
2304 
2305 
2306 //=================================================================================================
2307 //
2308 // DEBUGGING FUNCTIONS
2309 //
2310 //=================================================================================================
2311 
2312 //*************************************************************************************************
2321 template< typename Type // Data type of the matrix
2322  , size_t M // Number of rows
2323  , size_t N // Number of columns
2324  , bool SO > // Storage order
2325 inline bool HybridMatrix<Type,M,N,SO>::isIntact() const noexcept
2326 {
2327  if( m_ > M || n_ > N )
2328  return false;
2329 
2331  {
2332  for( size_t i=0UL; i<m_; ++i ) {
2333  for( size_t j=n_; j<NN; ++j ) {
2334  if( v_[i*NN+j] != Type() )
2335  return false;
2336  }
2337  }
2338 
2339  for( size_t i=m_; i<M; ++i ) {
2340  for( size_t j=0UL; j<NN; ++j ) {
2341  if( v_[i*NN+j] != Type() )
2342  return false;
2343  }
2344  }
2345  }
2346 
2347  return true;
2348 }
2349 //*************************************************************************************************
2350 
2351 
2352 
2353 
2354 //=================================================================================================
2355 //
2356 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2357 //
2358 //=================================================================================================
2359 
2360 //*************************************************************************************************
2370 template< typename Type // Data type of the matrix
2371  , size_t M // Number of rows
2372  , size_t N // Number of columns
2373  , bool SO > // Storage order
2374 template< typename Other > // Data type of the foreign expression
2375 inline bool HybridMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const noexcept
2376 {
2377  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2378 }
2379 //*************************************************************************************************
2380 
2381 
2382 //*************************************************************************************************
2392 template< typename Type // Data type of the matrix
2393  , size_t M // Number of rows
2394  , size_t N // Number of columns
2395  , bool SO > // Storage order
2396 template< typename Other > // Data type of the foreign expression
2397 inline bool HybridMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const noexcept
2398 {
2399  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2400 }
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>::isAligned() const noexcept
2418 {
2419  return ( usePadding || columns() % SIMDSIZE == 0UL );
2420 }
2421 //*************************************************************************************************
2422 
2423 
2424 //*************************************************************************************************
2439 template< typename Type // Data type of the matrix
2440  , size_t M // Number of rows
2441  , size_t N // Number of columns
2442  , bool SO > // Storage order
2444  HybridMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const noexcept
2445 {
2446  if( usePadding )
2447  return loada( i, j );
2448  else
2449  return loadu( i, j );
2450 }
2451 //*************************************************************************************************
2452 
2453 
2454 //*************************************************************************************************
2469 template< typename Type // Data type of the matrix
2470  , size_t M // Number of rows
2471  , size_t N // Number of columns
2472  , bool SO > // Storage order
2474  HybridMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const noexcept
2475 {
2476  using blaze::loada;
2477 
2479 
2480  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2481  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2482  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2483  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2484  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2485 
2486  return loada( &v_[i*NN+j] );
2487 }
2488 //*************************************************************************************************
2489 
2490 
2491 //*************************************************************************************************
2506 template< typename Type // Data type of the matrix
2507  , size_t M // Number of rows
2508  , size_t N // Number of columns
2509  , bool SO > // Storage order
2511  HybridMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const noexcept
2512 {
2513  using blaze::loadu;
2514 
2516 
2517  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2518  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2519  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2520 
2521  return loadu( &v_[i*NN+j] );
2522 }
2523 //*************************************************************************************************
2524 
2525 
2526 //*************************************************************************************************
2542 template< typename Type // Data type of the matrix
2543  , size_t M // Number of rows
2544  , size_t N // Number of columns
2545  , bool SO > // Storage order
2547  HybridMatrix<Type,M,N,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2548 {
2549  if( usePadding )
2550  storea( i, j, value );
2551  else
2552  storeu( i, j, value );
2553 }
2554 //*************************************************************************************************
2555 
2556 
2557 //*************************************************************************************************
2573 template< typename Type // Data type of the matrix
2574  , size_t M // Number of rows
2575  , size_t N // Number of columns
2576  , bool SO > // Storage order
2578  HybridMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2579 {
2580  using blaze::storea;
2581 
2583 
2584  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2585  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2586  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2587  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2588  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2589 
2590  storea( &v_[i*NN+j], value );
2591 }
2592 //*************************************************************************************************
2593 
2594 
2595 //*************************************************************************************************
2611 template< typename Type // Data type of the matrix
2612  , size_t M // Number of rows
2613  , size_t N // Number of columns
2614  , bool SO > // Storage order
2616  HybridMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2617 {
2618  using blaze::storeu;
2619 
2621 
2622  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2623  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2624  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2625 
2626  storeu( &v_[i*NN+j], value );
2627 }
2628 //*************************************************************************************************
2629 
2630 
2631 //*************************************************************************************************
2648 template< typename Type // Data type of the matrix
2649  , size_t M // Number of rows
2650  , size_t N // Number of columns
2651  , bool SO > // Storage order
2653  HybridMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2654 {
2655  using blaze::stream;
2656 
2658 
2659  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2660  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2661  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2662  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2663  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2664 
2665  stream( &v_[i*NN+j], value );
2666 }
2667 //*************************************************************************************************
2668 
2669 
2670 //*************************************************************************************************
2681 template< typename Type // Data type of the matrix
2682  , size_t M // Number of rows
2683  , size_t N // Number of columns
2684  , bool SO > // Storage order
2685 template< typename MT // Type of the right-hand side dense matrix
2686  , bool SO2 > // Storage order of the right-hand side dense matrix
2689 {
2690  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2691 
2692  for( size_t i=0UL; i<m_; ++i ) {
2693  for( size_t j=0UL; j<n_; ++j ) {
2694  v_[i*NN+j] = (~rhs)(i,j);
2695  }
2696  }
2697 }
2698 //*************************************************************************************************
2699 
2700 
2701 //*************************************************************************************************
2712 template< typename Type // Data type of the matrix
2713  , size_t M // Number of rows
2714  , size_t N // Number of columns
2715  , bool SO > // Storage order
2716 template< typename MT // Type of the right-hand side dense matrix
2717  , bool SO2 > // Storage order of the right-hand side dense matrix
2720 {
2722 
2723  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2724 
2725  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2726 
2727  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2728  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2729 
2730  for( size_t i=0UL; i<m_; ++i )
2731  {
2732  size_t j( 0UL );
2733 
2734  for( ; j<jpos; j+=SIMDSIZE ) {
2735  store( i, j, (~rhs).load(i,j) );
2736  }
2737  for( ; remainder && j<n_; ++j ) {
2738  v_[i*NN+j] = (~rhs)(i,j);
2739  }
2740  }
2741 }
2742 //*************************************************************************************************
2743 
2744 
2745 //*************************************************************************************************
2756 template< typename Type // Data type of the matrix
2757  , size_t M // Number of rows
2758  , size_t N // Number of columns
2759  , bool SO > // Storage order
2760 template< typename MT > // Type of the right-hand side sparse matrix
2762 {
2763  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2764 
2765  for( size_t i=0UL; i<m_; ++i )
2766  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2767  v_[i*NN+element->index()] = element->value();
2768 }
2769 //*************************************************************************************************
2770 
2771 
2772 //*************************************************************************************************
2783 template< typename Type // Data type of the matrix
2784  , size_t M // Number of rows
2785  , size_t N // Number of columns
2786  , bool SO > // Storage order
2787 template< typename MT > // Type of the right-hand side sparse matrix
2789 {
2791 
2792  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2793 
2794  for( size_t j=0UL; j<n_; ++j )
2795  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2796  v_[element->index()*NN+j] = element->value();
2797 }
2798 //*************************************************************************************************
2799 
2800 
2801 //*************************************************************************************************
2812 template< typename Type // Data type of the matrix
2813  , size_t M // Number of rows
2814  , size_t N // Number of columns
2815  , bool SO > // Storage order
2816 template< typename MT // Type of the right-hand side dense matrix
2817  , bool SO2 > // Storage order of the right-hand side dense matrix
2820 {
2821  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2822 
2823  for( size_t i=0UL; i<m_; ++i )
2824  {
2825  if( IsDiagonal<MT>::value )
2826  {
2827  v_[i*NN+i] += (~rhs)(i,i);
2828  }
2829  else
2830  {
2831  const size_t jbegin( ( IsUpper<MT>::value )
2832  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2833  :( 0UL ) );
2834  const size_t jend ( ( IsLower<MT>::value )
2835  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2836  :( n_ ) );
2837  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2838 
2839  for( size_t j=jbegin; j<jend; ++j ) {
2840  v_[i*NN+j] += (~rhs)(i,j);
2841  }
2842  }
2843  }
2844 }
2845 //*************************************************************************************************
2846 
2847 
2848 //*************************************************************************************************
2859 template< typename Type // Data type of the matrix
2860  , size_t M // Number of rows
2861  , size_t N // Number of columns
2862  , bool SO > // Storage order
2863 template< typename MT // Type of the right-hand side dense matrix
2864  , bool SO2 > // Storage order of the right-hand side dense matrix
2865 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2867 {
2870 
2871  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2872 
2873  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2874 
2875  for( size_t i=0UL; i<m_; ++i )
2876  {
2877  const size_t jbegin( ( IsUpper<MT>::value )
2878  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2879  :( 0UL ) );
2880  const size_t jend ( ( IsLower<MT>::value )
2881  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2882  :( n_ ) );
2883  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2884 
2885  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2886  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2887 
2888  size_t j( jbegin );
2889 
2890  for( ; j<jpos; j+=SIMDSIZE ) {
2891  store( i, j, load(i,j) + (~rhs).load(i,j) );
2892  }
2893  for( ; remainder && j<jend; ++j ) {
2894  v_[i*NN+j] += (~rhs)(i,j);
2895  }
2896  }
2897 }
2898 //*************************************************************************************************
2899 
2900 
2901 //*************************************************************************************************
2912 template< typename Type // Data type of the matrix
2913  , size_t M // Number of rows
2914  , size_t N // Number of columns
2915  , bool SO > // Storage order
2916 template< typename MT > // Type of the right-hand side sparse matrix
2918 {
2919  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2920 
2921  for( size_t i=0UL; i<m_; ++i )
2922  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2923  v_[i*NN+element->index()] += element->value();
2924 }
2925 //*************************************************************************************************
2926 
2927 
2928 //*************************************************************************************************
2939 template< typename Type // Data type of the matrix
2940  , size_t M // Number of rows
2941  , size_t N // Number of columns
2942  , bool SO > // Storage order
2943 template< typename MT > // Type of the right-hand side sparse matrix
2945 {
2947 
2948  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2949 
2950  for( size_t j=0UL; j<n_; ++j )
2951  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2952  v_[element->index()*NN+j] += element->value();
2953 }
2954 //*************************************************************************************************
2955 
2956 
2957 //*************************************************************************************************
2968 template< typename Type // Data type of the matrix
2969  , size_t M // Number of rows
2970  , size_t N // Number of columns
2971  , bool SO > // Storage order
2972 template< typename MT // Type of the right-hand side dense matrix
2973  , bool SO2 > // Storage order of the right-hand side dense matrix
2976 {
2977  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2978 
2979  for( size_t i=0UL; i<m_; ++i )
2980  {
2981  if( IsDiagonal<MT>::value )
2982  {
2983  v_[i*NN+i] -= (~rhs)(i,i);
2984  }
2985  else
2986  {
2987  const size_t jbegin( ( IsUpper<MT>::value )
2988  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2989  :( 0UL ) );
2990  const size_t jend ( ( IsLower<MT>::value )
2991  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2992  :( n_ ) );
2993  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2994 
2995  for( size_t j=jbegin; j<jend; ++j ) {
2996  v_[i*NN+j] -= (~rhs)(i,j);
2997  }
2998  }
2999  }
3000 }
3001 //*************************************************************************************************
3002 
3003 
3004 //*************************************************************************************************
3015 template< typename Type // Data type of the matrix
3016  , size_t M // Number of rows
3017  , size_t N // Number of columns
3018  , bool SO > // Storage order
3019 template< typename MT // Type of the right-hand side dense matrix
3020  , bool SO2 > // Storage order of the right-hand side dense matrix
3021 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
3023 {
3026 
3027  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3028 
3029  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
3030 
3031  for( size_t i=0UL; i<m_; ++i )
3032  {
3033  const size_t jbegin( ( IsUpper<MT>::value )
3034  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
3035  :( 0UL ) );
3036  const size_t jend ( ( IsLower<MT>::value )
3037  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
3038  :( n_ ) );
3039  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3040 
3041  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
3042  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3043 
3044  size_t j( jbegin );
3045 
3046  for( ; j<jpos; j+=SIMDSIZE ) {
3047  store( i, j, load(i,j) - (~rhs).load(i,j) );
3048  }
3049  for( ; remainder && j<jend; ++j ) {
3050  v_[i*NN+j] -= (~rhs)(i,j);
3051  }
3052  }
3053 }
3054 //*************************************************************************************************
3055 
3056 
3057 //*************************************************************************************************
3068 template< typename Type // Data type of the matrix
3069  , size_t M // Number of rows
3070  , size_t N // Number of columns
3071  , bool SO > // Storage order
3072 template< typename MT > // Type of the right-hand side sparse matrix
3074 {
3075  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3076 
3077  for( size_t i=0UL; i<m_; ++i )
3078  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3079  v_[i*NN+element->index()] -= element->value();
3080 }
3081 //*************************************************************************************************
3082 
3083 
3084 //*************************************************************************************************
3095 template< typename Type // Data type of the matrix
3096  , size_t M // Number of rows
3097  , size_t N // Number of columns
3098  , bool SO > // Storage order
3099 template< typename MT > // Type of the right-hand side sparse matrix
3101 {
3103 
3104  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3105 
3106  for( size_t j=0UL; j<n_; ++j )
3107  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3108  v_[element->index()*NN+j] -= element->value();
3109 }
3110 //*************************************************************************************************
3111 
3112 
3113 //*************************************************************************************************
3124 template< typename Type // Data type of the matrix
3125  , size_t M // Number of rows
3126  , size_t N // Number of columns
3127  , bool SO > // Storage order
3128 template< typename MT // Type of the right-hand side dense matrix
3129  , bool SO2 > // Storage order of the right-hand side dense matrix
3130 inline DisableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3132 {
3133  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3134 
3135  for( size_t i=0UL; i<m_; ++i ) {
3136  for( size_t j=0UL; j<n_; ++j ) {
3137  v_[i*NN+j] *= (~rhs)(i,j);
3138  }
3139  }
3140 }
3141 //*************************************************************************************************
3142 
3143 
3144 //*************************************************************************************************
3155 template< typename Type // Data type of the matrix
3156  , size_t M // Number of rows
3157  , size_t N // Number of columns
3158  , bool SO > // Storage order
3159 template< typename MT // Type of the right-hand side dense matrix
3160  , bool SO2 > // Storage order of the right-hand side dense matrix
3161 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
3163 {
3165 
3166  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3167 
3168  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
3169 
3170  for( size_t i=0UL; i<m_; ++i )
3171  {
3172  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
3173  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3174 
3175  size_t j( 0UL );
3176 
3177  for( ; j<jpos; j+=SIMDSIZE ) {
3178  store( i, j, load(i,j) * (~rhs).load(i,j) );
3179  }
3180  for( ; remainder && j<n_; ++j ) {
3181  v_[i*NN+j] *= (~rhs)(i,j);
3182  }
3183  }
3184 }
3185 //*************************************************************************************************
3186 
3187 
3188 //*************************************************************************************************
3199 template< typename Type // Data type of the matrix
3200  , size_t M // Number of rows
3201  , size_t N // Number of columns
3202  , bool SO > // Storage order
3203 template< typename MT > // Type of the right-hand side sparse matrix
3205 {
3206  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3207 
3208  const HybridMatrix tmp( serial( *this ) );
3209 
3210  reset();
3211 
3212  for( size_t i=0UL; i<m_; ++i )
3213  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3214  v_[i*NN+element->index()] = tmp.v_[i*NN+element->index()] * element->value();
3215 }
3216 //*************************************************************************************************
3217 
3218 
3219 //*************************************************************************************************
3230 template< typename Type // Data type of the matrix
3231  , size_t M // Number of rows
3232  , size_t N // Number of columns
3233  , bool SO > // Storage order
3234 template< typename MT > // Type of the right-hand side sparse matrix
3236 {
3238 
3239  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3240 
3241  const HybridMatrix tmp( serial( *this ) );
3242 
3243  reset();
3244 
3245  for( size_t j=0UL; j<n_; ++j )
3246  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3247  v_[element->index()*NN+j] = tmp.v_[element->index()*NN+j] * element->value();
3248 }
3249 //*************************************************************************************************
3250 
3251 
3252 
3253 
3254 
3255 
3256 
3257 
3258 //=================================================================================================
3259 //
3260 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3261 //
3262 //=================================================================================================
3263 
3264 //*************************************************************************************************
3272 template< typename Type // Data type of the matrix
3273  , size_t M // Number of rows
3274  , size_t N > // Number of columns
3275 class HybridMatrix<Type,M,N,true>
3276  : public DenseMatrix< HybridMatrix<Type,M,N,true>, true >
3277 {
3278  public:
3279  //**Type definitions****************************************************************************
3282  using ResultType = This;
3285  using ElementType = Type;
3287  using ReturnType = const Type&;
3288  using CompositeType = const This&;
3289 
3290  using Reference = Type&;
3291  using ConstReference = const Type&;
3292  using Pointer = Type*;
3293  using ConstPointer = const Type*;
3294 
3297  //**********************************************************************************************
3298 
3299  //**Rebind struct definition********************************************************************
3302  template< typename NewType > // Data type of the other matrix
3303  struct Rebind {
3304  using Other = HybridMatrix<NewType,M,N,true>;
3305  };
3306  //**********************************************************************************************
3307 
3308  //**Resize struct definition********************************************************************
3311  template< size_t NewM // Number of rows of the other matrix
3312  , size_t NewN > // Number of columns of the other matrix
3313  struct Resize {
3314  using Other = HybridMatrix<Type,NewM,NewN,true>;
3315  };
3316  //**********************************************************************************************
3317 
3318  //**Compilation flags***************************************************************************
3320 
3324  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3325 
3327 
3330  enum : bool { smpAssignable = false };
3331  //**********************************************************************************************
3332 
3333  //**Constructors********************************************************************************
3336  explicit inline HybridMatrix();
3337  explicit inline HybridMatrix( size_t m, size_t n );
3338  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
3339  explicit inline HybridMatrix( initializer_list< initializer_list<Type> > list );
3340 
3341  template< typename Other >
3342  explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
3343 
3344  template< typename Other, size_t Rows, size_t Cols >
3345  explicit inline HybridMatrix( const Other (&array)[Rows][Cols] );
3346 
3347  inline HybridMatrix( const HybridMatrix& m );
3348  template< typename MT, bool SO > inline HybridMatrix( const Matrix<MT,SO>& m );
3350  //**********************************************************************************************
3351 
3352  //**Destructor**********************************************************************************
3353  // No explicitly declared destructor.
3354  //**********************************************************************************************
3355 
3356  //**Data access functions***********************************************************************
3359  inline Reference operator()( size_t i, size_t j ) noexcept;
3360  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3361  inline Reference at( size_t i, size_t j );
3362  inline ConstReference at( size_t i, size_t j ) const;
3363  inline Pointer data () noexcept;
3364  inline ConstPointer data () const noexcept;
3365  inline Pointer data ( size_t j ) noexcept;
3366  inline ConstPointer data ( size_t j ) const noexcept;
3367  inline Iterator begin ( size_t j ) noexcept;
3368  inline ConstIterator begin ( size_t j ) const noexcept;
3369  inline ConstIterator cbegin( size_t j ) const noexcept;
3370  inline Iterator end ( size_t j ) noexcept;
3371  inline ConstIterator end ( size_t j ) const noexcept;
3372  inline ConstIterator cend ( size_t j ) const noexcept;
3374  //**********************************************************************************************
3375 
3376  //**Assignment operators************************************************************************
3379  inline HybridMatrix& operator=( const Type& set );
3380  inline HybridMatrix& operator=( initializer_list< initializer_list<Type> > list );
3381 
3382  template< typename Other, size_t Rows, size_t Cols >
3383  inline HybridMatrix& operator=( const Other (&array)[Rows][Cols] );
3384 
3385  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
3386  template< typename MT, bool SO > inline HybridMatrix& operator= ( const Matrix<MT,SO>& rhs );
3387  template< typename MT, bool SO > inline HybridMatrix& operator+=( const Matrix<MT,SO>& rhs );
3388  template< typename MT, bool SO > inline HybridMatrix& operator-=( const Matrix<MT,SO>& rhs );
3389  template< typename MT, bool SO > inline HybridMatrix& operator%=( const Matrix<MT,SO>& rhs );
3391  //**********************************************************************************************
3392 
3393  //**Utility functions***************************************************************************
3396  inline size_t rows() const noexcept;
3397  inline size_t columns() const noexcept;
3398  inline constexpr size_t spacing() const noexcept;
3399  inline constexpr size_t capacity() const noexcept;
3400  inline size_t capacity( size_t j ) const noexcept;
3401  inline size_t nonZeros() const;
3402  inline size_t nonZeros( size_t j ) const;
3403  inline void reset();
3404  inline void reset( size_t i );
3405  inline void clear();
3406  void resize ( size_t m, size_t n, bool preserve=true );
3407  inline void extend ( size_t m, size_t n, bool preserve=true );
3408  inline void swap( HybridMatrix& m ) noexcept;
3410  //**********************************************************************************************
3411 
3412  //**Numeric functions***************************************************************************
3415  inline HybridMatrix& transpose();
3416  inline HybridMatrix& ctranspose();
3417 
3418  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
3420  //**********************************************************************************************
3421 
3422  //**Memory functions****************************************************************************
3425  static inline void* operator new ( std::size_t size );
3426  static inline void* operator new[]( std::size_t size );
3427  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3428  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3429 
3430  static inline void operator delete ( void* ptr );
3431  static inline void operator delete[]( void* ptr );
3432  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3433  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3435  //**********************************************************************************************
3436 
3437  private:
3438  //**********************************************************************************************
3440  template< typename MT >
3441  struct VectorizedAssign {
3442  enum : bool { value = useOptimizedKernels &&
3443  simdEnabled && MT::simdEnabled &&
3446  };
3447  //**********************************************************************************************
3448 
3449  //**********************************************************************************************
3451  template< typename MT >
3452  struct VectorizedAddAssign {
3453  enum : bool { value = useOptimizedKernels &&
3454  simdEnabled && MT::simdEnabled &&
3459  };
3460  //**********************************************************************************************
3461 
3462  //**********************************************************************************************
3464  template< typename MT >
3465  struct VectorizedSubAssign {
3466  enum : bool { value = useOptimizedKernels &&
3467  simdEnabled && MT::simdEnabled &&
3472  };
3473  //**********************************************************************************************
3474 
3475  //**********************************************************************************************
3477  template< typename MT >
3478  struct VectorizedSchurAssign {
3479  enum : bool { value = useOptimizedKernels &&
3480  simdEnabled && MT::simdEnabled &&
3484  };
3485  //**********************************************************************************************
3486 
3487  //**********************************************************************************************
3489  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3490  //**********************************************************************************************
3491 
3492  public:
3493  //**Debugging functions*************************************************************************
3496  inline bool isIntact() const noexcept;
3498  //**********************************************************************************************
3499 
3500  //**Expression template evaluation functions****************************************************
3503  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3504  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3505 
3506  inline bool isAligned() const noexcept;
3507 
3508  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3509  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3510  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3511 
3512  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3513  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3514  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3515  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3516 
3517  template< typename MT, bool SO >
3518  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3519 
3520  template< typename MT, bool SO >
3521  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3522 
3523  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3524  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3525 
3526  template< typename MT, bool SO >
3527  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3528 
3529  template< typename MT, bool SO >
3530  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3531 
3532  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3533  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3534 
3535  template< typename MT, bool SO >
3536  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3537 
3538  template< typename MT, bool SO >
3539  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3540 
3541  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3542  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3543 
3544  template< typename MT, bool SO >
3545  inline DisableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
3546 
3547  template< typename MT, bool SO >
3548  inline EnableIf_<VectorizedSchurAssign<MT> > schurAssign( const DenseMatrix<MT,SO>& rhs );
3549 
3550  template< typename MT > inline void schurAssign( const SparseMatrix<MT,true>& rhs );
3551  template< typename MT > inline void schurAssign( const SparseMatrix<MT,false>& rhs );
3553  //**********************************************************************************************
3554 
3555  private:
3556  //**********************************************************************************************
3558  enum : size_t { MM = ( usePadding )?( nextMultiple( M, SIMDSIZE ) ):( M ) };
3559  //**********************************************************************************************
3560 
3561  //**Member variables****************************************************************************
3565 
3567  size_t m_;
3568  size_t n_;
3569 
3570  //**********************************************************************************************
3571 
3572  //**Compile time checks*************************************************************************
3577  BLAZE_STATIC_ASSERT( !usePadding || MM % SIMDSIZE == 0UL );
3578  BLAZE_STATIC_ASSERT( MM >= M );
3579  //**********************************************************************************************
3580 };
3582 //*************************************************************************************************
3583 
3584 
3585 
3586 
3587 //=================================================================================================
3588 //
3589 // CONSTRUCTORS
3590 //
3591 //=================================================================================================
3592 
3593 //*************************************************************************************************
3599 template< typename Type // Data type of the matrix
3600  , size_t M // Number of rows
3601  , size_t N > // Number of columns
3603  : v_() // The statically allocated matrix elements
3604  , m_( 0UL ) // The current number of rows of the matrix
3605  , n_( 0UL ) // The current number of columns of the matrix
3606 {
3608 
3609  if( IsNumeric<Type>::value ) {
3610  for( size_t i=0UL; i<MM*N; ++i )
3611  v_[i] = Type();
3612  }
3613 
3614  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3615 }
3617 //*************************************************************************************************
3618 
3619 
3620 //*************************************************************************************************
3634 template< typename Type // Data type of the matrix
3635  , size_t M // Number of rows
3636  , size_t N > // Number of columns
3637 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n )
3638  : v_() // The statically allocated matrix elements
3639  , m_( m ) // The current number of rows of the matrix
3640  , n_( n ) // The current number of columns of the matrix
3641 {
3643 
3644  if( m > M ) {
3645  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3646  }
3647 
3648  if( n > N ) {
3649  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3650  }
3651 
3652  if( IsNumeric<Type>::value ) {
3653  for( size_t i=0UL; i<MM*N; ++i )
3654  v_[i] = Type();
3655  }
3656 
3657  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3658 }
3660 //*************************************************************************************************
3661 
3662 
3663 //*************************************************************************************************
3678 template< typename Type // Data type of the matrix
3679  , size_t M // Number of rows
3680  , size_t N > // Number of columns
3681 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Type& init )
3682  : v_() // The statically allocated matrix elements
3683  , m_( m ) // The current number of rows of the matrix
3684  , n_( n ) // The current number of columns of the matrix
3685 {
3687 
3688  if( m > M ) {
3689  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3690  }
3691 
3692  if( n > N ) {
3693  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3694  }
3695 
3696  for( size_t j=0UL; j<n; ++j ) {
3697  for( size_t i=0UL; i<m; ++i )
3698  v_[i+j*MM] = init;
3699 
3700  if( IsNumeric<Type>::value ) {
3701  for( size_t i=m; i<MM; ++i )
3702  v_[i+j*MM] = Type();
3703  }
3704  }
3705 
3706  if( IsNumeric<Type>::value ) {
3707  for( size_t j=n; j<N; ++j )
3708  for( size_t i=0UL; i<MM; ++i )
3709  v_[i+j*MM] = Type();
3710  }
3711 
3712  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3713 }
3715 //*************************************************************************************************
3716 
3717 
3718 //*************************************************************************************************
3743 template< typename Type // Data type of the matrix
3744  , size_t M // Number of rows
3745  , size_t N > // Number of columns
3747  : v_() // The statically allocated matrix elements
3748  , m_( list.size() ) // The current number of rows of the matrix
3749  , n_( determineColumns( list ) ) // The current number of columns of the matrix
3750 {
3752 
3753  if( m_ > M ) {
3754  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3755  }
3756 
3757  if( n_ > N ) {
3758  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3759  }
3760 
3761  size_t i( 0UL );
3762 
3763  for( const auto& rowList : list ) {
3764  size_t j( 0UL );
3765  for( const auto& element : rowList ) {
3766  v_[i+j*MM] = element;
3767  ++j;
3768  }
3769  if( IsNumeric<Type>::value ) {
3770  for( ; j<N; ++j ) {
3771  v_[i+j*MM] = Type();
3772  }
3773  }
3774  ++i;
3775  }
3776 
3777  BLAZE_INTERNAL_ASSERT( i == m_, "Invalid number of elements detected" );
3778 
3779  if( IsNumeric<Type>::value ) {
3780  for( ; i<MM; ++i ) {
3781  for( size_t j=0UL; j<N; ++j ) {
3782  v_[i+j*MM] = Type();
3783  }
3784  }
3785  }
3786 
3787  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3788 }
3790 //*************************************************************************************************
3791 
3792 
3793 //*************************************************************************************************
3821 template< typename Type // Data type of the matrix
3822  , size_t M // Number of rows
3823  , size_t N > // Number of columns
3824 template< typename Other > // Data type of the initialization array
3825 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Other* array )
3826  : v_() // The statically allocated matrix elements
3827  , m_( m ) // The current number of rows of the matrix
3828  , n_( n ) // The current number of columns of the matrix
3829 {
3831 
3832  if( m > M ) {
3833  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3834  }
3835 
3836  if( n > N ) {
3837  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3838  }
3839 
3840  for( size_t j=0UL; j<n; ++j ) {
3841  for( size_t i=0UL; i<m; ++i )
3842  v_[i+j*MM] = array[i+j*m];
3843 
3844  if( IsNumeric<Type>::value ) {
3845  for( size_t i=m; i<MM; ++i )
3846  v_[i+j*MM] = Type();
3847  }
3848  }
3849 
3850  if( IsNumeric<Type>::value ) {
3851  for( size_t j=n; j<N; ++j )
3852  for( size_t i=0UL; i<MM; ++i )
3853  v_[i+j*MM] = Type();
3854  }
3855 
3856  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3857 }
3859 //*************************************************************************************************
3860 
3861 
3862 //*************************************************************************************************
3884 template< typename Type // Data type of the matrix
3885  , size_t M // Number of rows
3886  , size_t N > // Number of columns
3887 template< typename Other // Data type of the initialization array
3888  , size_t Rows // Number of rows of the initialization array
3889  , size_t Cols > // Number of columns of the initialization array
3890 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const Other (&array)[Rows][Cols] )
3891  : v_() // The statically allocated matrix elements
3892  , m_( Rows ) // The current number of rows of the matrix
3893  , n_( Cols ) // The current number of columns of the matrix
3894 {
3895  BLAZE_STATIC_ASSERT( Rows <= M );
3896  BLAZE_STATIC_ASSERT( Cols <= N );
3898 
3899  for( size_t j=0UL; j<Cols; ++j ) {
3900  for( size_t i=0UL; i<Rows; ++i )
3901  v_[i+j*MM] = array[i][j];
3902 
3903  if( IsNumeric<Type>::value ) {
3904  for( size_t i=Rows; i<MM; ++i )
3905  v_[i+j*MM] = Type();
3906  }
3907  }
3908 
3909  if( IsNumeric<Type>::value ) {
3910  for( size_t j=Cols; j<N; ++j )
3911  for( size_t i=0UL; i<MM; ++i )
3912  v_[i+j*MM] = Type();
3913  }
3914 
3915  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3916 }
3918 //*************************************************************************************************
3919 
3920 
3921 //*************************************************************************************************
3930 template< typename Type // Data type of the matrix
3931  , size_t M // Number of rows
3932  , size_t N > // Number of columns
3934  : v_() // The statically allocated matrix elements
3935  , m_( m.m_ ) // The current number of rows of the matrix
3936  , n_( m.n_ ) // The current number of columns of the matrix
3937 {
3939 
3940  for( size_t j=0UL; j<n_; ++j ) {
3941  for( size_t i=0UL; i<m_; ++i )
3942  v_[i+j*MM] = m.v_[i+j*MM];
3943 
3944  if( IsNumeric<Type>::value ) {
3945  for( size_t i=m_; i<MM; ++i )
3946  v_[i+j*MM] = Type();
3947  }
3948  }
3949 
3950  if( IsNumeric<Type>::value ) {
3951  for( size_t j=n_; j<N; ++j )
3952  for( size_t i=0UL; i<MM; ++i )
3953  v_[i+j*MM] = Type();
3954  }
3955 
3956  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3957 }
3959 //*************************************************************************************************
3960 
3961 
3962 //*************************************************************************************************
3969 template< typename Type // Data type of the matrix
3970  , size_t M // Number of rows
3971  , size_t N > // Number of columns
3972 template< typename MT // Type of the foreign matrix
3973  , bool SO2 > // Storage order of the foreign matrix
3975  : v_() // The statically allocated matrix elements
3976  , m_( (~m).rows() ) // The current number of rows of the matrix
3977  , n_( (~m).columns() ) // The current number of columns of the matrix
3978 {
3979  using blaze::assign;
3980 
3982 
3983  if( (~m).rows() > M || (~m).columns() > N ) {
3984  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
3985  }
3986 
3987  for( size_t j=0UL; j<n_; ++j ) {
3988  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : m_ );
3989  i<( IsNumeric<Type>::value ? MM : m_ );
3990  ++i ) {
3991  v_[i+j*MM] = Type();
3992  }
3993  }
3994 
3995  if( IsNumeric<Type>::value ) {
3996  for( size_t j=n_; j<N; ++j )
3997  for( size_t i=0UL; i<MM; ++i )
3998  v_[i+j*MM] = Type();
3999  }
4000 
4001  assign( *this, ~m );
4002 
4003  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4004 }
4006 //*************************************************************************************************
4007 
4008 
4009 
4010 
4011 //=================================================================================================
4012 //
4013 // DATA ACCESS FUNCTIONS
4014 //
4015 //=================================================================================================
4016 
4017 //*************************************************************************************************
4028 template< typename Type // Data type of the matrix
4029  , size_t M // Number of rows
4030  , size_t N > // Number of columns
4032  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) noexcept
4033 {
4034  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
4035  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
4036  return v_[i+j*MM];
4037 }
4039 //*************************************************************************************************
4040 
4041 
4042 //*************************************************************************************************
4053 template< typename Type // Data type of the matrix
4054  , size_t M // Number of rows
4055  , size_t N > // Number of columns
4057  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const noexcept
4058 {
4059  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
4060  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
4061  return v_[i+j*MM];
4062 }
4064 //*************************************************************************************************
4065 
4066 
4067 //*************************************************************************************************
4079 template< typename Type // Data type of the matrix
4080  , size_t M // Number of rows
4081  , size_t N > // Number of columns
4083  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j )
4084 {
4085  if( i >= m_ ) {
4086  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4087  }
4088  if( j >= n_ ) {
4089  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4090  }
4091  return (*this)(i,j);
4092 }
4094 //*************************************************************************************************
4095 
4096 
4097 //*************************************************************************************************
4109 template< typename Type // Data type of the matrix
4110  , size_t M // Number of rows
4111  , size_t N > // Number of columns
4113  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
4114 {
4115  if( i >= m_ ) {
4116  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4117  }
4118  if( j >= n_ ) {
4119  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4120  }
4121  return (*this)(i,j);
4122 }
4124 //*************************************************************************************************
4125 
4126 
4127 //*************************************************************************************************
4139 template< typename Type // Data type of the matrix
4140  , size_t M // Number of rows
4141  , size_t N > // Number of columns
4144 {
4145  return v_;
4146 }
4148 //*************************************************************************************************
4149 
4150 
4151 //*************************************************************************************************
4163 template< typename Type // Data type of the matrix
4164  , size_t M // Number of rows
4165  , size_t N > // Number of columns
4167  HybridMatrix<Type,M,N,true>::data() const noexcept
4168 {
4169  return v_;
4170 }
4172 //*************************************************************************************************
4173 
4174 
4175 //*************************************************************************************************
4184 template< typename Type // Data type of the matrix
4185  , size_t M // Number of rows
4186  , size_t N > // Number of columns
4188  HybridMatrix<Type,M,N,true>::data( size_t j ) noexcept
4189 {
4190  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4191  return v_ + j*MM;
4192 }
4194 //*************************************************************************************************
4195 
4196 
4197 //*************************************************************************************************
4206 template< typename Type // Data type of the matrix
4207  , size_t M // Number of rows
4208  , size_t N > // Number of columns
4210  HybridMatrix<Type,M,N,true>::data( size_t j ) const noexcept
4211 {
4212  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4213  return v_ + j*MM;
4214 }
4216 //*************************************************************************************************
4217 
4218 
4219 //*************************************************************************************************
4226 template< typename Type // Data type of the matrix
4227  , size_t M // Number of rows
4228  , size_t N > // Number of columns
4230  HybridMatrix<Type,M,N,true>::begin( size_t j ) noexcept
4231 {
4232  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4233  return Iterator( v_ + j*MM );
4234 }
4236 //*************************************************************************************************
4237 
4238 
4239 //*************************************************************************************************
4246 template< typename Type // Data type of the matrix
4247  , size_t M // Number of rows
4248  , size_t N > // Number of columns
4250  HybridMatrix<Type,M,N,true>::begin( size_t j ) const noexcept
4251 {
4252  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4253  return ConstIterator( v_ + j*MM );
4254 }
4256 //*************************************************************************************************
4257 
4258 
4259 //*************************************************************************************************
4266 template< typename Type // Data type of the matrix
4267  , size_t M // Number of rows
4268  , size_t N > // Number of columns
4270  HybridMatrix<Type,M,N,true>::cbegin( size_t j ) const noexcept
4271 {
4272  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4273  return ConstIterator( v_ + j*MM );
4274 }
4276 //*************************************************************************************************
4277 
4278 
4279 //*************************************************************************************************
4286 template< typename Type // Data type of the matrix
4287  , size_t M // Number of rows
4288  , size_t N > // Number of columns
4290  HybridMatrix<Type,M,N,true>::end( size_t j ) noexcept
4291 {
4292  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4293  return Iterator( v_ + j*MM + M );
4294 }
4296 //*************************************************************************************************
4297 
4298 
4299 //*************************************************************************************************
4306 template< typename Type // Data type of the matrix
4307  , size_t M // Number of rows
4308  , size_t N > // Number of columns
4310  HybridMatrix<Type,M,N,true>::end( size_t j ) const noexcept
4311 {
4312  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4313  return ConstIterator( v_ + j*MM + M );
4314 }
4316 //*************************************************************************************************
4317 
4318 
4319 //*************************************************************************************************
4326 template< typename Type // Data type of the matrix
4327  , size_t M // Number of rows
4328  , size_t N > // Number of columns
4330  HybridMatrix<Type,M,N,true>::cend( size_t j ) const noexcept
4331 {
4332  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4333  return ConstIterator( v_ + j*MM + M );
4334 }
4336 //*************************************************************************************************
4337 
4338 
4339 
4340 
4341 //=================================================================================================
4342 //
4343 // ASSIGNMENT OPERATORS
4344 //
4345 //=================================================================================================
4346 
4347 //*************************************************************************************************
4354 template< typename Type // Data type of the matrix
4355  , size_t M // Number of rows
4356  , size_t N > // Number of columns
4358  HybridMatrix<Type,M,N,true>::operator=( const Type& set )
4359 {
4360  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
4361  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
4362 
4363  for( size_t j=0UL; j<n_; ++j )
4364  for( size_t i=0UL; i<m_; ++i )
4365  v_[i+j*MM] = set;
4366 
4367  return *this;
4368 }
4370 //*************************************************************************************************
4371 
4372 
4373 //*************************************************************************************************
4399 template< typename Type // Data type of the matrix
4400  , size_t M // Number of rows
4401  , size_t N > // Number of columns
4404 {
4405  const size_t m( list.size() );
4406  const size_t n( determineColumns( list ) );
4407 
4408  if( m > M ) {
4409  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4410  }
4411 
4412  if( n > N ) {
4413  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4414  }
4415 
4416  resize( m, n, false );
4417 
4418  size_t i( 0UL );
4419 
4420  for( const auto& rowList : list ) {
4421  size_t j( 0UL );
4422  for( const auto& element : rowList ) {
4423  v_[i+j*MM] = element;
4424  ++j;
4425  }
4426  for( ; j<n_; ++j ) {
4427  v_[i+j*MM] = Type();
4428  }
4429  ++i;
4430  }
4431 
4432  return *this;
4433 }
4435 //*************************************************************************************************
4436 
4437 
4438 //*************************************************************************************************
4460 template< typename Type // Data type of the matrix
4461  , size_t M // Number of rows
4462  , size_t N > // Number of columns
4463 template< typename Other // Data type of the initialization array
4464  , size_t Rows // Number of rows of the initialization array
4465  , size_t Cols > // Number of columns of the initialization array
4467  HybridMatrix<Type,M,N,true>::operator=( const Other (&array)[Rows][Cols] )
4468 {
4469  BLAZE_STATIC_ASSERT( Rows <= M );
4470  BLAZE_STATIC_ASSERT( Cols <= N );
4471 
4472  resize( Rows, Cols );
4473 
4474  for( size_t j=0UL; j<Cols; ++j )
4475  for( size_t i=0UL; i<Rows; ++i )
4476  v_[i+j*MM] = array[i][j];
4477 
4478  return *this;
4479 }
4481 //*************************************************************************************************
4482 
4483 
4484 //*************************************************************************************************
4493 template< typename Type // Data type of the matrix
4494  , size_t M // Number of rows
4495  , size_t N > // Number of columns
4498 {
4499  using blaze::assign;
4500 
4501  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
4502  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
4503 
4504  resize( rhs.rows(), rhs.columns() );
4505  assign( *this, ~rhs );
4506 
4507  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4508 
4509  return *this;
4510 }
4512 //*************************************************************************************************
4513 
4514 
4515 //*************************************************************************************************
4527 template< typename Type // Data type of the matrix
4528  , size_t M // Number of rows
4529  , size_t N > // Number of columns
4530 template< typename MT // Type of the right-hand side matrix
4531  , bool SO > // Storage order of the right-hand side matrix
4533 {
4534  using blaze::assign;
4535 
4536  using TT = TransExprTrait_<This>;
4537  using CT = CTransExprTrait_<This>;
4538  using IT = InvExprTrait_<This>;
4539 
4540  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
4541  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
4542  }
4543 
4544  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4545  transpose();
4546  }
4547  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4548  ctranspose();
4549  }
4550  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4551  HybridMatrix tmp( ~rhs );
4552  resize( tmp.rows(), tmp.columns() );
4553  assign( *this, tmp );
4554  }
4555  else {
4556  resize( (~rhs).rows(), (~rhs).columns() );
4558  reset();
4559  assign( *this, ~rhs );
4560  }
4561 
4562  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4563 
4564  return *this;
4565 }
4567 //*************************************************************************************************
4568 
4569 
4570 //*************************************************************************************************
4581 template< typename Type // Data type of the matrix
4582  , size_t M // Number of rows
4583  , size_t N > // Number of columns
4584 template< typename MT // Type of the right-hand side matrix
4585  , bool SO > // Storage order of the right-hand side matrix
4587 {
4588  using blaze::addAssign;
4589 
4590  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4591  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4592  }
4593 
4594  if( (~rhs).canAlias( this ) ) {
4595  const ResultType_<MT> tmp( ~rhs );
4596  addAssign( *this, tmp );
4597  }
4598  else {
4599  addAssign( *this, ~rhs );
4600  }
4601 
4602  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4603 
4604  return *this;
4605 }
4607 //*************************************************************************************************
4608 
4609 
4610 //*************************************************************************************************
4621 template< typename Type // Data type of the matrix
4622  , size_t M // Number of rows
4623  , size_t N > // Number of columns
4624 template< typename MT // Type of the right-hand side matrix
4625  , bool SO > // Storage order of the right-hand side matrix
4627 {
4628  using blaze::subAssign;
4629 
4630  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4631  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4632  }
4633 
4634  if( (~rhs).canAlias( this ) ) {
4635  const ResultType_<MT> tmp( ~rhs );
4636  subAssign( *this, tmp );
4637  }
4638  else {
4639  subAssign( *this, ~rhs );
4640  }
4641 
4642  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4643 
4644  return *this;
4645 }
4647 //*************************************************************************************************
4648 
4649 
4650 //*************************************************************************************************
4661 template< typename Type // Data type of the matrix
4662  , size_t M // Number of rows
4663  , size_t N > // Number of columns
4664 template< typename MT // Type of the right-hand side matrix
4665  , bool SO > // Storage order of the right-hand side matrix
4667 {
4668  using blaze::schurAssign;
4669 
4670  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4671  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4672  }
4673 
4674  if( (~rhs).canAlias( this ) ) {
4675  const ResultType_<MT> tmp( ~rhs );
4676  schurAssign( *this, tmp );
4677  }
4678  else {
4679  schurAssign( *this, ~rhs );
4680  }
4681 
4682  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4683 
4684  return *this;
4685 }
4687 //*************************************************************************************************
4688 
4689 
4690 
4691 
4692 //=================================================================================================
4693 //
4694 // UTILITY FUNCTIONS
4695 //
4696 //=================================================================================================
4697 
4698 //*************************************************************************************************
4704 template< typename Type // Data type of the matrix
4705  , size_t M // Number of rows
4706  , size_t N > // Number of columns
4707 inline size_t HybridMatrix<Type,M,N,true>::rows() const noexcept
4708 {
4709  return m_;
4710 }
4712 //*************************************************************************************************
4713 
4714 
4715 //*************************************************************************************************
4721 template< typename Type // Data type of the matrix
4722  , size_t M // Number of rows
4723  , size_t N > // Number of columns
4724 inline size_t HybridMatrix<Type,M,N,true>::columns() const noexcept
4725 {
4726  return n_;
4727 }
4729 //*************************************************************************************************
4730 
4731 
4732 //*************************************************************************************************
4741 template< typename Type // Data type of the matrix
4742  , size_t M // Number of rows
4743  , size_t N > // Number of columns
4744 inline constexpr size_t HybridMatrix<Type,M,N,true>::spacing() const noexcept
4745 {
4746  return MM;
4747 }
4749 //*************************************************************************************************
4750 
4751 
4752 //*************************************************************************************************
4758 template< typename Type // Data type of the matrix
4759  , size_t M // Number of rows
4760  , size_t N > // Number of columns
4761 inline constexpr size_t HybridMatrix<Type,M,N,true>::capacity() const noexcept
4762 {
4763  return MM*N;
4764 }
4766 //*************************************************************************************************
4767 
4768 
4769 //*************************************************************************************************
4776 template< typename Type // Data type of the matrix
4777  , size_t M // Number of rows
4778  , size_t N > // Number of columns
4779 inline size_t HybridMatrix<Type,M,N,true>::capacity( size_t j ) const noexcept
4780 {
4781  UNUSED_PARAMETER( j );
4782 
4783  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4784 
4785  return MM;
4786 }
4788 //*************************************************************************************************
4789 
4790 
4791 //*************************************************************************************************
4797 template< typename Type // Data type of the matrix
4798  , size_t M // Number of rows
4799  , size_t N > // Number of columns
4800 inline size_t HybridMatrix<Type,M,N,true>::nonZeros() const
4801 {
4802  size_t nonzeros( 0UL );
4803 
4804  for( size_t j=0UL; j<n_; ++j )
4805  for( size_t i=0UL; i<m_; ++i )
4806  if( !isDefault( v_[i+j*MM] ) )
4807  ++nonzeros;
4808 
4809  return nonzeros;
4810 }
4812 //*************************************************************************************************
4813 
4814 
4815 //*************************************************************************************************
4822 template< typename Type // Data type of the matrix
4823  , size_t M // Number of rows
4824  , size_t N > // Number of columns
4825 inline size_t HybridMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4826 {
4827  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4828 
4829  const size_t iend( j*MM + m_ );
4830  size_t nonzeros( 0UL );
4831 
4832  for( size_t i=j*MM; i<iend; ++i )
4833  if( !isDefault( v_[i] ) )
4834  ++nonzeros;
4835 
4836  return nonzeros;
4837 }
4839 //*************************************************************************************************
4840 
4841 
4842 //*************************************************************************************************
4848 template< typename Type // Data type of the matrix
4849  , size_t M // Number of rows
4850  , size_t N > // Number of columns
4852 {
4853  using blaze::clear;
4854 
4855  for( size_t j=0UL; j<n_; ++j )
4856  for( size_t i=0UL; i<m_; ++i )
4857  clear( v_[i+j*MM] );
4858 }
4860 //*************************************************************************************************
4861 
4862 
4863 //*************************************************************************************************
4873 template< typename Type // Data type of the matrix
4874  , size_t M // Number of rows
4875  , size_t N > // Number of columns
4876 inline void HybridMatrix<Type,M,N,true>::reset( size_t j )
4877 {
4878  using blaze::clear;
4879 
4880  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4881  for( size_t i=0UL; i<m_; ++i )
4882  clear( v_[i+j*MM] );
4883 }
4885 //*************************************************************************************************
4886 
4887 
4888 //*************************************************************************************************
4896 template< typename Type // Data type of the matrix
4897  , size_t M // Number of rows
4898  , size_t N > // Number of columns
4900 {
4901  resize( 0UL, 0UL );
4902 }
4904 //*************************************************************************************************
4905 
4906 
4907 //*************************************************************************************************
4944 template< typename Type // Data type of the matrix
4945  , size_t M // Number of rows
4946  , size_t N > // Number of columns
4947 void HybridMatrix<Type,M,N,true>::resize( size_t m, size_t n, bool preserve )
4948 {
4949  UNUSED_PARAMETER( preserve );
4950 
4951  if( m > M ) {
4952  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4953  }
4954 
4955  if( n > N ) {
4956  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4957  }
4958 
4959  if( IsVectorizable<Type>::value && m < m_ ) {
4960  for( size_t j=0UL; j<n; ++j )
4961  for( size_t i=m; i<m_; ++i )
4962  v_[i+j*MM] = Type();
4963  }
4964 
4965  if( IsVectorizable<Type>::value && n < n_ ) {
4966  for( size_t j=n; j<n_; ++j )
4967  for( size_t i=0UL; i<m_; ++i )
4968  v_[i+j*MM] = Type();
4969  }
4970 
4971  m_ = m;
4972  n_ = n;
4973 }
4975 //*************************************************************************************************
4976 
4977 
4978 //*************************************************************************************************
4994 template< typename Type // Data type of the matrix
4995  , size_t M // Number of rows
4996  , size_t N > // Number of columns
4997 inline void HybridMatrix<Type,M,N,true>::extend( size_t m, size_t n, bool preserve )
4998 {
4999  UNUSED_PARAMETER( preserve );
5000  resize( m_+m, n_+n );
5001 }
5003 //*************************************************************************************************
5004 
5005 
5006 //*************************************************************************************************
5013 template< typename Type // Data type of the matrix
5014  , size_t M // Number of rows
5015  , size_t N > // Number of columns
5016 inline void HybridMatrix<Type,M,N,true>::swap( HybridMatrix& m ) noexcept
5017 {
5018  using std::swap;
5019 
5020  const size_t maxrows( max( m_, m.m_ ) );
5021  const size_t maxcols( max( n_, m.n_ ) );
5022 
5023  for( size_t j=0UL; j<maxcols; ++j ) {
5024  for( size_t i=0UL; i<maxrows; ++i ) {
5025  swap( v_[i+j*MM], m(i,j) );
5026  }
5027  }
5028 
5029  swap( m_, m.m_ );
5030  swap( n_, m.n_ );
5031 }
5033 //*************************************************************************************************
5034 
5035 
5036 
5037 
5038 //=================================================================================================
5039 //
5040 // NUMERIC FUNCTIONS
5041 //
5042 //=================================================================================================
5043 
5044 //*************************************************************************************************
5056 template< typename Type // Data type of the matrix
5057  , size_t M // Number of rows
5058  , size_t N > // Number of columns
5060 {
5061  using std::swap;
5062 
5063  if( m_ > N || n_ > M ) {
5064  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
5065  }
5066 
5067  const size_t maxsize( max( m_, n_ ) );
5068  for( size_t j=1UL; j<maxsize; ++j ) {
5069  for( size_t i=0UL; i<j; ++i ) {
5070  swap( v_[i+j*MM], v_[j+i*MM] );
5071  }
5072  }
5073 
5074  if( IsVectorizable<Type>::value && n_ < m_ ) {
5075  for( size_t j=0UL; j<n_; ++j ) {
5076  for( size_t i=n_; i<m_; ++i ) {
5077  v_[i+j*MM] = Type();
5078  }
5079  }
5080  }
5081 
5082  if( IsVectorizable<Type>::value && n_ > m_ ) {
5083  for( size_t j=m_; j<n_; ++j ) {
5084  for( size_t i=0UL; i<m_; ++i ) {
5085  v_[i+j*MM] = Type();
5086  }
5087  }
5088  }
5089 
5090  swap( m_, n_ );
5091 
5092  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5093 
5094  return *this;
5095 }
5097 //*************************************************************************************************
5098 
5099 
5100 //*************************************************************************************************
5112 template< typename Type // Data type of the matrix
5113  , size_t M // Number of rows
5114  , size_t N > // Number of columns
5116 {
5117  using std::swap;
5118 
5119  if( m_ > N || n_ > M ) {
5120  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
5121  }
5122 
5123  const size_t maxsize( max( m_, n_ ) );
5124  for( size_t j=0UL; j<maxsize; ++j ) {
5125  for( size_t i=0UL; i<j; ++i ) {
5126  cswap( v_[i+j*MM], v_[j+i*MM] );
5127  }
5128  conjugate( v_[j+j*MM] );
5129  }
5130 
5131  if( IsVectorizable<Type>::value && n_ < m_ ) {
5132  for( size_t j=0UL; j<n_; ++j ) {
5133  for( size_t i=n_; i<m_; ++i ) {
5134  v_[i+j*MM] = Type();
5135  }
5136  }
5137  }
5138 
5139  if( IsVectorizable<Type>::value && n_ > m_ ) {
5140  for( size_t j=m_; j<n_; ++j ) {
5141  for( size_t i=0UL; i<m_; ++i ) {
5142  v_[i+j*MM] = Type();
5143  }
5144  }
5145  }
5146 
5147  swap( m_, n_ );
5148 
5149  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5150 
5151  return *this;
5152 }
5154 //*************************************************************************************************
5155 
5156 
5157 //*************************************************************************************************
5175 template< typename Type // Data type of the matrix
5176  , size_t M // Number of rows
5177  , size_t N > // Number of columns
5178 template< typename Other > // Data type of the scalar value
5180  HybridMatrix<Type,M,N,true>::scale( const Other& scalar )
5181 {
5182  for( size_t j=0UL; j<n_; ++j )
5183  for( size_t i=0UL; i<m_; ++i )
5184  v_[i+j*MM] *= scalar;
5185 
5186  return *this;
5187 }
5189 //*************************************************************************************************
5190 
5191 
5192 
5193 
5194 //=================================================================================================
5195 //
5196 // MEMORY FUNCTIONS
5197 //
5198 //=================================================================================================
5199 
5200 //*************************************************************************************************
5211 template< typename Type // Data type of the matrix
5212  , size_t M // Number of rows
5213  , size_t N > // Number of columns
5214 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size )
5215 {
5216  UNUSED_PARAMETER( size );
5217 
5218  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5219 
5220  return allocate<HybridMatrix>( 1UL );
5221 }
5223 //*************************************************************************************************
5224 
5225 
5226 //*************************************************************************************************
5237 template< typename Type // Data type of the matrix
5238  , size_t M // Number of rows
5239  , size_t N > // Number of columns
5240 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size )
5241 {
5242  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5243  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5244 
5245  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5246 }
5248 //*************************************************************************************************
5249 
5250 
5251 //*************************************************************************************************
5262 template< typename Type // Data type of the matrix
5263  , size_t M // Number of rows
5264  , size_t N > // Number of columns
5265 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
5266 {
5267  UNUSED_PARAMETER( size );
5268 
5269  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5270 
5271  return allocate<HybridMatrix>( 1UL );
5272 }
5274 //*************************************************************************************************
5275 
5276 
5277 //*************************************************************************************************
5288 template< typename Type // Data type of the matrix
5289  , size_t M // Number of rows
5290  , size_t N > // Number of columns
5291 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
5292 {
5293  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5294  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5295 
5296  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5297 }
5299 //*************************************************************************************************
5300 
5301 
5302 //*************************************************************************************************
5309 template< typename Type // Data type of the matrix
5310  , size_t M // Number of rows
5311  , size_t N > // Number of columns
5312 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr )
5313 {
5314  deallocate( static_cast<HybridMatrix*>( ptr ) );
5315 }
5317 //*************************************************************************************************
5318 
5319 
5320 //*************************************************************************************************
5327 template< typename Type // Data type of the matrix
5328  , size_t M // Number of rows
5329  , size_t N > // Number of columns
5330 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr )
5331 {
5332  deallocate( static_cast<HybridMatrix*>( ptr ) );
5333 }
5335 //*************************************************************************************************
5336 
5337 
5338 //*************************************************************************************************
5345 template< typename Type // Data type of the matrix
5346  , size_t M // Number of rows
5347  , size_t N > // Number of columns
5348 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
5349 {
5350  deallocate( static_cast<HybridMatrix*>( ptr ) );
5351 }
5353 //*************************************************************************************************
5354 
5355 
5356 //*************************************************************************************************
5363 template< typename Type // Data type of the matrix
5364  , size_t M // Number of rows
5365  , size_t N > // Number of columns
5366 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
5367 {
5368  deallocate( static_cast<HybridMatrix*>( ptr ) );
5369 }
5371 //*************************************************************************************************
5372 
5373 
5374 
5375 
5376 //=================================================================================================
5377 //
5378 // DEBUGGING FUNCTIONS
5379 //
5380 //=================================================================================================
5381 
5382 //*************************************************************************************************
5392 template< typename Type // Data type of the matrix
5393  , size_t M // Number of rows
5394  , size_t N > // Number of columns
5395 inline bool HybridMatrix<Type,M,N,true>::isIntact() const noexcept
5396 {
5397  if( m_ > M || n_ > N )
5398  return false;
5399 
5401  {
5402  for( size_t j=0UL; j<n_; ++j ) {
5403  for( size_t i=m_; i<MM; ++i ) {
5404  if( v_[i+j*MM] != Type() )
5405  return false;
5406  }
5407  }
5408 
5409  for( size_t j=n_; j<N; ++j ) {
5410  for( size_t i=0UL; i<MM; ++i ) {
5411  if( v_[i+j*MM] != Type() )
5412  return false;
5413  }
5414  }
5415  }
5416 
5417  return true;
5418 }
5420 //*************************************************************************************************
5421 
5422 
5423 
5424 
5425 //=================================================================================================
5426 //
5427 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5428 //
5429 //=================================================================================================
5430 
5431 //*************************************************************************************************
5442 template< typename Type // Data type of the matrix
5443  , size_t M // Number of rows
5444  , size_t N > // Number of columns
5445 template< typename Other > // Data type of the foreign expression
5446 inline bool HybridMatrix<Type,M,N,true>::canAlias( const Other* alias ) const noexcept
5447 {
5448  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5449 }
5451 //*************************************************************************************************
5452 
5453 
5454 //*************************************************************************************************
5465 template< typename Type // Data type of the matrix
5466  , size_t M // Number of rows
5467  , size_t N > // Number of columns
5468 template< typename Other > // Data type of the foreign expression
5469 inline bool HybridMatrix<Type,M,N,true>::isAliased( const Other* alias ) const noexcept
5470 {
5471  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5472 }
5474 //*************************************************************************************************
5475 
5476 
5477 //*************************************************************************************************
5487 template< typename Type // Data type of the matrix
5488  , size_t M // Number of rows
5489  , size_t N > // Number of columns
5490 inline bool HybridMatrix<Type,M,N,true>::isAligned() const noexcept
5491 {
5492  return ( usePadding || rows() % SIMDSIZE == 0UL );
5493 }
5495 //*************************************************************************************************
5496 
5497 
5498 //*************************************************************************************************
5513 template< typename Type // Data type of the matrix
5514  , size_t M // Number of rows
5515  , size_t N > // Number of columns
5517  HybridMatrix<Type,M,N,true>::load( size_t i, size_t j ) const noexcept
5518 {
5519  if( usePadding )
5520  return loada( i, j );
5521  else
5522  return loadu( i, j );
5523 }
5525 //*************************************************************************************************
5526 
5527 
5528 //*************************************************************************************************
5543 template< typename Type // Data type of the matrix
5544  , size_t M // Number of rows
5545  , size_t N > // Number of columns
5547  HybridMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const noexcept
5548 {
5549  using blaze::loada;
5550 
5552 
5553  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5554  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5555  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5556  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5557  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5558 
5559  return loada( &v_[i+j*MM] );
5560 }
5562 //*************************************************************************************************
5563 
5564 
5565 //*************************************************************************************************
5580 template< typename Type // Data type of the matrix
5581  , size_t M // Number of rows
5582  , size_t N > // Number of columns
5584  HybridMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const noexcept
5585 {
5586  using blaze::loadu;
5587 
5589 
5590  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5591  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5592  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5593 
5594  return loadu( &v_[i+j*MM] );
5595 }
5597 //*************************************************************************************************
5598 
5599 
5600 //*************************************************************************************************
5616 template< typename Type // Data type of the matrix
5617  , size_t M // Number of rows
5618  , size_t N > // Number of columns
5620  HybridMatrix<Type,M,N,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5621 {
5622  if( usePadding )
5623  storea( i, j, value );
5624  else
5625  storeu( i, j, value );
5626 }
5628 //*************************************************************************************************
5629 
5630 
5631 //*************************************************************************************************
5647 template< typename Type // Data type of the matrix
5648  , size_t M // Number of rows
5649  , size_t N > // Number of columns
5651  HybridMatrix<Type,M,N,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5652 {
5653  using blaze::storea;
5654 
5656 
5657  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5658  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5659  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5660  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5661  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5662 
5663  storea( &v_[i+j*MM], value );
5664 }
5666 //*************************************************************************************************
5667 
5668 
5669 //*************************************************************************************************
5685 template< typename Type // Data type of the matrix
5686  , size_t M // Number of rows
5687  , size_t N > // Number of columns
5689  HybridMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5690 {
5691  using blaze::storeu;
5692 
5694 
5695  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5696  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5697  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5698 
5699  storeu( &v_[i+j*MM], value );
5700 }
5702 //*************************************************************************************************
5703 
5704 
5705 //*************************************************************************************************
5722 template< typename Type // Data type of the matrix
5723  , size_t M // Number of rows
5724  , size_t N > // Number of columns
5726  HybridMatrix<Type,M,N,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5727 {
5728  using blaze::stream;
5729 
5731 
5732  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5733  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5734  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5735  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5736  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5737 
5738  stream( &v_[i+j*MM], value );
5739 }
5741 //*************************************************************************************************
5742 
5743 
5744 //*************************************************************************************************
5756 template< typename Type // Data type of the matrix
5757  , size_t M // Number of rows
5758  , size_t N > // Number of columns
5759 template< typename MT // Type of the right-hand side dense matrix
5760  , bool SO > // Storage order of the right-hand side dense matrix
5763 {
5764  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5765 
5766  for( size_t j=0UL; j<n_; ++j ) {
5767  for( size_t i=0UL; i<m_; ++i ) {
5768  v_[i+j*MM] = (~rhs)(i,j);
5769  }
5770  }
5771 }
5773 //*************************************************************************************************
5774 
5775 
5776 //*************************************************************************************************
5788 template< typename Type // Data type of the matrix
5789  , size_t M // Number of rows
5790  , size_t N > // Number of columns
5791 template< typename MT // Type of the right-hand side dense matrix
5792  , bool SO > // Storage order of the right-hand side dense matrix
5795 {
5797 
5798  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5799 
5800  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5801 
5802  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5803  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5804 
5805  for( size_t j=0UL; j<n_; ++j )
5806  {
5807  size_t i( 0UL );
5808 
5809  for( ; i<ipos; i+=SIMDSIZE ) {
5810  store( i, j, (~rhs).load(i,j) );
5811  }
5812  for( ; remainder && i<m_; ++i ) {
5813  v_[i+j*MM] = (~rhs)(i,j);
5814  }
5815  }
5816 }
5818 //*************************************************************************************************
5819 
5820 
5821 //*************************************************************************************************
5833 template< typename Type // Data type of the matrix
5834  , size_t M // Number of rows
5835  , size_t N > // Number of columns
5836 template< typename MT > // Type of the right-hand side sparse matrix
5838 {
5839  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5840 
5841  for( size_t j=0UL; j<n_; ++j )
5842  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5843  v_[element->index()+j*MM] = element->value();
5844 }
5846 //*************************************************************************************************
5847 
5848 
5849 //*************************************************************************************************
5861 template< typename Type // Data type of the matrix
5862  , size_t M // Number of rows
5863  , size_t N > // Number of columns
5864 template< typename MT > // Type of the right-hand side sparse matrix
5866 {
5868 
5869  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5870 
5871  for( size_t i=0UL; i<m_; ++i )
5872  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5873  v_[i+element->index()*MM] = element->value();
5874 }
5876 //*************************************************************************************************
5877 
5878 
5879 //*************************************************************************************************
5891 template< typename Type // Data type of the matrix
5892  , size_t M // Number of rows
5893  , size_t N > // Number of columns
5894 template< typename MT // Type of the right-hand side dense matrix
5895  , bool SO > // Storage order of the right-hand side dense matrix
5898 {
5899  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5900 
5901  for( size_t j=0UL; j<n_; ++j )
5902  {
5903  if( IsDiagonal<MT>::value )
5904  {
5905  v_[j+j*MM] += (~rhs)(j,j);
5906  }
5907  else
5908  {
5909  const size_t ibegin( ( IsLower<MT>::value )
5910  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5911  :( 0UL ) );
5912  const size_t iend ( ( IsUpper<MT>::value )
5913  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5914  :( m_ ) );
5915  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5916 
5917  for( size_t i=ibegin; i<iend; ++i ) {
5918  v_[i+j*MM] += (~rhs)(i,j);
5919  }
5920  }
5921  }
5922 }
5924 //*************************************************************************************************
5925 
5926 
5927 //*************************************************************************************************
5939 template< typename Type // Data type of the matrix
5940  , size_t M // Number of rows
5941  , size_t N > // Number of columns
5942 template< typename MT // Type of the right-hand side dense matrix
5943  , bool SO > // Storage order of the right-hand side dense matrix
5946 {
5949 
5950  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5951 
5952  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5953 
5954  for( size_t j=0UL; j<n_; ++j )
5955  {
5956  const size_t ibegin( ( IsLower<MT>::value )
5957  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5958  :( 0UL ) );
5959  const size_t iend ( ( IsUpper<MT>::value )
5960  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5961  :( m_ ) );
5962  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5963 
5964  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5965  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5966 
5967  size_t i( ibegin );
5968 
5969  for( ; i<ipos; i+=SIMDSIZE ) {
5970  store( i, j, load(i,j) + (~rhs).load(i,j) );
5971  }
5972  for( ; remainder && i<iend; ++i ) {
5973  v_[i+j*MM] += (~rhs)(i,j);
5974  }
5975  }
5976 }
5978 //*************************************************************************************************
5979 
5980 
5981 //*************************************************************************************************
5993 template< typename Type // Data type of the matrix
5994  , size_t M // Number of rows
5995  , size_t N > // Number of columns
5996 template< typename MT > // Type of the right-hand side sparse matrix
5998 {
5999  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6000 
6001  for( size_t j=0UL; j<n_; ++j )
6002  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6003  v_[element->index()+j*MM] += element->value();
6004 }
6006 //*************************************************************************************************
6007 
6008 
6009 //*************************************************************************************************
6021 template< typename Type // Data type of the matrix
6022  , size_t M // Number of rows
6023  , size_t N > // Number of columns
6024 template< typename MT > // Type of the right-hand side sparse matrix
6026 {
6028 
6029  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6030 
6031  for( size_t i=0UL; i<m_; ++i )
6032  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6033  v_[i+element->index()*MM] += element->value();
6034 }
6036 //*************************************************************************************************
6037 
6038 
6039 //*************************************************************************************************
6051 template< typename Type // Data type of the matrix
6052  , size_t M // Number of rows
6053  , size_t N > // Number of columns
6054 template< typename MT // Type of the right-hand side dense matrix
6055  , bool SO > // Storage order of the right-hand side dense matrix
6058 {
6059  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6060 
6061  for( size_t j=0UL; j<n_; ++j )
6062  {
6063  if( IsDiagonal<MT>::value )
6064  {
6065  v_[j+j*MM] -= (~rhs)(j,j);
6066  }
6067  else
6068  {
6069  const size_t ibegin( ( IsLower<MT>::value )
6070  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
6071  :( 0UL ) );
6072  const size_t iend ( ( IsUpper<MT>::value )
6073  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6074  :( m_ ) );
6075  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6076 
6077  for( size_t i=ibegin; i<iend; ++i ) {
6078  v_[i+j*MM] -= (~rhs)(i,j);
6079  }
6080  }
6081  }
6082 }
6084 //*************************************************************************************************
6085 
6086 
6087 //*************************************************************************************************
6099 template< typename Type // Data type of the matrix
6100  , size_t M // Number of rows
6101  , size_t N > // Number of columns
6102 template< typename MT // Type of the right-hand side dense matrix
6103  , bool SO > // Storage order of the right-hand side dense matrix
6106 {
6109 
6110  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6111 
6112  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
6113 
6114  for( size_t j=0UL; j<n_; ++j )
6115  {
6116  const size_t ibegin( ( IsLower<MT>::value )
6117  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
6118  :( 0UL ) );
6119  const size_t iend ( ( IsUpper<MT>::value )
6120  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6121  :( m_ ) );
6122  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6123 
6124  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
6125  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6126 
6127  size_t i( ibegin );
6128 
6129  for( ; i<ipos; i+=SIMDSIZE ) {
6130  store( i, j, load(i,j) - (~rhs).load(i,j) );
6131  }
6132  for( ; remainder && i<iend; ++i ) {
6133  v_[i+j*MM] -= (~rhs)(i,j);
6134  }
6135  }
6136 }
6138 //*************************************************************************************************
6139 
6140 
6141 //*************************************************************************************************
6153 template< typename Type // Data type of the matrix
6154  , size_t M // Number of rows
6155  , size_t N > // Number of columns
6156 template< typename MT > // Type of the right-hand side sparse matrix
6158 {
6159  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6160 
6161  for( size_t j=0UL; j<n_; ++j )
6162  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6163  v_[element->index()+j*MM] -= element->value();
6164 }
6166 //*************************************************************************************************
6167 
6168 
6169 //*************************************************************************************************
6181 template< typename Type // Data type of the matrix
6182  , size_t M // Number of rows
6183  , size_t N > // Number of columns
6184 template< typename MT > // Type of the right-hand side sparse matrix
6186 {
6188 
6189  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6190 
6191  for( size_t i=0UL; i<m_; ++i )
6192  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6193  v_[i+element->index()*MM] -= element->value();
6194 }
6196 //*************************************************************************************************
6197 
6198 
6199 //*************************************************************************************************
6211 template< typename Type // Data type of the matrix
6212  , size_t M // Number of rows
6213  , size_t N > // Number of columns
6214 template< typename MT // Type of the right-hand side dense matrix
6215  , bool SO > // Storage order of the right-hand side dense matrix
6216 inline DisableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
6218 {
6219  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6220 
6221  for( size_t j=0UL; j<n_; ++j ) {
6222  for( size_t i=0UL; i<m_; ++i ) {
6223  v_[i+j*MM] *= (~rhs)(i,j);
6224  }
6225  }
6226 }
6228 //*************************************************************************************************
6229 
6230 
6231 //*************************************************************************************************
6243 template< typename Type // Data type of the matrix
6244  , size_t M // Number of rows
6245  , size_t N > // Number of columns
6246 template< typename MT // Type of the right-hand side dense matrix
6247  , bool SO > // Storage order of the right-hand side dense matrix
6248 inline EnableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSchurAssign<MT> >
6250 {
6252 
6253  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6254 
6255  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
6256 
6257  for( size_t j=0UL; j<n_; ++j )
6258  {
6259  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
6260  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6261 
6262  size_t i( 0UL );
6263 
6264  for( ; i<ipos; i+=SIMDSIZE ) {
6265  store( i, j, load(i,j) * (~rhs).load(i,j) );
6266  }
6267  for( ; remainder && i<m_; ++i ) {
6268  v_[i+j*MM] *= (~rhs)(i,j);
6269  }
6270  }
6271 }
6273 //*************************************************************************************************
6274 
6275 
6276 //*************************************************************************************************
6288 template< typename Type // Data type of the matrix
6289  , size_t M // Number of rows
6290  , size_t N > // Number of columns
6291 template< typename MT > // Type of the right-hand side sparse matrix
6293 {
6294  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6295 
6296  const HybridMatrix tmp( serial( *this ) );
6297 
6298  reset();
6299 
6300  for( size_t j=0UL; j<n_; ++j )
6301  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6302  v_[element->index()+j*MM] = tmp.v_[element->index()+j*MM] * element->value();
6303 }
6305 //*************************************************************************************************
6306 
6307 
6308 //*************************************************************************************************
6320 template< typename Type // Data type of the matrix
6321  , size_t M // Number of rows
6322  , size_t N > // Number of columns
6323 template< typename MT > // Type of the right-hand side sparse matrix
6325 {
6327 
6328  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6329 
6330  const HybridMatrix tmp( serial( *this ) );
6331 
6332  reset();
6333 
6334  for( size_t i=0UL; i<m_; ++i )
6335  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6336  v_[i+element->index()*MM] = tmp.v_[i+element->index()*MM] * element->value();
6337 }
6339 //*************************************************************************************************
6340 
6341 
6342 
6343 
6344 
6345 
6346 
6347 
6348 //=================================================================================================
6349 //
6350 // STATICMATRIX OPERATORS
6351 //
6352 //=================================================================================================
6353 
6354 //*************************************************************************************************
6357 template< typename Type, size_t M, size_t N, bool SO >
6358 inline void reset( HybridMatrix<Type,M,N,SO>& m );
6359 
6360 template< typename Type, size_t M, size_t N, bool SO >
6361 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i );
6362 
6363 template< typename Type, size_t M, size_t N, bool SO >
6364 inline void clear( HybridMatrix<Type,M,N,SO>& m );
6365 
6366 template< bool RF, typename Type, size_t M, size_t N, bool SO >
6367 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m );
6368 
6369 template< typename Type, size_t M, size_t N, bool SO >
6370 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m ) noexcept;
6371 
6372 template< typename Type, size_t M, size_t N, bool SO >
6373 inline void swap( HybridMatrix<Type,M,N,SO>& a, HybridMatrix<Type,M,N,SO>& b ) noexcept;
6375 //*************************************************************************************************
6376 
6377 
6378 //*************************************************************************************************
6385 template< typename Type // Data type of the matrix
6386  , size_t M // Number of rows
6387  , size_t N // Number of columns
6388  , bool SO > // Storage order
6390 {
6391  m.reset();
6392 }
6393 //*************************************************************************************************
6394 
6395 
6396 //*************************************************************************************************
6409 template< typename Type // Data type of the matrix
6410  , size_t M // Number of rows
6411  , size_t N // Number of columns
6412  , bool SO > // Storage order
6413 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i )
6414 {
6415  m.reset( i );
6416 }
6417 //*************************************************************************************************
6418 
6419 
6420 //*************************************************************************************************
6427 template< typename Type // Data type of the matrix
6428  , size_t M // Number of rows
6429  , size_t N // Number of columns
6430  , bool SO > // Storage order
6432 {
6433  m.clear();
6434 }
6435 //*************************************************************************************************
6436 
6437 
6438 //*************************************************************************************************
6463 template< bool RF // Relaxation flag
6464  , typename Type // Data type of the matrix
6465  , size_t M // Number of rows
6466  , size_t N // Number of columns
6467  , bool SO > // Storage order
6468 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m )
6469 {
6470  return ( m.rows() == 0UL && m.columns() == 0UL );
6471 }
6472 //*************************************************************************************************
6473 
6474 
6475 //*************************************************************************************************
6493 template< typename Type // Data type of the matrix
6494  , size_t M // Number of rows
6495  , size_t N // Number of columns
6496  , bool SO > // Storage order
6497 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m ) noexcept
6498 {
6499  return m.isIntact();
6500 }
6501 //*************************************************************************************************
6502 
6503 
6504 //*************************************************************************************************
6512 template< typename Type // Data type of the matrix
6513  , size_t M // Number of rows
6514  , size_t N // Number of columns
6515  , bool SO > // Storage order
6517 {
6518  a.swap( b );
6519 }
6520 //*************************************************************************************************
6521 
6522 
6523 
6524 
6525 //=================================================================================================
6526 //
6527 // HASCONSTDATAACCESS SPECIALIZATIONS
6528 //
6529 //=================================================================================================
6530 
6531 //*************************************************************************************************
6533 template< typename T, size_t M, size_t N, bool SO >
6534 struct HasConstDataAccess< HybridMatrix<T,M,N,SO> >
6535  : public TrueType
6536 {};
6538 //*************************************************************************************************
6539 
6540 
6541 
6542 
6543 //=================================================================================================
6544 //
6545 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6546 //
6547 //=================================================================================================
6548 
6549 //*************************************************************************************************
6551 template< typename T, size_t M, size_t N, bool SO >
6552 struct HasMutableDataAccess< HybridMatrix<T,M,N,SO> >
6553  : public TrueType
6554 {};
6556 //*************************************************************************************************
6557 
6558 
6559 
6560 
6561 //=================================================================================================
6562 //
6563 // ISALIGNED SPECIALIZATIONS
6564 //
6565 //=================================================================================================
6566 
6567 //*************************************************************************************************
6569 template< typename T, size_t M, size_t N, bool SO >
6570 struct IsAligned< HybridMatrix<T,M,N,SO> >
6571  : public BoolConstant<usePadding>
6572 {};
6574 //*************************************************************************************************
6575 
6576 
6577 
6578 
6579 //=================================================================================================
6580 //
6581 // ISCONTIGUOUS SPECIALIZATIONS
6582 //
6583 //=================================================================================================
6584 
6585 //*************************************************************************************************
6587 template< typename T, size_t M, size_t N, bool SO >
6588 struct IsContiguous< HybridMatrix<T,M,N,SO> >
6589  : public TrueType
6590 {};
6592 //*************************************************************************************************
6593 
6594 
6595 
6596 
6597 //=================================================================================================
6598 //
6599 // ISPADDED SPECIALIZATIONS
6600 //
6601 //=================================================================================================
6602 
6603 //*************************************************************************************************
6605 template< typename T, size_t M, size_t N, bool SO >
6606 struct IsPadded< HybridMatrix<T,M,N,SO> >
6607  : public BoolConstant<usePadding>
6608 {};
6610 //*************************************************************************************************
6611 
6612 
6613 
6614 
6615 //=================================================================================================
6616 //
6617 // ISRESIZABLE SPECIALIZATIONS
6618 //
6619 //=================================================================================================
6620 
6621 //*************************************************************************************************
6623 template< typename T, size_t M, size_t N, bool SO >
6624 struct IsResizable< HybridMatrix<T,M,N,SO> >
6625  : public TrueType
6626 {};
6628 //*************************************************************************************************
6629 
6630 
6631 
6632 
6633 //=================================================================================================
6634 //
6635 // ADDTRAIT SPECIALIZATIONS
6636 //
6637 //=================================================================================================
6638 
6639 //*************************************************************************************************
6641 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6642 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6643 {
6644  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, SO >;
6645 };
6646 
6647 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6648 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6649 {
6650  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, false >;
6651 };
6652 
6653 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6654 struct AddTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6655 {
6656  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, SO >;
6657 };
6658 
6659 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6660 struct AddTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6661 {
6662  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, false >;
6663 };
6664 
6665 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6666 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6667 {
6668  using Type = HybridMatrix< AddTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6669 };
6670 
6671 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6672 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6673 {
6674  using Type = HybridMatrix< AddTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6675 };
6677 //*************************************************************************************************
6678 
6679 
6680 
6681 
6682 //=================================================================================================
6683 //
6684 // SUBTRAIT SPECIALIZATIONS
6685 //
6686 //=================================================================================================
6687 
6688 //*************************************************************************************************
6690 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6691 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6692 {
6693  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, SO >;
6694 };
6695 
6696 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6697 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6698 {
6699  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, false >;
6700 };
6701 
6702 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6703 struct SubTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6704 {
6705  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, SO >;
6706 };
6707 
6708 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6709 struct SubTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6710 {
6711  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, false >;
6712 };
6713 
6714 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6715 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6716 {
6717  using Type = HybridMatrix< SubTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6718 };
6719 
6720 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6721 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6722 {
6723  using Type = HybridMatrix< SubTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6724 };
6726 //*************************************************************************************************
6727 
6728 
6729 
6730 
6731 //=================================================================================================
6732 //
6733 // SCHURTRAIT SPECIALIZATIONS
6734 //
6735 //=================================================================================================
6736 
6737 //*************************************************************************************************
6739 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6740 struct SchurTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6741 {
6742  using Type = StaticMatrix< MultTrait_<T1,T2>, M2, N2, SO >;
6743 };
6744 
6745 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6746 struct SchurTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6747 {
6748  using Type = StaticMatrix< MultTrait_<T1,T2>, M2, N2, false >;
6749 };
6750 
6751 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6752 struct SchurTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6753 {
6754  using Type = StaticMatrix< MultTrait_<T1,T2>, M2, N2, SO >;
6755 };
6756 
6757 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6758 struct SchurTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6759 {
6760  using Type = StaticMatrix< MultTrait_<T1,T2>, M2, N2, false >;
6761 };
6762 
6763 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6764 struct SchurTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6765 {
6766  using Type = HybridMatrix< MultTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6767 };
6768 
6769 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6770 struct SchurTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6771 {
6772  using Type = HybridMatrix< MultTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6773 };
6775 //*************************************************************************************************
6776 
6777 
6778 
6779 
6780 //=================================================================================================
6781 //
6782 // MULTTRAIT SPECIALIZATIONS
6783 //
6784 //=================================================================================================
6785 
6786 //*************************************************************************************************
6788 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6789 struct MultTrait< HybridMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6790 {
6791  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6792 };
6793 
6794 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6795 struct MultTrait< T1, HybridMatrix<T2,M,N,SO>, EnableIf_<IsNumeric<T1> > >
6796 {
6797  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6798 };
6799 
6800 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6801 struct MultTrait< HybridMatrix<T1,M,N,SO>, StaticVector<T2,K,false> >
6802 {
6803  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6804 };
6805 
6806 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6807 struct MultTrait< StaticVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6808 {
6809  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6810 };
6811 
6812 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6813 struct MultTrait< HybridMatrix<T1,M,N,SO>, HybridVector<T2,K,false> >
6814 {
6815  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6816 };
6817 
6818 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6819 struct MultTrait< HybridVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6820 {
6821  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6822 };
6823 
6824 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6825 struct MultTrait< HybridMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
6826 {
6827  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6828 };
6829 
6830 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6831 struct MultTrait< DynamicVector<T1,true>, HybridMatrix<T2,M,N,SO> >
6832 {
6833  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6834 };
6835 
6836 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6837 struct MultTrait< HybridMatrix<T1,M,N,SO>, CustomVector<T2,AF,PF,false> >
6838 {
6839  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6840 };
6841 
6842 template< typename T1, bool AF, bool PF, typename T2, size_t M, size_t N, bool SO >
6843 struct MultTrait< CustomVector<T1,AF,PF,true>, HybridMatrix<T2,M,N,SO> >
6844 {
6845  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6846 };
6847 
6848 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6849 struct MultTrait< HybridMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
6850 {
6851  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6852 };
6853 
6854 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6855 struct MultTrait< CompressedVector<T1,true>, HybridMatrix<T2,M,N,SO> >
6856 {
6857  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6858 };
6859 
6860 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6861 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6862 {
6863  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
6864 };
6865 
6866 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6867 struct MultTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6868 {
6869  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
6870 };
6871 
6872 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6873 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6874 {
6875  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
6876 };
6878 //*************************************************************************************************
6879 
6880 
6881 
6882 
6883 //=================================================================================================
6884 //
6885 // DIVTRAIT SPECIALIZATIONS
6886 //
6887 //=================================================================================================
6888 
6889 //*************************************************************************************************
6891 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6892 struct DivTrait< HybridMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6893 {
6894  using Type = HybridMatrix< DivTrait_<T1,T2>, M, N, SO >;
6895 };
6897 //*************************************************************************************************
6898 
6899 
6900 
6901 
6902 //=================================================================================================
6903 //
6904 // UNARYMAPTRAIT SPECIALIZATIONS
6905 //
6906 //=================================================================================================
6907 
6908 //*************************************************************************************************
6910 template< typename T, size_t M, size_t N, bool SO, typename OP >
6911 struct UnaryMapTrait< HybridMatrix<T,M,N,SO>, OP >
6912 {
6913  using Type = HybridMatrix< UnaryMapTrait_<T,OP>, M, N, SO >;
6914 };
6916 //*************************************************************************************************
6917 
6918 
6919 
6920 
6921 //=================================================================================================
6922 //
6923 // BINARYMAPTRAIT SPECIALIZATIONS
6924 //
6925 //=================================================================================================
6926 
6927 //*************************************************************************************************
6929 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2, typename OP >
6930 struct BinaryMapTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO>, OP >
6931 {
6932  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M2, N2, SO >;
6933 };
6934 
6935 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2, typename OP >
6936 struct BinaryMapTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2>, OP >
6937 {
6938  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M2, N2, false >;
6939 };
6940 
6941 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2, typename OP >
6942 struct BinaryMapTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO>, OP >
6943 {
6944  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M2, N2, SO >;
6945 };
6946 
6947 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2, typename OP >
6948 struct BinaryMapTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2>, OP >
6949 {
6950  using Type = StaticMatrix< BinaryMapTrait_<T1,T2,OP>, M2, N2, false >;
6951 };
6952 
6953 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2, typename OP >
6954 struct BinaryMapTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO>, OP >
6955 {
6956  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6957 };
6958 
6959 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2, typename OP >
6960 struct BinaryMapTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2>, OP >
6961 {
6962  using Type = HybridMatrix< BinaryMapTrait_<T1,T2,OP>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6963 };
6965 //*************************************************************************************************
6966 
6967 
6968 
6969 
6970 //=================================================================================================
6971 //
6972 // HIGHTYPE SPECIALIZATIONS
6973 //
6974 //=================================================================================================
6975 
6976 //*************************************************************************************************
6978 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6979 struct HighType< HybridMatrix<T1,M,N,SO>, HybridMatrix<T2,M,N,SO> >
6980 {
6981  using Type = HybridMatrix< typename HighType<T1,T2>::Type, M, N, SO >;
6982 };
6984 //*************************************************************************************************
6985 
6986 
6987 
6988 
6989 //=================================================================================================
6990 //
6991 // LOWTYPE SPECIALIZATIONS
6992 //
6993 //=================================================================================================
6994 
6995 //*************************************************************************************************
6997 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6998 struct LowType< HybridMatrix<T1,M,N,SO>, HybridMatrix<T2,M,N,SO> >
6999 {
7000  using Type = HybridMatrix< typename LowType<T1,T2>::Type, M, N, SO >;
7001 };
7003 //*************************************************************************************************
7004 
7005 
7006 
7007 
7008 //=================================================================================================
7009 //
7010 // SUBMATRIXTRAIT SPECIALIZATIONS
7011 //
7012 //=================================================================================================
7013 
7014 //*************************************************************************************************
7016 template< typename T, size_t M1, size_t N1, bool SO, size_t I, size_t J, size_t M2, size_t N2 >
7017 struct SubmatrixTrait< HybridMatrix<T,M1,N1,SO>, I, J, M2, N2 >
7018 {
7019  using Type = StaticMatrix<T,M2,N2,SO>;
7020 };
7021 
7022 template< typename T, size_t M, size_t N, bool SO >
7023 struct SubmatrixTrait< HybridMatrix<T,M,N,SO> >
7024 {
7025  using Type = HybridMatrix<T,M,N,SO>;
7026 };
7028 //*************************************************************************************************
7029 
7030 
7031 
7032 
7033 //=================================================================================================
7034 //
7035 // ROWTRAIT SPECIALIZATIONS
7036 //
7037 //=================================================================================================
7038 
7039 //*************************************************************************************************
7041 template< typename T, size_t M, size_t N, bool SO, size_t... CRAs >
7042 struct RowTrait< HybridMatrix<T,M,N,SO>, CRAs... >
7043 {
7044  using Type = HybridVector<T,N,true>;
7045 };
7047 //*************************************************************************************************
7048 
7049 
7050 
7051 
7052 //=================================================================================================
7053 //
7054 // ROWSTRAIT SPECIALIZATIONS
7055 //
7056 //=================================================================================================
7057 
7058 //*************************************************************************************************
7060 template< typename T, size_t M, size_t N, bool SO, size_t... CRAs >
7061 struct RowsTrait< HybridMatrix<T,M,N,SO>, CRAs... >
7062 {
7063  using Type = HybridMatrix<T,sizeof...(CRAs),N,false>;
7064 };
7065 
7066 template< typename T, size_t M, size_t N, bool SO >
7067 struct RowsTrait< HybridMatrix<T,M,N,SO> >
7068 {
7069  using Type = HybridMatrix<T,M,N,false>;
7070 };
7072 //*************************************************************************************************
7073 
7074 
7075 
7076 
7077 //=================================================================================================
7078 //
7079 // COLUMNTRAIT SPECIALIZATIONS
7080 //
7081 //=================================================================================================
7082 
7083 //*************************************************************************************************
7085 template< typename T, size_t M, size_t N, bool SO, size_t... CCAs >
7086 struct ColumnTrait< HybridMatrix<T,M,N,SO>, CCAs... >
7087 {
7088  using Type = HybridVector<T,M,false>;
7089 };
7091 //*************************************************************************************************
7092 
7093 
7094 
7095 
7096 //=================================================================================================
7097 //
7098 // COLUMNSTRAIT SPECIALIZATIONS
7099 //
7100 //=================================================================================================
7101 
7102 //*************************************************************************************************
7104 template< typename T, size_t M, size_t N, bool SO, size_t... CCAs >
7105 struct ColumnsTrait< HybridMatrix<T,M,N,SO>, CCAs... >
7106 {
7107  using Type = HybridMatrix<T,M,sizeof...(CCAs),true>;
7108 };
7109 
7110 template< typename T, size_t M, size_t N, bool SO >
7111 struct ColumnsTrait< HybridMatrix<T,M,N,SO> >
7112 {
7113  using Type = HybridMatrix<T,M,N,true>;
7114 };
7116 //*************************************************************************************************
7117 
7118 
7119 
7120 
7121 //=================================================================================================
7122 //
7123 // BANDTRAIT SPECIALIZATIONS
7124 //
7125 //=================================================================================================
7126 
7127 //*************************************************************************************************
7129 template< typename T, size_t M, size_t N, bool SO >
7130 struct BandTrait< HybridMatrix<T,M,N,SO> >
7131 {
7132  enum : size_t { Min = min( M, N ) };
7134 };
7135 
7136 template< typename T, size_t M, size_t N, bool SO, ptrdiff_t I >
7137 struct BandTrait< HybridMatrix<T,M,N,SO>, I >
7138 {
7139  enum : size_t { Min = min( M - ( I >= 0L ? 0UL : -I ), N - ( I >= 0L ? I : 0UL ) ) };
7141 };
7143 //*************************************************************************************************
7144 
7145 } // namespace blaze
7146 
7147 #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.
Headerfile for the generic min algorithm.
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:1292
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:109
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:108
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:243
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
Header file for the IsSame and IsStrictlySame type traits.
Base template for the SchurTrait class.
Definition: SchurTrait.h:112
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:1172
Header file for the IsColumnMajorMatrix type trait.
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: HybridMatrix.h:1024
constexpr size_t spacing() const noexcept
Returns the spacing between the beginning of two rows.
Definition: HybridMatrix.h:1685
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:87
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:1244
#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:1650
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:87
Header file for memory allocation and deallocation functionality.
Header file for the extended initializer_list 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:1220
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:1950
Base template for the RowsTrait class.
Definition: RowsTrait.h:109
Type ElementType
Type of the matrix elements.
Definition: HybridMatrix.h:233
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:129
Header file for the band trait.
Constraint on the data type.
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:2417
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:1892
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: HybridMatrix.h:1743
Base template for the RowTrait class.
Definition: RowTrait.h:109
Compile time check for the memory layout of data types.This type trait tests whether the given data t...
Definition: IsContiguous.h:86
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:58
#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:5908
HybridMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: HybridMatrix.h:1318
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:2616
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:2547
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:240
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:566
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:975
Header file for the IsLower type trait.
size_t m_
The current number of rows of the matrix.
Definition: HybridMatrix.h:530
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:89
Type & Reference
Reference to a non-constant matrix value.
Definition: HybridMatrix.h:238
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: HybridMatrix.h:241
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:1797
Header file for the exception macros of the math module.
HybridMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: HybridMatrix.h:2056
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:261
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:608
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:2653
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:1959
Header file for the IsSIMDCombinable type trait.
AlignedArray< Type, M *NN > v_
The statically allocated matrix elements.
Definition: HybridMatrix.h:520
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:2578
#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:1083
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
Determines the maximum number of columns specified by the given initializer list. ...
Definition: InitializerList.h:107
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:119
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:2001
Base template for the MultTrait class.
Definition: MultTrait.h:119
const Type & ConstReference
Reference to a constant matrix value.
Definition: HybridMatrix.h:239
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:2511
Header file for the division trait.
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
Constraint on the data type.
Header file for the IsContiguous type trait.
Header file for the columns trait.
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:2375
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:228
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:816
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:2444
Base template for the DivTrait class.
Definition: DivTrait.h:120
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
Header file for the rows trait.
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
Generic wrapper for the min() function.
Definition: Min.h:62
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:251
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:244
Header file for the IsRowMajorMatrix type trait.
Base template for the ColumnsTrait class.
Definition: ColumnsTrait.h:109
Header file for the default transpose flag for all vectors of the Blaze library.
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:2474
size_t n_
The current number of columns of the matrix.
Definition: HybridMatrix.h:531
Header file for the IntegralConstant class template.
const Type & ReturnType
Return type for expression template evaluations.
Definition: HybridMatrix.h:235
void clear()
Clearing the hybrid matrix.
Definition: HybridMatrix.h:1845
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:628
Base template for the SubTrait class.
Definition: SubTrait.h:119
#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:1941
#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:97
Header file for the IsResizable type trait.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: HybridMatrix.h:1666
Base template for the UnaryMapTrait class.
Definition: UnaryMapTrait.h:95
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:1701
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: HybridMatrix.h:234
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: HybridMatrix.h:2397
bool isIntact() const noexcept
Returns whether the invariants of the hybrid matrix are intact.
Definition: HybridMatrix.h:2325
Header file for the HighType type trait.
Header file for the TrueType type/value trait base class.
Base template for the BandTrait class.
Definition: BandTrait.h:109