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>
88 #include <blaze/system/Inline.h>
93 #include <blaze/util/Assert.h>
100 #include <blaze/util/DisableIf.h>
101 #include <blaze/util/EnableIf.h>
103 #include <blaze/util/Memory.h>
104 #include <blaze/util/StaticAssert.h>
105 #include <blaze/util/Template.h>
106 #include <blaze/util/TrueType.h>
107 #include <blaze/util/Types.h>
111 #include <blaze/util/Unused.h>
112 
113 
114 namespace blaze {
115 
116 //=================================================================================================
117 //
118 // CLASS DEFINITION
119 //
120 //=================================================================================================
121 
122 //*************************************************************************************************
208 template< typename Type // Data type of the matrix
209  , size_t M // Number of rows
210  , size_t N // Number of columns
211  , bool SO = defaultStorageOrder > // Storage order
212 class HybridMatrix : public DenseMatrix< HybridMatrix<Type,M,N,SO>, SO >
213 {
214  public:
215  //**Type definitions****************************************************************************
218  typedef This ResultType;
221  typedef Type ElementType;
223  typedef const Type& ReturnType;
224  typedef const This& CompositeType;
225 
226  typedef Type& Reference;
227  typedef const Type& ConstReference;
228  typedef Type* Pointer;
229  typedef const Type* ConstPointer;
230 
233  //**********************************************************************************************
234 
235  //**Rebind struct definition********************************************************************
238  template< typename NewType > // Data type of the other matrix
239  struct Rebind {
241  };
242  //**********************************************************************************************
243 
244  //**Resize struct definition********************************************************************
247  template< size_t NewM // Number of rows of the other matrix
248  , size_t NewN > // Number of columns of the other matrix
249  struct Resize {
251  };
252  //**********************************************************************************************
253 
254  //**Compilation flags***************************************************************************
256 
260  enum : bool { simdEnabled = IsVectorizable<Type>::value };
261 
263 
266  enum : bool { smpAssignable = false };
267  //**********************************************************************************************
268 
269  //**Constructors********************************************************************************
272  explicit inline HybridMatrix();
273  explicit inline HybridMatrix( size_t m, size_t n );
274  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
275  explicit inline HybridMatrix( initializer_list< initializer_list<Type> > list );
276 
277  template< typename Other >
278  explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
279 
280  template< typename Other, size_t M2, size_t N2 >
281  explicit inline HybridMatrix( const Other (&array)[M2][N2] );
282 
283  inline HybridMatrix( const HybridMatrix& m );
284  template< typename MT, bool SO2 > inline HybridMatrix( const Matrix<MT,SO2>& m );
286  //**********************************************************************************************
287 
288  //**Destructor**********************************************************************************
289  // No explicitly declared destructor.
290  //**********************************************************************************************
291 
292  //**Data access functions***********************************************************************
295  inline Reference operator()( size_t i, size_t j ) noexcept;
296  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
297  inline Reference at( size_t i, size_t j );
298  inline ConstReference at( size_t i, size_t j ) const;
299  inline Pointer data () noexcept;
300  inline ConstPointer data () const noexcept;
301  inline Pointer data ( size_t i ) noexcept;
302  inline ConstPointer data ( size_t i ) const noexcept;
303  inline Iterator begin ( size_t i ) noexcept;
304  inline ConstIterator begin ( size_t i ) const noexcept;
305  inline ConstIterator cbegin( size_t i ) const noexcept;
306  inline Iterator end ( size_t i ) noexcept;
307  inline ConstIterator end ( size_t i ) const noexcept;
308  inline ConstIterator cend ( size_t i ) const noexcept;
310  //**********************************************************************************************
311 
312  //**Assignment operators************************************************************************
315  inline HybridMatrix& operator=( const Type& set );
316  inline HybridMatrix& operator=( initializer_list< initializer_list<Type> > list );
317 
318  template< typename Other, size_t M2, size_t N2 >
319  inline HybridMatrix& operator=( const Other (&array)[M2][N2] );
320 
321  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
322  template< typename MT, bool SO2 > inline HybridMatrix& operator= ( const Matrix<MT,SO2>& rhs );
323  template< typename MT, bool SO2 > inline HybridMatrix& operator+=( const Matrix<MT,SO2>& rhs );
324  template< typename MT, bool SO2 > inline HybridMatrix& operator-=( const Matrix<MT,SO2>& rhs );
325  template< typename MT, bool SO2 > inline HybridMatrix& operator*=( const Matrix<MT,SO2>& rhs );
326 
327  template< typename Other >
328  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator*=( Other rhs );
329 
330  template< typename Other >
331  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator/=( Other rhs );
333  //**********************************************************************************************
334 
335  //**Utility functions***************************************************************************
338  inline size_t rows() const noexcept;
339  inline size_t columns() const noexcept;
340  inline constexpr size_t spacing() const noexcept;
341  inline constexpr size_t capacity() const noexcept;
342  inline size_t capacity( size_t i ) const noexcept;
343  inline size_t nonZeros() const;
344  inline size_t nonZeros( size_t i ) const;
345  inline void reset();
346  inline void reset( size_t i );
347  inline void clear();
348  void resize ( size_t m, size_t n, bool preserve=true );
349  inline void extend ( size_t m, size_t n, bool preserve=true );
350  inline void swap( HybridMatrix& m ) noexcept;
352  //**********************************************************************************************
353 
354  //**Numeric functions***************************************************************************
357  inline HybridMatrix& transpose();
358  inline HybridMatrix& ctranspose();
359 
360  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
362  //**********************************************************************************************
363 
364  //**Memory functions****************************************************************************
367  static inline void* operator new ( std::size_t size );
368  static inline void* operator new[]( std::size_t size );
369  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
370  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
371 
372  static inline void operator delete ( void* ptr );
373  static inline void operator delete[]( void* ptr );
374  static inline void operator delete ( void* ptr, const std::nothrow_t& );
375  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
377  //**********************************************************************************************
378 
379  private:
380  //**********************************************************************************************
382  template< typename MT >
384  struct VectorizedAssign {
385  enum : bool { value = useOptimizedKernels &&
386  simdEnabled && MT::simdEnabled &&
389  };
391  //**********************************************************************************************
392 
393  //**********************************************************************************************
395  template< typename MT >
397  struct VectorizedAddAssign {
398  enum : bool { value = useOptimizedKernels &&
399  simdEnabled && MT::simdEnabled &&
404  };
406  //**********************************************************************************************
407 
408  //**********************************************************************************************
410  template< typename MT >
412  struct VectorizedSubAssign {
413  enum : bool { value = useOptimizedKernels &&
414  simdEnabled && MT::simdEnabled &&
419  };
421  //**********************************************************************************************
422 
423  //**********************************************************************************************
425  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
426  //**********************************************************************************************
427 
428  public:
429  //**Debugging functions*************************************************************************
432  inline bool isIntact() const noexcept;
434  //**********************************************************************************************
435 
436  //**Expression template evaluation functions****************************************************
439  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
440  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
441 
442  inline bool isAligned() const noexcept;
443 
444  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
445  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
446  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
447 
448  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
449  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
450  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
451  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
452 
453  template< typename MT, bool SO2 >
454  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
455 
456  template< typename MT, bool SO2 >
457  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
458 
459  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
460  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
461 
462  template< typename MT, bool SO2 >
463  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
464 
465  template< typename MT, bool SO2 >
466  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
467 
468  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
469  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
470 
471  template< typename MT, bool SO2 >
472  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
473 
474  template< typename MT, bool SO2 >
475  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
476 
477  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
478  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
480  //**********************************************************************************************
481 
482  private:
483  //**********************************************************************************************
485  enum : size_t { NN = ( usePadding )?( nextMultiple( N, SIMDSIZE ) ):( N ) };
486  //**********************************************************************************************
487 
488  //**Member variables****************************************************************************
492 
501  size_t m_;
502  size_t n_;
503 
504  //**********************************************************************************************
505 
506  //**Compile time checks*************************************************************************
512  BLAZE_STATIC_ASSERT( !usePadding || NN % SIMDSIZE == 0UL );
513  BLAZE_STATIC_ASSERT( NN >= N );
515  //**********************************************************************************************
516 };
517 //*************************************************************************************************
518 
519 
520 
521 
522 //=================================================================================================
523 //
524 // CONSTRUCTORS
525 //
526 //=================================================================================================
527 
528 //*************************************************************************************************
533 template< typename Type // Data type of the matrix
534  , size_t M // Number of rows
535  , size_t N // Number of columns
536  , bool SO > // Storage order
538  : v_() // The statically allocated matrix elements
539  , m_( 0UL ) // The current number of rows of the matrix
540  , n_( 0UL ) // The current number of columns of the matrix
541 {
543 
544  if( IsNumeric<Type>::value ) {
545  for( size_t i=0UL; i<M*NN; ++i )
546  v_[i] = Type();
547  }
548 
549  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
550 }
551 //*************************************************************************************************
552 
553 
554 //*************************************************************************************************
567 template< typename Type // Data type of the matrix
568  , size_t M // Number of rows
569  , size_t N // Number of columns
570  , bool SO > // Storage order
571 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n )
572  : v_() // The statically allocated matrix elements
573  , m_( m ) // The current number of rows of the matrix
574  , n_( n ) // The current number of columns of the matrix
575 {
577 
578  if( m > M ) {
579  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
580  }
581 
582  if( n > N ) {
583  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
584  }
585 
586  if( IsNumeric<Type>::value ) {
587  for( size_t i=0UL; i<M*NN; ++i )
588  v_[i] = Type();
589  }
590 
591  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
592 }
593 //*************************************************************************************************
594 
595 
596 //*************************************************************************************************
610 template< typename Type // Data type of the matrix
611  , size_t M // Number of rows
612  , size_t N // Number of columns
613  , bool SO > // Storage order
614 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Type& init )
615  : v_() // The statically allocated matrix elements
616  , m_( m ) // The current number of rows of the matrix
617  , n_( n ) // The current number of columns of the matrix
618 {
620 
621  if( m > M ) {
622  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
623  }
624 
625  if( n > N ) {
626  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
627  }
628 
629  for( size_t i=0UL; i<m; ++i ) {
630  for( size_t j=0UL; j<n; ++j )
631  v_[i*NN+j] = init;
632 
633  if( IsNumeric<Type>::value ) {
634  for( size_t j=n; j<NN; ++j )
635  v_[i*NN+j] = Type();
636  }
637  }
638 
639  if( IsNumeric<Type>::value ) {
640  for( size_t i=m; i<M; ++i )
641  for( size_t j=0UL; j<NN; ++j )
642  v_[i*NN+j] = Type();
643  }
644 
645  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
646 }
647 //*************************************************************************************************
648 
649 
650 //*************************************************************************************************
674 template< typename Type // Data type of the matrix
675  , size_t M // Number of rows
676  , size_t N // Number of columns
677  , bool SO > // Storage order
679  : v_() // The statically allocated matrix elements
680  , m_( list.size() ) // The current number of rows of the matrix
681  , n_( determineColumns( list ) ) // The current number of columns of the matrix
682 {
684 
685  if( m_ > M ) {
686  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
687  }
688 
689  if( n_ > N ) {
690  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
691  }
692 
693  size_t i( 0UL );
694 
695  for( const auto& rowList : list ) {
696  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
697  ++i;
698  }
699 
700  if( IsNumeric<Type>::value ) {
701  for( ; i<M; ++i )
702  for( size_t j=0UL; j<NN; ++j )
703  v_[i*NN+j] = Type();
704  }
705 
706  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
707 }
708 //*************************************************************************************************
709 
710 
711 //*************************************************************************************************
738 template< typename Type // Data type of the matrix
739  , size_t M // Number of rows
740  , size_t N // Number of columns
741  , bool SO > // Storage order
742 template< typename Other > // Data type of the initialization array
743 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Other* array )
744  : v_() // The statically allocated matrix elements
745  , m_( m ) // The current number of rows of the matrix
746  , n_( n ) // The current number of columns of the matrix
747 {
749 
750  if( m > M ) {
751  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
752  }
753 
754  if( n > N ) {
755  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
756  }
757 
758  for( size_t i=0UL; i<m; ++i ) {
759  for( size_t j=0UL; j<n; ++j )
760  v_[i*NN+j] = array[i*n+j];
761 
762  if( IsNumeric<Type>::value ) {
763  for( size_t j=n; j<NN; ++j )
764  v_[i*NN+j] = Type();
765  }
766  }
767 
768  if( IsNumeric<Type>::value ) {
769  for( size_t i=m; i<M; ++i )
770  for( size_t j=0UL; j<NN; ++j )
771  v_[i*NN+j] = Type();
772  }
773 
774  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
775 }
776 //*************************************************************************************************
777 
778 
779 //*************************************************************************************************
800 template< typename Type // Data type of the matrix
801  , size_t M // Number of rows
802  , size_t N // Number of columns
803  , bool SO > // Storage order
804 template< typename Other // Data type of the initialization array
805  , size_t M2 // Number of rows of the initialization array
806  , size_t N2 > // Number of columns of the initialization array
807 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( const Other (&array)[M2][N2] )
808  : v_() // The statically allocated matrix elements
809  , m_( M2 ) // The current number of rows of the matrix
810  , n_( N2 ) // The current number of columns of the matrix
811 {
812  BLAZE_STATIC_ASSERT( M2 <= M );
813  BLAZE_STATIC_ASSERT( N2 <= N );
815 
816  for( size_t i=0UL; i<M2; ++i ) {
817  for( size_t j=0UL; j<N2; ++j )
818  v_[i*NN+j] = array[i][j];
819 
820  if( IsNumeric<Type>::value ) {
821  for( size_t j=N2; j<NN; ++j )
822  v_[i*NN+j] = Type();
823  }
824  }
825 
826  if( IsNumeric<Type>::value ) {
827  for( size_t i=M2; i<M; ++i )
828  for( size_t j=0UL; j<NN; ++j )
829  v_[i*NN+j] = Type();
830  }
831 
832  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
833 }
834 //*************************************************************************************************
835 
836 
837 //*************************************************************************************************
845 template< typename Type // Data type of the matrix
846  , size_t M // Number of rows
847  , size_t N // Number of columns
848  , bool SO > // Storage order
850  : v_() // The statically allocated matrix elements
851  , m_( m.m_ ) // The current number of rows of the matrix
852  , n_( m.n_ ) // The current number of columns of the matrix
853 {
855 
856  for( size_t i=0UL; i<m_; ++i ) {
857  for( size_t j=0UL; j<n_; ++j )
858  v_[i*NN+j] = m.v_[i*NN+j];
859 
860  if( IsNumeric<Type>::value ) {
861  for( size_t j=n_; j<NN; ++j )
862  v_[i*NN+j] = Type();
863  }
864  }
865 
866  if( IsNumeric<Type>::value ) {
867  for( size_t i=m_; i<M; ++i )
868  for( size_t j=0UL; j<NN; ++j )
869  v_[i*NN+j] = Type();
870  }
871 
872  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
873 }
874 //*************************************************************************************************
875 
876 
877 //*************************************************************************************************
883 template< typename Type // Data type of the matrix
884  , size_t M // Number of rows
885  , size_t N // Number of columns
886  , bool SO > // Storage order
887 template< typename MT // Type of the foreign matrix
888  , bool SO2 > // Storage order of the foreign matrix
890  : v_() // The statically allocated matrix elements
891  , m_( (~m).rows() ) // The current number of rows of the matrix
892  , n_( (~m).columns() ) // The current number of columns of the matrix
893 {
894  using blaze::assign;
895 
897 
898  if( (~m).rows() > M || (~m).columns() > N ) {
899  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
900  }
901 
902  for( size_t i=0UL; i<m_; ++i ) {
903  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : n_ );
904  j<( IsNumeric<Type>::value ? NN : n_ );
905  ++j ) {
906  v_[i*NN+j] = Type();
907  }
908  }
909 
910  if( IsNumeric<Type>::value ) {
911  for( size_t i=m_; i<M; ++i )
912  for( size_t j=0UL; j<NN; ++j )
913  v_[i*NN+j] = Type();
914  }
915 
916  assign( *this, ~m );
917 
918  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
919 }
920 //*************************************************************************************************
921 
922 
923 
924 
925 //=================================================================================================
926 //
927 // DATA ACCESS FUNCTIONS
928 //
929 //=================================================================================================
930 
931 //*************************************************************************************************
941 template< typename Type // Data type of the matrix
942  , size_t M // Number of rows
943  , size_t N // Number of columns
944  , bool SO > // Storage order
946  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) noexcept
947 {
948  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
949  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
950  return v_[i*NN+j];
951 }
952 //*************************************************************************************************
953 
954 
955 //*************************************************************************************************
965 template< typename Type // Data type of the matrix
966  , size_t M // Number of rows
967  , size_t N // Number of columns
968  , bool SO > // Storage order
970  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const noexcept
971 {
972  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
973  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
974  return v_[i*NN+j];
975 }
976 //*************************************************************************************************
977 
978 
979 //*************************************************************************************************
990 template< typename Type // Data type of the matrix
991  , size_t M // Number of rows
992  , size_t N // Number of columns
993  , bool SO > // Storage order
995  HybridMatrix<Type,M,N,SO>::at( size_t i, size_t j )
996 {
997  if( i >= m_ ) {
998  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
999  }
1000  if( j >= n_ ) {
1001  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1002  }
1003  return (*this)(i,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 ) const
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 //*************************************************************************************************
1049 template< typename Type // Data type of the matrix
1050  , size_t M // Number of rows
1051  , size_t N // Number of columns
1052  , bool SO > // Storage order
1053 inline typename HybridMatrix<Type,M,N,SO>::Pointer
1055 {
1056  return v_;
1057 }
1058 //*************************************************************************************************
1059 
1060 
1061 //*************************************************************************************************
1073 template< typename Type // Data type of the matrix
1074  , size_t M // Number of rows
1075  , size_t N // Number of columns
1076  , bool SO > // Storage order
1079 {
1080  return v_;
1081 }
1082 //*************************************************************************************************
1083 
1084 
1085 //*************************************************************************************************
1093 template< typename Type // Data type of the matrix
1094  , size_t M // Number of rows
1095  , size_t N // Number of columns
1096  , bool SO > // Storage order
1097 inline typename HybridMatrix<Type,M,N,SO>::Pointer
1098  HybridMatrix<Type,M,N,SO>::data( size_t i ) noexcept
1099 {
1100  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1101  return v_ + i*NN;
1102 }
1103 //*************************************************************************************************
1104 
1105 
1106 //*************************************************************************************************
1114 template< typename Type // Data type of the matrix
1115  , size_t M // Number of rows
1116  , size_t N // Number of columns
1117  , bool SO > // Storage order
1119  HybridMatrix<Type,M,N,SO>::data( size_t i ) const noexcept
1120 {
1121  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1122  return v_ + i*NN;
1123 }
1124 //*************************************************************************************************
1125 
1126 
1127 //*************************************************************************************************
1138 template< typename Type // Data type of the matrix
1139  , size_t M // Number of rows
1140  , size_t N // Number of columns
1141  , bool SO > // Storage order
1144 {
1145  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1146  return Iterator( v_ + i*NN );
1147 }
1148 //*************************************************************************************************
1149 
1150 
1151 //*************************************************************************************************
1162 template< typename Type // Data type of the matrix
1163  , size_t M // Number of rows
1164  , size_t N // Number of columns
1165  , bool SO > // Storage order
1167  HybridMatrix<Type,M,N,SO>::begin( size_t i ) const noexcept
1168 {
1169  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1170  return ConstIterator( v_ + i*NN );
1171 }
1172 //*************************************************************************************************
1173 
1174 
1175 //*************************************************************************************************
1186 template< typename Type // Data type of the matrix
1187  , size_t M // Number of rows
1188  , size_t N // Number of columns
1189  , bool SO > // Storage order
1191  HybridMatrix<Type,M,N,SO>::cbegin( size_t i ) const noexcept
1192 {
1193  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1194  return ConstIterator( v_ + i*NN );
1195 }
1196 //*************************************************************************************************
1197 
1198 
1199 //*************************************************************************************************
1210 template< typename Type // Data type of the matrix
1211  , size_t M // Number of rows
1212  , size_t N // Number of columns
1213  , bool SO > // Storage order
1215  HybridMatrix<Type,M,N,SO>::end( size_t i ) noexcept
1216 {
1217  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1218  return Iterator( v_ + i*NN + N );
1219 }
1220 //*************************************************************************************************
1221 
1222 
1223 //*************************************************************************************************
1234 template< typename Type // Data type of the matrix
1235  , size_t M // Number of rows
1236  , size_t N // Number of columns
1237  , bool SO > // Storage order
1239  HybridMatrix<Type,M,N,SO>::end( size_t i ) const noexcept
1240 {
1241  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1242  return ConstIterator( v_ + i*NN + N );
1243 }
1244 //*************************************************************************************************
1245 
1246 
1247 //*************************************************************************************************
1258 template< typename Type // Data type of the matrix
1259  , size_t M // Number of rows
1260  , size_t N // Number of columns
1261  , bool SO > // Storage order
1263  HybridMatrix<Type,M,N,SO>::cend( size_t i ) const noexcept
1264 {
1265  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1266  return ConstIterator( v_ + i*NN + N );
1267 }
1268 //*************************************************************************************************
1269 
1270 
1271 
1272 
1273 //=================================================================================================
1274 //
1275 // ASSIGNMENT OPERATORS
1276 //
1277 //=================================================================================================
1278 
1279 //*************************************************************************************************
1285 template< typename Type // Data type of the matrix
1286  , size_t M // Number of rows
1287  , size_t N // Number of columns
1288  , bool SO > // Storage order
1290 {
1291  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1292  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1293 
1294  for( size_t i=0UL; i<m_; ++i )
1295  for( size_t j=0UL; j<n_; ++j )
1296  v_[i*NN+j] = set;
1297 
1298  return *this;
1299 }
1300 //*************************************************************************************************
1301 
1302 
1303 //*************************************************************************************************
1328 template< typename Type // Data type of the matrix
1329  , size_t M // Number of rows
1330  , size_t N // Number of columns
1331  , bool SO > // Storage order
1334 {
1335  const size_t m( list.size() );
1336  const size_t n( determineColumns( list ) );
1337 
1338  if( m > M ) {
1339  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1340  }
1341 
1342  if( n > N ) {
1343  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1344  }
1345 
1346  resize( m, n, false );
1347 
1348  size_t i( 0UL );
1349 
1350  for( const auto& rowList : list ) {
1351  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
1352  ++i;
1353  }
1354 
1355  return *this;
1356 }
1357 //*************************************************************************************************
1358 
1359 
1360 //*************************************************************************************************
1381 template< typename Type // Data type of the matrix
1382  , size_t M // Number of rows
1383  , size_t N // Number of columns
1384  , bool SO > // Storage order
1385 template< typename Other // Data type of the initialization array
1386  , size_t M2 // Number of rows of the initialization array
1387  , size_t N2 > // Number of columns of the initialization array
1389 {
1390  BLAZE_STATIC_ASSERT( M2 <= M );
1391  BLAZE_STATIC_ASSERT( N2 <= N );
1392 
1393  resize( M2, N2 );
1394 
1395  for( size_t i=0UL; i<M2; ++i )
1396  for( size_t j=0UL; j<N2; ++j )
1397  v_[i*NN+j] = array[i][j];
1398 
1399  return *this;
1400 }
1401 //*************************************************************************************************
1402 
1403 
1404 //*************************************************************************************************
1412 template< typename Type // Data type of the matrix
1413  , size_t M // Number of rows
1414  , size_t N // Number of columns
1415  , bool SO > // Storage order
1417 {
1418  using blaze::assign;
1419 
1420  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1421  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1422 
1423  resize( rhs.rows(), rhs.columns() );
1424  assign( *this, ~rhs );
1425 
1426  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1427 
1428  return *this;
1429 }
1430 //*************************************************************************************************
1431 
1432 
1433 //*************************************************************************************************
1444 template< typename Type // Data type of the matrix
1445  , size_t M // Number of rows
1446  , size_t N // Number of columns
1447  , bool SO > // Storage order
1448 template< typename MT // Type of the right-hand side matrix
1449  , bool SO2 > // Storage order of the right-hand side matrix
1451 {
1452  using blaze::assign;
1453 
1454  typedef TransExprTrait_<This> TT;
1455  typedef CTransExprTrait_<This> CT;
1456  typedef InvExprTrait_<This> IT;
1457 
1458  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
1459  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
1460  }
1461 
1462  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1463  transpose();
1464  }
1465  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1466  ctranspose();
1467  }
1468  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1469  HybridMatrix tmp( ~rhs );
1470  resize( tmp.rows(), tmp.columns() );
1471  assign( *this, tmp );
1472  }
1473  else {
1474  resize( (~rhs).rows(), (~rhs).columns() );
1476  reset();
1477  assign( *this, ~rhs );
1478  }
1479 
1480  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1481 
1482  return *this;
1483 }
1484 //*************************************************************************************************
1485 
1486 
1487 //*************************************************************************************************
1497 template< typename Type // Data type of the matrix
1498  , size_t M // Number of rows
1499  , size_t N // Number of columns
1500  , bool SO > // Storage order
1501 template< typename MT // Type of the right-hand side matrix
1502  , bool SO2 > // Storage order of the right-hand side matrix
1504 {
1505  using blaze::addAssign;
1506 
1507  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1508  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1509  }
1510 
1511  if( (~rhs).canAlias( this ) ) {
1512  const ResultType_<MT> tmp( ~rhs );
1513  addAssign( *this, tmp );
1514  }
1515  else {
1516  addAssign( *this, ~rhs );
1517  }
1518 
1519  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1520 
1521  return *this;
1522 }
1523 //*************************************************************************************************
1524 
1525 
1526 //*************************************************************************************************
1536 template< typename Type // Data type of the matrix
1537  , size_t M // Number of rows
1538  , size_t N // Number of columns
1539  , bool SO > // Storage order
1540 template< typename MT // Type of the right-hand side matrix
1541  , bool SO2 > // Storage order of the right-hand side matrix
1543 {
1544  using blaze::subAssign;
1545 
1546  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1547  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1548  }
1549 
1550  if( (~rhs).canAlias( this ) ) {
1551  const ResultType_<MT> tmp( ~rhs );
1552  subAssign( *this, tmp );
1553  }
1554  else {
1555  subAssign( *this, ~rhs );
1556  }
1557 
1558  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1559 
1560  return *this;
1561 }
1562 //*************************************************************************************************
1563 
1564 
1565 //*************************************************************************************************
1575 template< typename Type // Data type of the matrix
1576  , size_t M // Number of rows
1577  , size_t N // Number of columns
1578  , bool SO > // Storage order
1579 template< typename MT // Type of the right-hand side matrix
1580  , bool SO2 > // Storage order of the right-hand side matrix
1582 {
1583  if( n_ != (~rhs).rows() || (~rhs).columns() > N ) {
1584  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1585  }
1586 
1587  const HybridMatrix tmp( *this * (~rhs) );
1588  this->operator=( tmp );
1589 
1590  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1591 
1592  return *this;
1593 }
1594 //*************************************************************************************************
1595 
1596 
1597 //*************************************************************************************************
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 Other > // Data type of the right-hand side scalar
1611 {
1612  using blaze::assign;
1613 
1614  assign( *this, (*this) * rhs );
1615 
1616  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1617 
1618  return *this;
1619 }
1620 //*************************************************************************************************
1621 
1622 
1623 //*************************************************************************************************
1632 template< typename Type // Data type of the matrix
1633  , size_t M // Number of rows
1634  , size_t N // Number of columns
1635  , bool SO > // Storage order
1636 template< typename Other > // Data type of the right-hand side scalar
1637 inline EnableIf_<IsNumeric<Other>, HybridMatrix<Type,M,N,SO> >&
1639 {
1640  using blaze::assign;
1641 
1642  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1643 
1644  assign( *this, (*this) / rhs );
1645 
1646  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1647 
1648  return *this;
1649 }
1650 //*************************************************************************************************
1651 
1652 
1653 
1654 
1655 //=================================================================================================
1656 //
1657 // UTILITY FUNCTIONS
1658 //
1659 //=================================================================================================
1660 
1661 //*************************************************************************************************
1666 template< typename Type // Data type of the matrix
1667  , size_t M // Number of rows
1668  , size_t N // Number of columns
1669  , bool SO > // Storage order
1670 inline size_t HybridMatrix<Type,M,N,SO>::rows() const noexcept
1671 {
1672  return m_;
1673 }
1674 //*************************************************************************************************
1675 
1676 
1677 //*************************************************************************************************
1682 template< typename Type // Data type of the matrix
1683  , size_t M // Number of rows
1684  , size_t N // Number of columns
1685  , bool SO > // Storage order
1686 inline size_t HybridMatrix<Type,M,N,SO>::columns() const noexcept
1687 {
1688  return n_;
1689 }
1690 //*************************************************************************************************
1691 
1692 
1693 //*************************************************************************************************
1701 template< typename Type // Data type of the matrix
1702  , size_t M // Number of rows
1703  , size_t N // Number of columns
1704  , bool SO > // Storage order
1705 inline constexpr size_t HybridMatrix<Type,M,N,SO>::spacing() const noexcept
1706 {
1707  return NN;
1708 }
1709 //*************************************************************************************************
1710 
1711 
1712 //*************************************************************************************************
1717 template< typename Type // Data type of the matrix
1718  , size_t M // Number of rows
1719  , size_t N // Number of columns
1720  , bool SO > // Storage order
1721 inline constexpr size_t HybridMatrix<Type,M,N,SO>::capacity() const noexcept
1722 {
1723  return M*NN;
1724 }
1725 //*************************************************************************************************
1726 
1727 
1728 //*************************************************************************************************
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
1743 inline size_t HybridMatrix<Type,M,N,SO>::capacity( size_t i ) const noexcept
1744 {
1745  UNUSED_PARAMETER( i );
1746 
1747  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1748 
1749  return NN;
1750 }
1751 //*************************************************************************************************
1752 
1753 
1754 //*************************************************************************************************
1759 template< typename Type // Data type of the matrix
1760  , size_t M // Number of rows
1761  , size_t N // Number of columns
1762  , bool SO > // Storage order
1764 {
1765  size_t nonzeros( 0UL );
1766 
1767  for( size_t i=0UL; i<m_; ++i )
1768  for( size_t j=0UL; j<n_; ++j )
1769  if( !isDefault( v_[i*NN+j] ) )
1770  ++nonzeros;
1771 
1772  return nonzeros;
1773 }
1774 //*************************************************************************************************
1775 
1776 
1777 //*************************************************************************************************
1788 template< typename Type // Data type of the matrix
1789  , size_t M // Number of rows
1790  , size_t N // Number of columns
1791  , bool SO > // Storage order
1792 inline size_t HybridMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1793 {
1794  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1795 
1796  const size_t jend( i*NN + n_ );
1797  size_t nonzeros( 0UL );
1798 
1799  for( size_t j=i*NN; j<jend; ++j )
1800  if( !isDefault( v_[j] ) )
1801  ++nonzeros;
1802 
1803  return nonzeros;
1804 }
1805 //*************************************************************************************************
1806 
1807 
1808 //*************************************************************************************************
1813 template< typename Type // Data type of the matrix
1814  , size_t M // Number of rows
1815  , size_t N // Number of columns
1816  , bool SO > // Storage order
1818 {
1819  using blaze::clear;
1820 
1821  for( size_t i=0UL; i<m_; ++i )
1822  for( size_t j=0UL; j<n_; ++j )
1823  clear( v_[i*NN+j] );
1824 }
1825 //*************************************************************************************************
1826 
1827 
1828 //*************************************************************************************************
1839 template< typename Type // Data type of the matrix
1840  , size_t M // Number of rows
1841  , size_t N // Number of columns
1842  , bool SO > // Storage order
1843 inline void HybridMatrix<Type,M,N,SO>::reset( size_t i )
1844 {
1845  using blaze::clear;
1846 
1847  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1848  for( size_t j=0UL; j<n_; ++j )
1849  clear( v_[i*NN+j] );
1850 }
1851 //*************************************************************************************************
1852 
1853 
1854 //*************************************************************************************************
1861 template< typename Type // Data type of the matrix
1862  , size_t M // Number of rows
1863  , size_t N // Number of columns
1864  , bool SO > // Storage order
1866 {
1867  resize( 0UL, 0UL );
1868 }
1869 //*************************************************************************************************
1870 
1871 
1872 //*************************************************************************************************
1908 template< typename Type // Data type of the matrix
1909  , size_t M // Number of rows
1910  , size_t N // Number of columns
1911  , bool SO > // Storage order
1912 void HybridMatrix<Type,M,N,SO>::resize( size_t m, size_t n, bool preserve )
1913 {
1914  UNUSED_PARAMETER( preserve );
1915 
1916  if( m > M ) {
1917  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1918  }
1919 
1920  if( n > N ) {
1921  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1922  }
1923 
1924  if( IsVectorizable<Type>::value && n < n_ ) {
1925  for( size_t i=0UL; i<m; ++i )
1926  for( size_t j=n; j<n_; ++j )
1927  v_[i*NN+j] = Type();
1928  }
1929 
1930  if( IsVectorizable<Type>::value && m < m_ ) {
1931  for( size_t i=m; i<m_; ++i )
1932  for( size_t j=0UL; j<n_; ++j )
1933  v_[i*NN+j] = Type();
1934  }
1935 
1936  m_ = m;
1937  n_ = n;
1938 }
1939 //*************************************************************************************************
1940 
1941 
1942 //*************************************************************************************************
1957 template< typename Type // Data type of the matrix
1958  , size_t M // Number of rows
1959  , size_t N // Number of columns
1960  , bool SO > // Storage order
1961 inline void HybridMatrix<Type,M,N,SO>::extend( size_t m, size_t n, bool preserve )
1962 {
1963  UNUSED_PARAMETER( preserve );
1964  resize( m_+m, n_+n );
1965 }
1966 //*************************************************************************************************
1967 
1968 
1969 //*************************************************************************************************
1975 template< typename Type // Data type of the matrix
1976  , size_t M // Number of rows
1977  , size_t N // Number of columns
1978  , bool SO > // Storage order
1980 {
1981  using std::swap;
1982 
1983  const size_t maxrows( max( m_, m.m_ ) );
1984  const size_t maxcols( max( n_, m.n_ ) );
1985 
1986  for( size_t i=0UL; i<maxrows; ++i ) {
1987  for( size_t j=0UL; j<maxcols; ++j ) {
1988  swap( v_[i*NN+j], m(i,j) );
1989  }
1990  }
1991 
1992  swap( m_, m.m_ );
1993  swap( n_, m.n_ );
1994 }
1995 //*************************************************************************************************
1996 
1997 
1998 
1999 
2000 //=================================================================================================
2001 //
2002 // NUMERIC FUNCTIONS
2003 //
2004 //=================================================================================================
2005 
2006 //*************************************************************************************************
2017 template< typename Type // Data type of the matrix
2018  , size_t M // Number of rows
2019  , size_t N // Number of columns
2020  , bool SO > // Storage order
2022 {
2023  using std::swap;
2024 
2025  if( m_ > N || n_ > M ) {
2026  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2027  }
2028 
2029  const size_t maxsize( max( m_, n_ ) );
2030  for( size_t i=1UL; i<maxsize; ++i ) {
2031  for( size_t j=0UL; j<i; ++j ) {
2032  swap( v_[i*NN+j], v_[j*NN+i] );
2033  }
2034  }
2035 
2036  if( IsVectorizable<Type>::value && m_ < n_ ) {
2037  for( size_t i=0UL; i<m_; ++i ) {
2038  for( size_t j=m_; j<n_; ++j ) {
2039  v_[i*NN+j] = Type();
2040  }
2041  }
2042  }
2043 
2044  if( IsVectorizable<Type>::value && m_ > n_ ) {
2045  for( size_t i=n_; i<m_; ++i ) {
2046  for( size_t j=0UL; j<n_; ++j ) {
2047  v_[i*NN+j] = Type();
2048  }
2049  }
2050  }
2051 
2052  swap( m_, n_ );
2053 
2054  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2055 
2056  return *this;
2057 }
2058 //*************************************************************************************************
2059 
2060 
2061 //*************************************************************************************************
2072 template< typename Type // Data type of the matrix
2073  , size_t M // Number of rows
2074  , size_t N // Number of columns
2075  , bool SO > // Storage order
2077 {
2078  using std::swap;
2079 
2080  if( m_ > N || n_ > M ) {
2081  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2082  }
2083 
2084  const size_t maxsize( max( m_, n_ ) );
2085  for( size_t i=0UL; i<maxsize; ++i ) {
2086  for( size_t j=0UL; j<i; ++j ) {
2087  cswap( v_[i*NN+j], v_[j*NN+i] );
2088  }
2089  conjugate( v_[i*NN+i] );
2090  }
2091 
2092  if( IsVectorizable<Type>::value && m_ < n_ ) {
2093  for( size_t i=0UL; i<m_; ++i ) {
2094  for( size_t j=m_; j<n_; ++j ) {
2095  v_[i*NN+j] = Type();
2096  }
2097  }
2098  }
2099 
2100  if( IsVectorizable<Type>::value && m_ > n_ ) {
2101  for( size_t i=n_; i<m_; ++i ) {
2102  for( size_t j=0UL; j<n_; ++j ) {
2103  v_[i*NN+j] = Type();
2104  }
2105  }
2106  }
2107 
2108  swap( m_, n_ );
2109 
2110  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2111 
2112  return *this;
2113 }
2114 //*************************************************************************************************
2115 
2116 
2117 //*************************************************************************************************
2123 template< typename Type // Data type of the matrix
2124  , size_t M // Number of rows
2125  , size_t N // Number of columns
2126  , bool SO > // Storage order
2127 template< typename Other > // Data type of the scalar value
2129 {
2130  for( size_t i=0UL; i<m_; ++i )
2131  for( size_t j=0UL; j<n_; ++j )
2132  v_[i*NN+j] *= scalar;
2133 
2134  return *this;
2135 }
2136 //*************************************************************************************************
2137 
2138 
2139 
2140 
2141 //=================================================================================================
2142 //
2143 // MEMORY FUNCTIONS
2144 //
2145 //=================================================================================================
2146 
2147 //*************************************************************************************************
2157 template< typename Type // Data type of the matrix
2158  , size_t M // Number of rows
2159  , size_t N // Number of columns
2160  , bool SO > // Storage order
2161 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size )
2162 {
2164 
2165  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2166 
2167  return allocate<HybridMatrix>( 1UL );
2168 }
2169 //*************************************************************************************************
2170 
2171 
2172 //*************************************************************************************************
2182 template< typename Type // Data type of the matrix
2183  , size_t M // Number of rows
2184  , size_t N // Number of columns
2185  , bool SO > // Storage order
2186 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
2187 {
2188  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2189  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2190 
2191  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2192 }
2193 //*************************************************************************************************
2194 
2195 
2196 //*************************************************************************************************
2206 template< typename Type // Data type of the matrix
2207  , size_t M // Number of rows
2208  , size_t N // Number of columns
2209  , bool SO > // Storage order
2210 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
2211 {
2212  UNUSED_PARAMETER( size );
2213 
2214  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2215 
2216  return allocate<HybridMatrix>( 1UL );
2217 }
2218 //*************************************************************************************************
2219 
2220 
2221 //*************************************************************************************************
2231 template< typename Type // Data type of the matrix
2232  , size_t M // Number of rows
2233  , size_t N // Number of columns
2234  , bool SO > // Storage order
2235 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2236 {
2237  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2238  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2239 
2240  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2241 }
2242 //*************************************************************************************************
2243 
2244 
2245 //*************************************************************************************************
2251 template< typename Type // Data type of the matrix
2252  , size_t M // Number of rows
2253  , size_t N // Number of columns
2254  , bool SO > // Storage order
2255 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr )
2256 {
2257  deallocate( static_cast<HybridMatrix*>( ptr ) );
2258 }
2259 //*************************************************************************************************
2260 
2261 
2262 //*************************************************************************************************
2268 template< typename Type // Data type of the matrix
2269  , size_t M // Number of rows
2270  , size_t N // Number of columns
2271  , bool SO > // Storage order
2272 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2273 {
2274  deallocate( static_cast<HybridMatrix*>( ptr ) );
2275 }
2276 //*************************************************************************************************
2277 
2278 
2279 //*************************************************************************************************
2285 template< typename Type // Data type of the matrix
2286  , size_t M // Number of rows
2287  , size_t N // Number of columns
2288  , bool SO > // Storage order
2289 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2290 {
2291  deallocate( static_cast<HybridMatrix*>( ptr ) );
2292 }
2293 //*************************************************************************************************
2294 
2295 
2296 //*************************************************************************************************
2302 template< typename Type // Data type of the matrix
2303  , size_t M // Number of rows
2304  , size_t N // Number of columns
2305  , bool SO > // Storage order
2306 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2307 {
2308  deallocate( static_cast<HybridMatrix*>( ptr ) );
2309 }
2310 //*************************************************************************************************
2311 
2312 
2313 
2314 
2315 //=================================================================================================
2316 //
2317 // DEBUGGING FUNCTIONS
2318 //
2319 //=================================================================================================
2320 
2321 //*************************************************************************************************
2330 template< typename Type // Data type of the matrix
2331  , size_t M // Number of rows
2332  , size_t N // Number of columns
2333  , bool SO > // Storage order
2334 inline bool HybridMatrix<Type,M,N,SO>::isIntact() const noexcept
2335 {
2336  if( m_ > M || n_ > N )
2337  return false;
2338 
2340  {
2341  for( size_t i=0UL; i<m_; ++i ) {
2342  for( size_t j=n_; j<NN; ++j ) {
2343  if( v_[i*NN+j] != Type() )
2344  return false;
2345  }
2346  }
2347 
2348  for( size_t i=m_; i<M; ++i ) {
2349  for( size_t j=0UL; j<NN; ++j ) {
2350  if( v_[i*NN+j] != Type() )
2351  return false;
2352  }
2353  }
2354  }
2355 
2356  return true;
2357 }
2358 //*************************************************************************************************
2359 
2360 
2361 
2362 
2363 //=================================================================================================
2364 //
2365 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2366 //
2367 //=================================================================================================
2368 
2369 //*************************************************************************************************
2379 template< typename Type // Data type of the matrix
2380  , size_t M // Number of rows
2381  , size_t N // Number of columns
2382  , bool SO > // Storage order
2383 template< typename Other > // Data type of the foreign expression
2384 inline bool HybridMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const noexcept
2385 {
2386  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2387 }
2388 //*************************************************************************************************
2389 
2390 
2391 //*************************************************************************************************
2401 template< typename Type // Data type of the matrix
2402  , size_t M // Number of rows
2403  , size_t N // Number of columns
2404  , bool SO > // Storage order
2405 template< typename Other > // Data type of the foreign expression
2406 inline bool HybridMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const noexcept
2407 {
2408  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2409 }
2410 //*************************************************************************************************
2411 
2412 
2413 //*************************************************************************************************
2422 template< typename Type // Data type of the matrix
2423  , size_t M // Number of rows
2424  , size_t N // Number of columns
2425  , bool SO > // Storage order
2426 inline bool HybridMatrix<Type,M,N,SO>::isAligned() const noexcept
2427 {
2428  return ( usePadding || columns() % SIMDSIZE == 0UL );
2429 }
2430 //*************************************************************************************************
2431 
2432 
2433 //*************************************************************************************************
2448 template< typename Type // Data type of the matrix
2449  , size_t M // Number of rows
2450  , size_t N // Number of columns
2451  , bool SO > // Storage order
2453  HybridMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const noexcept
2454 {
2455  if( usePadding )
2456  return loada( i, j );
2457  else
2458  return loadu( i, j );
2459 }
2460 //*************************************************************************************************
2461 
2462 
2463 //*************************************************************************************************
2478 template< typename Type // Data type of the matrix
2479  , size_t M // Number of rows
2480  , size_t N // Number of columns
2481  , bool SO > // Storage order
2483  HybridMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const noexcept
2484 {
2485  using blaze::loada;
2486 
2488 
2489  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2490  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2491  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2492  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2493  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2494 
2495  return loada( &v_[i*NN+j] );
2496 }
2497 //*************************************************************************************************
2498 
2499 
2500 //*************************************************************************************************
2515 template< typename Type // Data type of the matrix
2516  , size_t M // Number of rows
2517  , size_t N // Number of columns
2518  , bool SO > // Storage order
2520  HybridMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const noexcept
2521 {
2522  using blaze::loadu;
2523 
2525 
2526  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2527  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2528  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2529 
2530  return loadu( &v_[i*NN+j] );
2531 }
2532 //*************************************************************************************************
2533 
2534 
2535 //*************************************************************************************************
2551 template< typename Type // Data type of the matrix
2552  , size_t M // Number of rows
2553  , size_t N // Number of columns
2554  , bool SO > // Storage order
2556  HybridMatrix<Type,M,N,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2557 {
2558  if( usePadding )
2559  storea( i, j, value );
2560  else
2561  storeu( i, j, value );
2562 }
2563 //*************************************************************************************************
2564 
2565 
2566 //*************************************************************************************************
2582 template< typename Type // Data type of the matrix
2583  , size_t M // Number of rows
2584  , size_t N // Number of columns
2585  , bool SO > // Storage order
2587  HybridMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2588 {
2589  using blaze::storea;
2590 
2592 
2593  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2594  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2595  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2596  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2597  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2598 
2599  storea( &v_[i*NN+j], value );
2600 }
2601 //*************************************************************************************************
2602 
2603 
2604 //*************************************************************************************************
2620 template< typename Type // Data type of the matrix
2621  , size_t M // Number of rows
2622  , size_t N // Number of columns
2623  , bool SO > // Storage order
2625  HybridMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2626 {
2627  using blaze::storeu;
2628 
2630 
2631  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2632  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2633  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2634 
2635  storeu( &v_[i*NN+j], value );
2636 }
2637 //*************************************************************************************************
2638 
2639 
2640 //*************************************************************************************************
2657 template< typename Type // Data type of the matrix
2658  , size_t M // Number of rows
2659  , size_t N // Number of columns
2660  , bool SO > // Storage order
2662  HybridMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2663 {
2664  using blaze::stream;
2665 
2667 
2668  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2669  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2670  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2671  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2672  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2673 
2674  stream( &v_[i*NN+j], value );
2675 }
2676 //*************************************************************************************************
2677 
2678 
2679 //*************************************************************************************************
2690 template< typename Type // Data type of the matrix
2691  , size_t M // Number of rows
2692  , size_t N // Number of columns
2693  , bool SO > // Storage order
2694 template< typename MT // Type of the right-hand side dense matrix
2695  , bool SO2 > // Storage order of the right-hand side dense matrix
2698 {
2699  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2700 
2701  for( size_t i=0UL; i<m_; ++i ) {
2702  for( size_t j=0UL; j<n_; ++j ) {
2703  v_[i*NN+j] = (~rhs)(i,j);
2704  }
2705  }
2706 }
2707 //*************************************************************************************************
2708 
2709 
2710 //*************************************************************************************************
2721 template< typename Type // Data type of the matrix
2722  , size_t M // Number of rows
2723  , size_t N // Number of columns
2724  , bool SO > // Storage order
2725 template< typename MT // Type of the right-hand side dense matrix
2726  , bool SO2 > // Storage order of the right-hand side dense matrix
2729 {
2731 
2732  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2733 
2734  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2735 
2736  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2737  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2738 
2739  for( size_t i=0UL; i<m_; ++i )
2740  {
2741  size_t j( 0UL );
2742 
2743  for( ; j<jpos; j+=SIMDSIZE ) {
2744  store( i, j, (~rhs).load(i,j) );
2745  }
2746  for( ; remainder && j<n_; ++j ) {
2747  v_[i*NN+j] = (~rhs)(i,j);
2748  }
2749  }
2750 }
2751 //*************************************************************************************************
2752 
2753 
2754 //*************************************************************************************************
2765 template< typename Type // Data type of the matrix
2766  , size_t M // Number of rows
2767  , size_t N // Number of columns
2768  , bool SO > // Storage order
2769 template< typename MT > // Type of the right-hand side sparse matrix
2771 {
2772  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2773 
2774  for( size_t i=0UL; i<m_; ++i )
2775  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2776  v_[i*NN+element->index()] = element->value();
2777 }
2778 //*************************************************************************************************
2779 
2780 
2781 //*************************************************************************************************
2792 template< typename Type // Data type of the matrix
2793  , size_t M // Number of rows
2794  , size_t N // Number of columns
2795  , bool SO > // Storage order
2796 template< typename MT > // Type of the right-hand side sparse matrix
2798 {
2800 
2801  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2802 
2803  for( size_t j=0UL; j<n_; ++j )
2804  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2805  v_[element->index()*NN+j] = element->value();
2806 }
2807 //*************************************************************************************************
2808 
2809 
2810 //*************************************************************************************************
2821 template< typename Type // Data type of the matrix
2822  , size_t M // Number of rows
2823  , size_t N // Number of columns
2824  , bool SO > // Storage order
2825 template< typename MT // Type of the right-hand side dense matrix
2826  , bool SO2 > // Storage order of the right-hand side dense matrix
2829 {
2830  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2831 
2832  for( size_t i=0UL; i<m_; ++i )
2833  {
2834  if( IsDiagonal<MT>::value )
2835  {
2836  v_[i*NN+i] += (~rhs)(i,i);
2837  }
2838  else
2839  {
2840  const size_t jbegin( ( IsUpper<MT>::value )
2841  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2842  :( 0UL ) );
2843  const size_t jend ( ( IsLower<MT>::value )
2844  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2845  :( n_ ) );
2846  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2847 
2848  for( size_t j=jbegin; j<jend; ++j ) {
2849  v_[i*NN+j] += (~rhs)(i,j);
2850  }
2851  }
2852  }
2853 }
2854 //*************************************************************************************************
2855 
2856 
2857 //*************************************************************************************************
2868 template< typename Type // Data type of the matrix
2869  , size_t M // Number of rows
2870  , size_t N // Number of columns
2871  , bool SO > // Storage order
2872 template< typename MT // Type of the right-hand side dense matrix
2873  , bool SO2 > // Storage order of the right-hand side dense matrix
2874 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2876 {
2879 
2880  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2881 
2882  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
2883 
2884  for( size_t i=0UL; i<m_; ++i )
2885  {
2886  const size_t jbegin( ( IsUpper<MT>::value )
2887  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2888  :( 0UL ) );
2889  const size_t jend ( ( IsLower<MT>::value )
2890  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2891  :( n_ ) );
2892  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2893 
2894  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2895  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2896 
2897  size_t j( jbegin );
2898 
2899  for( ; j<jpos; j+=SIMDSIZE ) {
2900  store( i, j, load(i,j) + (~rhs).load(i,j) );
2901  }
2902  for( ; remainder && j<jend; ++j ) {
2903  v_[i*NN+j] += (~rhs)(i,j);
2904  }
2905  }
2906 }
2907 //*************************************************************************************************
2908 
2909 
2910 //*************************************************************************************************
2921 template< typename Type // Data type of the matrix
2922  , size_t M // Number of rows
2923  , size_t N // Number of columns
2924  , bool SO > // Storage order
2925 template< typename MT > // Type of the right-hand side sparse matrix
2927 {
2928  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2929 
2930  for( size_t i=0UL; i<m_; ++i )
2931  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2932  v_[i*NN+element->index()] += element->value();
2933 }
2934 //*************************************************************************************************
2935 
2936 
2937 //*************************************************************************************************
2948 template< typename Type // Data type of the matrix
2949  , size_t M // Number of rows
2950  , size_t N // Number of columns
2951  , bool SO > // Storage order
2952 template< typename MT > // Type of the right-hand side sparse matrix
2954 {
2956 
2957  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2958 
2959  for( size_t j=0UL; j<n_; ++j )
2960  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2961  v_[element->index()*NN+j] += element->value();
2962 }
2963 //*************************************************************************************************
2964 
2965 
2966 //*************************************************************************************************
2977 template< typename Type // Data type of the matrix
2978  , size_t M // Number of rows
2979  , size_t N // Number of columns
2980  , bool SO > // Storage order
2981 template< typename MT // Type of the right-hand side dense matrix
2982  , bool SO2 > // Storage order of the right-hand side dense matrix
2985 {
2986  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2987 
2988  for( size_t i=0UL; i<m_; ++i )
2989  {
2990  if( IsDiagonal<MT>::value )
2991  {
2992  v_[i*NN+i] -= (~rhs)(i,i);
2993  }
2994  else
2995  {
2996  const size_t jbegin( ( IsUpper<MT>::value )
2997  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2998  :( 0UL ) );
2999  const size_t jend ( ( IsLower<MT>::value )
3000  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
3001  :( n_ ) );
3002  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3003 
3004  for( size_t j=jbegin; j<jend; ++j ) {
3005  v_[i*NN+j] -= (~rhs)(i,j);
3006  }
3007  }
3008  }
3009 }
3010 //*************************************************************************************************
3011 
3012 
3013 //*************************************************************************************************
3024 template< typename Type // Data type of the matrix
3025  , size_t M // Number of rows
3026  , size_t N // Number of columns
3027  , bool SO > // Storage order
3028 template< typename MT // Type of the right-hand side dense matrix
3029  , bool SO2 > // Storage order of the right-hand side dense matrix
3030 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
3032 {
3035 
3036  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3037 
3038  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
3039 
3040  for( size_t i=0UL; i<m_; ++i )
3041  {
3042  const size_t jbegin( ( IsUpper<MT>::value )
3043  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
3044  :( 0UL ) );
3045  const size_t jend ( ( IsLower<MT>::value )
3046  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
3047  :( n_ ) );
3048  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3049 
3050  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
3051  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3052 
3053  size_t j( jbegin );
3054 
3055  for( ; j<jpos; j+=SIMDSIZE ) {
3056  store( i, j, load(i,j) - (~rhs).load(i,j) );
3057  }
3058  for( ; remainder && j<jend; ++j ) {
3059  v_[i*NN+j] -= (~rhs)(i,j);
3060  }
3061  }
3062 }
3063 //*************************************************************************************************
3064 
3065 
3066 //*************************************************************************************************
3077 template< typename Type // Data type of the matrix
3078  , size_t M // Number of rows
3079  , size_t N // Number of columns
3080  , bool SO > // Storage order
3081 template< typename MT > // Type of the right-hand side sparse matrix
3083 {
3084  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3085 
3086  for( size_t i=0UL; i<m_; ++i )
3087  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3088  v_[i*NN+element->index()] -= element->value();
3089 }
3090 //*************************************************************************************************
3091 
3092 
3093 //*************************************************************************************************
3104 template< typename Type // Data type of the matrix
3105  , size_t M // Number of rows
3106  , size_t N // Number of columns
3107  , bool SO > // Storage order
3108 template< typename MT > // Type of the right-hand side sparse matrix
3110 {
3112 
3113  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3114 
3115  for( size_t j=0UL; j<n_; ++j )
3116  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3117  v_[element->index()*NN+j] -= element->value();
3118 }
3119 //*************************************************************************************************
3120 
3121 
3122 
3123 
3124 
3125 
3126 
3127 
3128 //=================================================================================================
3129 //
3130 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3131 //
3132 //=================================================================================================
3133 
3134 //*************************************************************************************************
3142 template< typename Type // Data type of the matrix
3143  , size_t M // Number of rows
3144  , size_t N > // Number of columns
3145 class HybridMatrix<Type,M,N,true> : public DenseMatrix< HybridMatrix<Type,M,N,true>, true >
3146 {
3147  public:
3148  //**Type definitions****************************************************************************
3151  typedef This ResultType;
3154  typedef Type ElementType;
3156  typedef const Type& ReturnType;
3157  typedef const This& CompositeType;
3158 
3159  typedef Type& Reference;
3160  typedef const Type& ConstReference;
3161  typedef Type* Pointer;
3162  typedef const Type* ConstPointer;
3163 
3166  //**********************************************************************************************
3167 
3168  //**Rebind struct definition********************************************************************
3171  template< typename NewType > // Data type of the other matrix
3172  struct Rebind {
3173  typedef HybridMatrix<NewType,M,N,true> Other;
3174  };
3175  //**********************************************************************************************
3176 
3177  //**Resize struct definition********************************************************************
3180  template< size_t NewM // Number of rows of the other matrix
3181  , size_t NewN > // Number of columns of the other matrix
3182  struct Resize {
3183  typedef HybridMatrix<Type,NewM,NewN,true> Other;
3184  };
3185  //**********************************************************************************************
3186 
3187  //**Compilation flags***************************************************************************
3189 
3193  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3194 
3196 
3199  enum : bool { smpAssignable = false };
3200  //**********************************************************************************************
3201 
3202  //**Constructors********************************************************************************
3205  explicit inline HybridMatrix();
3206  explicit inline HybridMatrix( size_t m, size_t n );
3207  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
3208  explicit inline HybridMatrix( initializer_list< initializer_list<Type> > list );
3209 
3210  template< typename Other >
3211  explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
3212 
3213  template< typename Other, size_t M2, size_t N2 >
3214  explicit inline HybridMatrix( const Other (&array)[M2][N2] );
3215 
3216  inline HybridMatrix( const HybridMatrix& m );
3217  template< typename MT, bool SO > inline HybridMatrix( const Matrix<MT,SO>& m );
3219  //**********************************************************************************************
3220 
3221  //**Destructor**********************************************************************************
3222  // No explicitly declared destructor.
3223  //**********************************************************************************************
3224 
3225  //**Data access functions***********************************************************************
3228  inline Reference operator()( size_t i, size_t j ) noexcept;
3229  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3230  inline Reference at( size_t i, size_t j );
3231  inline ConstReference at( size_t i, size_t j ) const;
3232  inline Pointer data () noexcept;
3233  inline ConstPointer data () const noexcept;
3234  inline Pointer data ( size_t j ) noexcept;
3235  inline ConstPointer data ( size_t j ) const noexcept;
3236  inline Iterator begin ( size_t j ) noexcept;
3237  inline ConstIterator begin ( size_t j ) const noexcept;
3238  inline ConstIterator cbegin( size_t j ) const noexcept;
3239  inline Iterator end ( size_t j ) noexcept;
3240  inline ConstIterator end ( size_t j ) const noexcept;
3241  inline ConstIterator cend ( size_t j ) const noexcept;
3243  //**********************************************************************************************
3244 
3245  //**Assignment operators************************************************************************
3248  inline HybridMatrix& operator=( const Type& set );
3249  inline HybridMatrix& operator=( initializer_list< initializer_list<Type> > list );
3250 
3251  template< typename Other, size_t M2, size_t N2 >
3252  inline HybridMatrix& operator=( const Other (&array)[M2][N2] );
3253 
3254  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
3255  template< typename MT, bool SO > inline HybridMatrix& operator= ( const Matrix<MT,SO>& rhs );
3256  template< typename MT, bool SO > inline HybridMatrix& operator+=( const Matrix<MT,SO>& rhs );
3257  template< typename MT, bool SO > inline HybridMatrix& operator-=( const Matrix<MT,SO>& rhs );
3258  template< typename MT, bool SO > inline HybridMatrix& operator*=( const Matrix<MT,SO>& rhs );
3259 
3260  template< typename Other >
3261  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator*=( Other rhs );
3262 
3263  template< typename Other >
3264  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator/=( Other rhs );
3266  //**********************************************************************************************
3267 
3268  //**Utility functions***************************************************************************
3271  inline size_t rows() const noexcept;
3272  inline size_t columns() const noexcept;
3273  inline constexpr size_t spacing() const noexcept;
3274  inline constexpr size_t capacity() const noexcept;
3275  inline size_t capacity( size_t j ) const noexcept;
3276  inline size_t nonZeros() const;
3277  inline size_t nonZeros( size_t j ) const;
3278  inline void reset();
3279  inline void reset( size_t i );
3280  inline void clear();
3281  void resize ( size_t m, size_t n, bool preserve=true );
3282  inline void extend ( size_t m, size_t n, bool preserve=true );
3283  inline void swap( HybridMatrix& m ) noexcept;
3285  //**********************************************************************************************
3286 
3287  //**Numeric functions***************************************************************************
3290  inline HybridMatrix& transpose();
3291  inline HybridMatrix& ctranspose();
3292 
3293  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
3295  //**********************************************************************************************
3296 
3297  //**Memory functions****************************************************************************
3300  static inline void* operator new ( std::size_t size );
3301  static inline void* operator new[]( std::size_t size );
3302  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3303  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3304 
3305  static inline void operator delete ( void* ptr );
3306  static inline void operator delete[]( void* ptr );
3307  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3308  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3310  //**********************************************************************************************
3311 
3312  private:
3313  //**********************************************************************************************
3315  template< typename MT >
3316  struct VectorizedAssign {
3317  enum : bool { value = useOptimizedKernels &&
3318  simdEnabled && MT::simdEnabled &&
3321  };
3322  //**********************************************************************************************
3323 
3324  //**********************************************************************************************
3326  template< typename MT >
3327  struct VectorizedAddAssign {
3328  enum : bool { value = useOptimizedKernels &&
3329  simdEnabled && MT::simdEnabled &&
3334  };
3335  //**********************************************************************************************
3336 
3337  //**********************************************************************************************
3339  template< typename MT >
3340  struct VectorizedSubAssign {
3341  enum : bool { value = useOptimizedKernels &&
3342  simdEnabled && MT::simdEnabled &&
3347  };
3348  //**********************************************************************************************
3349 
3350  //**********************************************************************************************
3352  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3353  //**********************************************************************************************
3354 
3355  public:
3356  //**Debugging functions*************************************************************************
3359  inline bool isIntact() const noexcept;
3361  //**********************************************************************************************
3362 
3363  //**Expression template evaluation functions****************************************************
3366  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3367  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3368 
3369  inline bool isAligned() const noexcept;
3370 
3371  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3372  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3373  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3374 
3375  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3376  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3377  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3378  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3379 
3380  template< typename MT, bool SO >
3381  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3382 
3383  template< typename MT, bool SO >
3384  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3385 
3386  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3387  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3388 
3389  template< typename MT, bool SO >
3390  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3391 
3392  template< typename MT, bool SO >
3393  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3394 
3395  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3396  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3397 
3398  template< typename MT, bool SO >
3399  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3400 
3401  template< typename MT, bool SO >
3402  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3403 
3404  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3405  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3407  //**********************************************************************************************
3408 
3409  private:
3410  //**********************************************************************************************
3412  enum : size_t { MM = ( usePadding )?( nextMultiple( M, SIMDSIZE ) ):( M ) };
3413  //**********************************************************************************************
3414 
3415  //**Member variables****************************************************************************
3419 
3421  size_t m_;
3422  size_t n_;
3423 
3424  //**********************************************************************************************
3425 
3426  //**Compile time checks*************************************************************************
3431  BLAZE_STATIC_ASSERT( !usePadding || MM % SIMDSIZE == 0UL );
3432  BLAZE_STATIC_ASSERT( MM >= M );
3433  //**********************************************************************************************
3434 };
3436 //*************************************************************************************************
3437 
3438 
3439 
3440 
3441 //=================================================================================================
3442 //
3443 // CONSTRUCTORS
3444 //
3445 //=================================================================================================
3446 
3447 //*************************************************************************************************
3453 template< typename Type // Data type of the matrix
3454  , size_t M // Number of rows
3455  , size_t N > // Number of columns
3457  : v_() // The statically allocated matrix elements
3458  , m_( 0UL ) // The current number of rows of the matrix
3459  , n_( 0UL ) // The current number of columns of the matrix
3460 {
3462 
3463  if( IsNumeric<Type>::value ) {
3464  for( size_t i=0UL; i<MM*N; ++i )
3465  v_[i] = Type();
3466  }
3467 
3468  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3469 }
3471 //*************************************************************************************************
3472 
3473 
3474 //*************************************************************************************************
3488 template< typename Type // Data type of the matrix
3489  , size_t M // Number of rows
3490  , size_t N > // Number of columns
3491 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n )
3492  : v_() // The statically allocated matrix elements
3493  , m_( m ) // The current number of rows of the matrix
3494  , n_( n ) // The current number of columns of the matrix
3495 {
3497 
3498  if( m > M ) {
3499  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3500  }
3501 
3502  if( n > N ) {
3503  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3504  }
3505 
3506  if( IsNumeric<Type>::value ) {
3507  for( size_t i=0UL; i<MM*N; ++i )
3508  v_[i] = Type();
3509  }
3510 
3511  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3512 }
3514 //*************************************************************************************************
3515 
3516 
3517 //*************************************************************************************************
3532 template< typename Type // Data type of the matrix
3533  , size_t M // Number of rows
3534  , size_t N > // Number of columns
3535 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Type& init )
3536  : v_() // The statically allocated matrix elements
3537  , m_( m ) // The current number of rows of the matrix
3538  , n_( n ) // The current number of columns of the matrix
3539 {
3541 
3542  if( m > M ) {
3543  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3544  }
3545 
3546  if( n > N ) {
3547  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3548  }
3549 
3550  for( size_t j=0UL; j<n; ++j ) {
3551  for( size_t i=0UL; i<m; ++i )
3552  v_[i+j*MM] = init;
3553 
3554  if( IsNumeric<Type>::value ) {
3555  for( size_t i=m; i<MM; ++i )
3556  v_[i+j*MM] = Type();
3557  }
3558  }
3559 
3560  if( IsNumeric<Type>::value ) {
3561  for( size_t j=n; j<N; ++j )
3562  for( size_t i=0UL; i<MM; ++i )
3563  v_[i+j*MM] = Type();
3564  }
3565 
3566  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3567 }
3569 //*************************************************************************************************
3570 
3571 
3572 //*************************************************************************************************
3597 template< typename Type // Data type of the matrix
3598  , size_t M // Number of rows
3599  , size_t N > // Number of columns
3601  : v_() // The statically allocated matrix elements
3602  , m_( list.size() ) // The current number of rows of the matrix
3603  , n_( determineColumns( list ) ) // The current number of columns of the matrix
3604 {
3606 
3607  if( m_ > M ) {
3608  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3609  }
3610 
3611  if( n_ > N ) {
3612  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3613  }
3614 
3615  size_t i( 0UL );
3616 
3617  for( const auto& rowList : list ) {
3618  size_t j( 0UL );
3619  for( const auto& element : rowList ) {
3620  v_[i+j*MM] = element;
3621  ++j;
3622  }
3623  if( IsNumeric<Type>::value ) {
3624  for( ; j<N; ++j ) {
3625  v_[i+j*MM] = Type();
3626  }
3627  }
3628  ++i;
3629  }
3630 
3631  BLAZE_INTERNAL_ASSERT( i == m_, "Invalid number of elements detected" );
3632 
3633  if( IsNumeric<Type>::value ) {
3634  for( ; i<MM; ++i ) {
3635  for( size_t j=0UL; j<N; ++j ) {
3636  v_[i+j*MM] = Type();
3637  }
3638  }
3639  }
3640 
3641  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3642 }
3644 //*************************************************************************************************
3645 
3646 
3647 //*************************************************************************************************
3675 template< typename Type // Data type of the matrix
3676  , size_t M // Number of rows
3677  , size_t N > // Number of columns
3678 template< typename Other > // Data type of the initialization array
3679 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Other* array )
3680  : v_() // The statically allocated matrix elements
3681  , m_( m ) // The current number of rows of the matrix
3682  , n_( n ) // The current number of columns of the matrix
3683 {
3685 
3686  if( m > M ) {
3687  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3688  }
3689 
3690  if( n > N ) {
3691  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3692  }
3693 
3694  for( size_t j=0UL; j<n; ++j ) {
3695  for( size_t i=0UL; i<m; ++i )
3696  v_[i+j*MM] = array[i+j*m];
3697 
3698  if( IsNumeric<Type>::value ) {
3699  for( size_t i=m; i<MM; ++i )
3700  v_[i+j*MM] = Type();
3701  }
3702  }
3703 
3704  if( IsNumeric<Type>::value ) {
3705  for( size_t j=n; j<N; ++j )
3706  for( size_t i=0UL; i<MM; ++i )
3707  v_[i+j*MM] = Type();
3708  }
3709 
3710  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3711 }
3713 //*************************************************************************************************
3714 
3715 
3716 //*************************************************************************************************
3738 template< typename Type // Data type of the matrix
3739  , size_t M // Number of rows
3740  , size_t N > // Number of columns
3741 template< typename Other // Data type of the initialization array
3742  , size_t M2 // Number of rows of the initialization array
3743  , size_t N2 > // Number of columns of the initialization array
3744 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const Other (&array)[M2][N2] )
3745  : v_() // The statically allocated matrix elements
3746  , m_( M2 ) // The current number of rows of the matrix
3747  , n_( N2 ) // The current number of columns of the matrix
3748 {
3749  BLAZE_STATIC_ASSERT( M2 <= M );
3750  BLAZE_STATIC_ASSERT( N2 <= N );
3752 
3753  for( size_t j=0UL; j<N2; ++j ) {
3754  for( size_t i=0UL; i<M2; ++i )
3755  v_[i+j*MM] = array[i][j];
3756 
3757  if( IsNumeric<Type>::value ) {
3758  for( size_t i=M2; i<MM; ++i )
3759  v_[i+j*MM] = Type();
3760  }
3761  }
3762 
3763  if( IsNumeric<Type>::value ) {
3764  for( size_t j=N2; j<N; ++j )
3765  for( size_t i=0UL; i<MM; ++i )
3766  v_[i+j*MM] = Type();
3767  }
3768 
3769  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3770 }
3772 //*************************************************************************************************
3773 
3774 
3775 //*************************************************************************************************
3784 template< typename Type // Data type of the matrix
3785  , size_t M // Number of rows
3786  , size_t N > // Number of columns
3788  : v_() // The statically allocated matrix elements
3789  , m_( m.m_ ) // The current number of rows of the matrix
3790  , n_( m.n_ ) // The current number of columns of the matrix
3791 {
3793 
3794  for( size_t j=0UL; j<n_; ++j ) {
3795  for( size_t i=0UL; i<m_; ++i )
3796  v_[i+j*MM] = m.v_[i+j*MM];
3797 
3798  if( IsNumeric<Type>::value ) {
3799  for( size_t i=m_; i<MM; ++i )
3800  v_[i+j*MM] = Type();
3801  }
3802  }
3803 
3804  if( IsNumeric<Type>::value ) {
3805  for( size_t j=n_; j<N; ++j )
3806  for( size_t i=0UL; i<MM; ++i )
3807  v_[i+j*MM] = Type();
3808  }
3809 
3810  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3811 }
3813 //*************************************************************************************************
3814 
3815 
3816 //*************************************************************************************************
3823 template< typename Type // Data type of the matrix
3824  , size_t M // Number of rows
3825  , size_t N > // Number of columns
3826 template< typename MT // Type of the foreign matrix
3827  , bool SO2 > // Storage order of the foreign matrix
3829  : v_() // The statically allocated matrix elements
3830  , m_( (~m).rows() ) // The current number of rows of the matrix
3831  , n_( (~m).columns() ) // The current number of columns of the matrix
3832 {
3833  using blaze::assign;
3834 
3836 
3837  if( (~m).rows() > M || (~m).columns() > N ) {
3838  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
3839  }
3840 
3841  for( size_t j=0UL; j<n_; ++j ) {
3842  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : m_ );
3843  i<( IsNumeric<Type>::value ? MM : m_ );
3844  ++i ) {
3845  v_[i+j*MM] = Type();
3846  }
3847  }
3848 
3849  if( IsNumeric<Type>::value ) {
3850  for( size_t j=n_; j<N; ++j )
3851  for( size_t i=0UL; i<MM; ++i )
3852  v_[i+j*MM] = Type();
3853  }
3854 
3855  assign( *this, ~m );
3856 
3857  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3858 }
3860 //*************************************************************************************************
3861 
3862 
3863 
3864 
3865 //=================================================================================================
3866 //
3867 // DATA ACCESS FUNCTIONS
3868 //
3869 //=================================================================================================
3870 
3871 //*************************************************************************************************
3882 template< typename Type // Data type of the matrix
3883  , size_t M // Number of rows
3884  , size_t N > // Number of columns
3886  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) noexcept
3887 {
3888  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3889  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3890  return v_[i+j*MM];
3891 }
3893 //*************************************************************************************************
3894 
3895 
3896 //*************************************************************************************************
3907 template< typename Type // Data type of the matrix
3908  , size_t M // Number of rows
3909  , size_t N > // Number of columns
3911  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const noexcept
3912 {
3913  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3914  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3915  return v_[i+j*MM];
3916 }
3918 //*************************************************************************************************
3919 
3920 
3921 //*************************************************************************************************
3933 template< typename Type // Data type of the matrix
3934  , size_t M // Number of rows
3935  , size_t N > // Number of columns
3937  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j )
3938 {
3939  if( i >= m_ ) {
3940  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3941  }
3942  if( j >= n_ ) {
3943  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3944  }
3945  return (*this)(i,j);
3946 }
3948 //*************************************************************************************************
3949 
3950 
3951 //*************************************************************************************************
3963 template< typename Type // Data type of the matrix
3964  , size_t M // Number of rows
3965  , size_t N > // Number of columns
3967  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
3968 {
3969  if( i >= m_ ) {
3970  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3971  }
3972  if( j >= n_ ) {
3973  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3974  }
3975  return (*this)(i,j);
3976 }
3978 //*************************************************************************************************
3979 
3980 
3981 //*************************************************************************************************
3993 template< typename Type // Data type of the matrix
3994  , size_t M // Number of rows
3995  , size_t N > // Number of columns
3998 {
3999  return v_;
4000 }
4002 //*************************************************************************************************
4003 
4004 
4005 //*************************************************************************************************
4017 template< typename Type // Data type of the matrix
4018  , size_t M // Number of rows
4019  , size_t N > // Number of columns
4021  HybridMatrix<Type,M,N,true>::data() const noexcept
4022 {
4023  return v_;
4024 }
4026 //*************************************************************************************************
4027 
4028 
4029 //*************************************************************************************************
4038 template< typename Type // Data type of the matrix
4039  , size_t M // Number of rows
4040  , size_t N > // Number of columns
4042  HybridMatrix<Type,M,N,true>::data( size_t j ) noexcept
4043 {
4044  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4045  return v_ + j*MM;
4046 }
4048 //*************************************************************************************************
4049 
4050 
4051 //*************************************************************************************************
4060 template< typename Type // Data type of the matrix
4061  , size_t M // Number of rows
4062  , size_t N > // Number of columns
4064  HybridMatrix<Type,M,N,true>::data( size_t j ) const noexcept
4065 {
4066  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4067  return v_ + j*MM;
4068 }
4070 //*************************************************************************************************
4071 
4072 
4073 //*************************************************************************************************
4080 template< typename Type // Data type of the matrix
4081  , size_t M // Number of rows
4082  , size_t N > // Number of columns
4084  HybridMatrix<Type,M,N,true>::begin( size_t j ) noexcept
4085 {
4086  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4087  return Iterator( v_ + j*MM );
4088 }
4090 //*************************************************************************************************
4091 
4092 
4093 //*************************************************************************************************
4100 template< typename Type // Data type of the matrix
4101  , size_t M // Number of rows
4102  , size_t N > // Number of columns
4104  HybridMatrix<Type,M,N,true>::begin( size_t j ) const noexcept
4105 {
4106  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4107  return ConstIterator( v_ + j*MM );
4108 }
4110 //*************************************************************************************************
4111 
4112 
4113 //*************************************************************************************************
4120 template< typename Type // Data type of the matrix
4121  , size_t M // Number of rows
4122  , size_t N > // Number of columns
4124  HybridMatrix<Type,M,N,true>::cbegin( size_t j ) const noexcept
4125 {
4126  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4127  return ConstIterator( v_ + j*MM );
4128 }
4130 //*************************************************************************************************
4131 
4132 
4133 //*************************************************************************************************
4140 template< typename Type // Data type of the matrix
4141  , size_t M // Number of rows
4142  , size_t N > // Number of columns
4144  HybridMatrix<Type,M,N,true>::end( size_t j ) noexcept
4145 {
4146  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4147  return Iterator( v_ + j*MM + M );
4148 }
4150 //*************************************************************************************************
4151 
4152 
4153 //*************************************************************************************************
4160 template< typename Type // Data type of the matrix
4161  , size_t M // Number of rows
4162  , size_t N > // Number of columns
4164  HybridMatrix<Type,M,N,true>::end( size_t j ) const noexcept
4165 {
4166  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4167  return ConstIterator( v_ + j*MM + M );
4168 }
4170 //*************************************************************************************************
4171 
4172 
4173 //*************************************************************************************************
4180 template< typename Type // Data type of the matrix
4181  , size_t M // Number of rows
4182  , size_t N > // Number of columns
4184  HybridMatrix<Type,M,N,true>::cend( size_t j ) const noexcept
4185 {
4186  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4187  return ConstIterator( v_ + j*MM + M );
4188 }
4190 //*************************************************************************************************
4191 
4192 
4193 
4194 
4195 //=================================================================================================
4196 //
4197 // ASSIGNMENT OPERATORS
4198 //
4199 //=================================================================================================
4200 
4201 //*************************************************************************************************
4208 template< typename Type // Data type of the matrix
4209  , size_t M // Number of rows
4210  , size_t N > // Number of columns
4212  HybridMatrix<Type,M,N,true>::operator=( const Type& set )
4213 {
4214  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
4215  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
4216 
4217  for( size_t j=0UL; j<n_; ++j )
4218  for( size_t i=0UL; i<m_; ++i )
4219  v_[i+j*MM] = set;
4220 
4221  return *this;
4222 }
4224 //*************************************************************************************************
4225 
4226 
4227 //*************************************************************************************************
4253 template< typename Type // Data type of the matrix
4254  , size_t M // Number of rows
4255  , size_t N > // Number of columns
4258 {
4259  const size_t m( list.size() );
4260  const size_t n( determineColumns( list ) );
4261 
4262  if( m > M ) {
4263  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4264  }
4265 
4266  if( n > N ) {
4267  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4268  }
4269 
4270  resize( m, n, false );
4271 
4272  size_t i( 0UL );
4273 
4274  for( const auto& rowList : list ) {
4275  size_t j( 0UL );
4276  for( const auto& element : rowList ) {
4277  v_[i+j*MM] = element;
4278  ++j;
4279  }
4280  for( ; j<n_; ++j ) {
4281  v_[i+j*MM] = Type();
4282  }
4283  ++i;
4284  }
4285 
4286  return *this;
4287 }
4289 //*************************************************************************************************
4290 
4291 
4292 //*************************************************************************************************
4314 template< typename Type // Data type of the matrix
4315  , size_t M // Number of rows
4316  , size_t N > // Number of columns
4317 template< typename Other // Data type of the initialization array
4318  , size_t M2 // Number of rows of the initialization array
4319  , size_t N2 > // Number of columns of the initialization array
4321  HybridMatrix<Type,M,N,true>::operator=( const Other (&array)[M2][N2] )
4322 {
4323  BLAZE_STATIC_ASSERT( M2 <= M );
4324  BLAZE_STATIC_ASSERT( N2 <= N );
4325 
4326  resize( M2, N2 );
4327 
4328  for( size_t j=0UL; j<N2; ++j )
4329  for( size_t i=0UL; i<M2; ++i )
4330  v_[i+j*MM] = array[i][j];
4331 
4332  return *this;
4333 }
4335 //*************************************************************************************************
4336 
4337 
4338 //*************************************************************************************************
4347 template< typename Type // Data type of the matrix
4348  , size_t M // Number of rows
4349  , size_t N > // Number of columns
4352 {
4353  using blaze::assign;
4354 
4355  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
4356  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
4357 
4358  resize( rhs.rows(), rhs.columns() );
4359  assign( *this, ~rhs );
4360 
4361  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4362 
4363  return *this;
4364 }
4366 //*************************************************************************************************
4367 
4368 
4369 //*************************************************************************************************
4381 template< typename Type // Data type of the matrix
4382  , size_t M // Number of rows
4383  , size_t N > // Number of columns
4384 template< typename MT // Type of the right-hand side matrix
4385  , bool SO > // Storage order of the right-hand side matrix
4387 {
4388  using blaze::assign;
4389 
4390  typedef TransExprTrait_<This> TT;
4391  typedef CTransExprTrait_<This> CT;
4392  typedef InvExprTrait_<This> IT;
4393 
4394  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
4395  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
4396  }
4397 
4398  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4399  transpose();
4400  }
4401  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4402  ctranspose();
4403  }
4404  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4405  HybridMatrix tmp( ~rhs );
4406  resize( tmp.rows(), tmp.columns() );
4407  assign( *this, tmp );
4408  }
4409  else {
4410  resize( (~rhs).rows(), (~rhs).columns() );
4412  reset();
4413  assign( *this, ~rhs );
4414  }
4415 
4416  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4417 
4418  return *this;
4419 }
4421 //*************************************************************************************************
4422 
4423 
4424 //*************************************************************************************************
4435 template< typename Type // Data type of the matrix
4436  , size_t M // Number of rows
4437  , size_t N > // Number of columns
4438 template< typename MT // Type of the right-hand side matrix
4439  , bool SO > // Storage order of the right-hand side matrix
4441 {
4442  using blaze::addAssign;
4443 
4444  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4445  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4446  }
4447 
4448  if( (~rhs).canAlias( this ) ) {
4449  const ResultType_<MT> tmp( ~rhs );
4450  addAssign( *this, tmp );
4451  }
4452  else {
4453  addAssign( *this, ~rhs );
4454  }
4455 
4456  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4457 
4458  return *this;
4459 }
4461 //*************************************************************************************************
4462 
4463 
4464 //*************************************************************************************************
4475 template< typename Type // Data type of the matrix
4476  , size_t M // Number of rows
4477  , size_t N > // Number of columns
4478 template< typename MT // Type of the right-hand side matrix
4479  , bool SO > // Storage order of the right-hand side matrix
4481 {
4482  using blaze::subAssign;
4483 
4484  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4485  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4486  }
4487 
4488  if( (~rhs).canAlias( this ) ) {
4489  const ResultType_<MT> tmp( ~rhs );
4490  subAssign( *this, tmp );
4491  }
4492  else {
4493  subAssign( *this, ~rhs );
4494  }
4495 
4496  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4497 
4498  return *this;
4499 }
4501 //*************************************************************************************************
4502 
4503 
4504 //*************************************************************************************************
4515 template< typename Type // Data type of the matrix
4516  , size_t M // Number of rows
4517  , size_t N > // Number of columns
4518 template< typename MT // Type of the right-hand side matrix
4519  , bool SO > // Storage order of the right-hand side matrix
4521 {
4522  if( n_ != (~rhs).rows() || (~rhs).columns() > N ) {
4523  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4524  }
4525 
4526  const HybridMatrix tmp( *this * (~rhs) );
4527  this->operator=( tmp );
4528 
4529  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4530 
4531  return *this;
4532 }
4534 //*************************************************************************************************
4535 
4536 
4537 //*************************************************************************************************
4545 template< typename Type // Data type of the matrix
4546  , size_t M // Number of rows
4547  , size_t N > // Number of columns
4548 template< typename Other > // Data type of the right-hand side scalar
4549 inline EnableIf_<IsNumeric<Other>, HybridMatrix<Type,M,N,true> >&
4551 {
4552  using blaze::assign;
4553 
4554  assign( *this, (*this) * rhs );
4555 
4556  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4557 
4558  return *this;
4559 }
4561 //*************************************************************************************************
4562 
4563 
4564 //*************************************************************************************************
4574 template< typename Type // Data type of the matrix
4575  , size_t M // Number of rows
4576  , size_t N > // Number of columns
4577 template< typename Other > // Data type of the right-hand side scalar
4578 inline EnableIf_<IsNumeric<Other>, HybridMatrix<Type,M,N,true> >&
4580 {
4581  using blaze::assign;
4582 
4583  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4584 
4585  assign( *this, (*this) / rhs );
4586 
4587  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4588 
4589  return *this;
4590 }
4592 //*************************************************************************************************
4593 
4594 
4595 
4596 
4597 //=================================================================================================
4598 //
4599 // UTILITY FUNCTIONS
4600 //
4601 //=================================================================================================
4602 
4603 //*************************************************************************************************
4609 template< typename Type // Data type of the matrix
4610  , size_t M // Number of rows
4611  , size_t N > // Number of columns
4612 inline size_t HybridMatrix<Type,M,N,true>::rows() const noexcept
4613 {
4614  return m_;
4615 }
4617 //*************************************************************************************************
4618 
4619 
4620 //*************************************************************************************************
4626 template< typename Type // Data type of the matrix
4627  , size_t M // Number of rows
4628  , size_t N > // Number of columns
4629 inline size_t HybridMatrix<Type,M,N,true>::columns() const noexcept
4630 {
4631  return n_;
4632 }
4634 //*************************************************************************************************
4635 
4636 
4637 //*************************************************************************************************
4646 template< typename Type // Data type of the matrix
4647  , size_t M // Number of rows
4648  , size_t N > // Number of columns
4649 inline constexpr size_t HybridMatrix<Type,M,N,true>::spacing() const noexcept
4650 {
4651  return MM;
4652 }
4654 //*************************************************************************************************
4655 
4656 
4657 //*************************************************************************************************
4663 template< typename Type // Data type of the matrix
4664  , size_t M // Number of rows
4665  , size_t N > // Number of columns
4666 inline constexpr size_t HybridMatrix<Type,M,N,true>::capacity() const noexcept
4667 {
4668  return MM*N;
4669 }
4671 //*************************************************************************************************
4672 
4673 
4674 //*************************************************************************************************
4681 template< typename Type // Data type of the matrix
4682  , size_t M // Number of rows
4683  , size_t N > // Number of columns
4684 inline size_t HybridMatrix<Type,M,N,true>::capacity( size_t j ) const noexcept
4685 {
4686  UNUSED_PARAMETER( j );
4687 
4688  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4689 
4690  return MM;
4691 }
4693 //*************************************************************************************************
4694 
4695 
4696 //*************************************************************************************************
4702 template< typename Type // Data type of the matrix
4703  , size_t M // Number of rows
4704  , size_t N > // Number of columns
4705 inline size_t HybridMatrix<Type,M,N,true>::nonZeros() const
4706 {
4707  size_t nonzeros( 0UL );
4708 
4709  for( size_t j=0UL; j<n_; ++j )
4710  for( size_t i=0UL; i<m_; ++i )
4711  if( !isDefault( v_[i+j*MM] ) )
4712  ++nonzeros;
4713 
4714  return nonzeros;
4715 }
4717 //*************************************************************************************************
4718 
4719 
4720 //*************************************************************************************************
4727 template< typename Type // Data type of the matrix
4728  , size_t M // Number of rows
4729  , size_t N > // Number of columns
4730 inline size_t HybridMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4731 {
4732  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4733 
4734  const size_t iend( j*MM + m_ );
4735  size_t nonzeros( 0UL );
4736 
4737  for( size_t i=j*MM; i<iend; ++i )
4738  if( !isDefault( v_[i] ) )
4739  ++nonzeros;
4740 
4741  return nonzeros;
4742 }
4744 //*************************************************************************************************
4745 
4746 
4747 //*************************************************************************************************
4753 template< typename Type // Data type of the matrix
4754  , size_t M // Number of rows
4755  , size_t N > // Number of columns
4757 {
4758  using blaze::clear;
4759 
4760  for( size_t j=0UL; j<n_; ++j )
4761  for( size_t i=0UL; i<m_; ++i )
4762  clear( v_[i+j*MM] );
4763 }
4765 //*************************************************************************************************
4766 
4767 
4768 //*************************************************************************************************
4778 template< typename Type // Data type of the matrix
4779  , size_t M // Number of rows
4780  , size_t N > // Number of columns
4781 inline void HybridMatrix<Type,M,N,true>::reset( size_t j )
4782 {
4783  using blaze::clear;
4784 
4785  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4786  for( size_t i=0UL; i<m_; ++i )
4787  clear( v_[i+j*MM] );
4788 }
4790 //*************************************************************************************************
4791 
4792 
4793 //*************************************************************************************************
4801 template< typename Type // Data type of the matrix
4802  , size_t M // Number of rows
4803  , size_t N > // Number of columns
4805 {
4806  resize( 0UL, 0UL );
4807 }
4809 //*************************************************************************************************
4810 
4811 
4812 //*************************************************************************************************
4849 template< typename Type // Data type of the matrix
4850  , size_t M // Number of rows
4851  , size_t N > // Number of columns
4852 void HybridMatrix<Type,M,N,true>::resize( size_t m, size_t n, bool preserve )
4853 {
4854  UNUSED_PARAMETER( preserve );
4855 
4856  if( m > M ) {
4857  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4858  }
4859 
4860  if( n > N ) {
4861  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4862  }
4863 
4864  if( IsVectorizable<Type>::value && m < m_ ) {
4865  for( size_t j=0UL; j<n; ++j )
4866  for( size_t i=m; i<m_; ++i )
4867  v_[i+j*MM] = Type();
4868  }
4869 
4870  if( IsVectorizable<Type>::value && n < n_ ) {
4871  for( size_t j=n; j<n_; ++j )
4872  for( size_t i=0UL; i<m_; ++i )
4873  v_[i+j*MM] = Type();
4874  }
4875 
4876  m_ = m;
4877  n_ = n;
4878 }
4880 //*************************************************************************************************
4881 
4882 
4883 //*************************************************************************************************
4899 template< typename Type // Data type of the matrix
4900  , size_t M // Number of rows
4901  , size_t N > // Number of columns
4902 inline void HybridMatrix<Type,M,N,true>::extend( size_t m, size_t n, bool preserve )
4903 {
4904  UNUSED_PARAMETER( preserve );
4905  resize( m_+m, n_+n );
4906 }
4908 //*************************************************************************************************
4909 
4910 
4911 //*************************************************************************************************
4918 template< typename Type // Data type of the matrix
4919  , size_t M // Number of rows
4920  , size_t N > // Number of columns
4921 inline void HybridMatrix<Type,M,N,true>::swap( HybridMatrix& m ) noexcept
4922 {
4923  using std::swap;
4924 
4925  const size_t maxrows( max( m_, m.m_ ) );
4926  const size_t maxcols( max( n_, m.n_ ) );
4927 
4928  for( size_t j=0UL; j<maxcols; ++j ) {
4929  for( size_t i=0UL; i<maxrows; ++i ) {
4930  swap( v_[i+j*MM], m(i,j) );
4931  }
4932  }
4933 
4934  swap( m_, m.m_ );
4935  swap( n_, m.n_ );
4936 }
4938 //*************************************************************************************************
4939 
4940 
4941 
4942 
4943 //=================================================================================================
4944 //
4945 // NUMERIC FUNCTIONS
4946 //
4947 //=================================================================================================
4948 
4949 //*************************************************************************************************
4961 template< typename Type // Data type of the matrix
4962  , size_t M // Number of rows
4963  , size_t N > // Number of columns
4965 {
4966  using std::swap;
4967 
4968  if( m_ > N || n_ > M ) {
4969  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4970  }
4971 
4972  const size_t maxsize( max( m_, n_ ) );
4973  for( size_t j=1UL; j<maxsize; ++j ) {
4974  for( size_t i=0UL; i<j; ++i ) {
4975  swap( v_[i+j*MM], v_[j+i*MM] );
4976  }
4977  }
4978 
4979  if( IsVectorizable<Type>::value && n_ < m_ ) {
4980  for( size_t j=0UL; j<n_; ++j ) {
4981  for( size_t i=n_; i<m_; ++i ) {
4982  v_[i+j*MM] = Type();
4983  }
4984  }
4985  }
4986 
4987  if( IsVectorizable<Type>::value && n_ > m_ ) {
4988  for( size_t j=m_; j<n_; ++j ) {
4989  for( size_t i=0UL; i<m_; ++i ) {
4990  v_[i+j*MM] = Type();
4991  }
4992  }
4993  }
4994 
4995  swap( m_, n_ );
4996 
4997  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4998 
4999  return *this;
5000 }
5002 //*************************************************************************************************
5003 
5004 
5005 //*************************************************************************************************
5017 template< typename Type // Data type of the matrix
5018  , size_t M // Number of rows
5019  , size_t N > // Number of columns
5021 {
5022  using std::swap;
5023 
5024  if( m_ > N || n_ > M ) {
5025  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
5026  }
5027 
5028  const size_t maxsize( max( m_, n_ ) );
5029  for( size_t j=0UL; j<maxsize; ++j ) {
5030  for( size_t i=0UL; i<j; ++i ) {
5031  cswap( v_[i+j*MM], v_[j+i*MM] );
5032  }
5033  conjugate( v_[j+j*MM] );
5034  }
5035 
5036  if( IsVectorizable<Type>::value && n_ < m_ ) {
5037  for( size_t j=0UL; j<n_; ++j ) {
5038  for( size_t i=n_; i<m_; ++i ) {
5039  v_[i+j*MM] = Type();
5040  }
5041  }
5042  }
5043 
5044  if( IsVectorizable<Type>::value && n_ > m_ ) {
5045  for( size_t j=m_; j<n_; ++j ) {
5046  for( size_t i=0UL; i<m_; ++i ) {
5047  v_[i+j*MM] = Type();
5048  }
5049  }
5050  }
5051 
5052  swap( m_, n_ );
5053 
5054  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
5055 
5056  return *this;
5057 }
5059 //*************************************************************************************************
5060 
5061 
5062 //*************************************************************************************************
5069 template< typename Type // Data type of the matrix
5070  , size_t M // Number of rows
5071  , size_t N > // Number of columns
5072 template< typename Other > // Data type of the scalar value
5074  HybridMatrix<Type,M,N,true>::scale( const Other& scalar )
5075 {
5076  for( size_t j=0UL; j<n_; ++j )
5077  for( size_t i=0UL; i<m_; ++i )
5078  v_[i+j*MM] *= scalar;
5079 
5080  return *this;
5081 }
5083 //*************************************************************************************************
5084 
5085 
5086 
5087 
5088 //=================================================================================================
5089 //
5090 // MEMORY FUNCTIONS
5091 //
5092 //=================================================================================================
5093 
5094 //*************************************************************************************************
5105 template< typename Type // Data type of the matrix
5106  , size_t M // Number of rows
5107  , size_t N > // Number of columns
5108 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size )
5109 {
5110  UNUSED_PARAMETER( size );
5111 
5112  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5113 
5114  return allocate<HybridMatrix>( 1UL );
5115 }
5117 //*************************************************************************************************
5118 
5119 
5120 //*************************************************************************************************
5131 template< typename Type // Data type of the matrix
5132  , size_t M // Number of rows
5133  , size_t N > // Number of columns
5134 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size )
5135 {
5136  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5137  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5138 
5139  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5140 }
5142 //*************************************************************************************************
5143 
5144 
5145 //*************************************************************************************************
5156 template< typename Type // Data type of the matrix
5157  , size_t M // Number of rows
5158  , size_t N > // Number of columns
5159 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
5160 {
5161  UNUSED_PARAMETER( size );
5162 
5163  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5164 
5165  return allocate<HybridMatrix>( 1UL );
5166 }
5168 //*************************************************************************************************
5169 
5170 
5171 //*************************************************************************************************
5182 template< typename Type // Data type of the matrix
5183  , size_t M // Number of rows
5184  , size_t N > // Number of columns
5185 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
5186 {
5187  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5188  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5189 
5190  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5191 }
5193 //*************************************************************************************************
5194 
5195 
5196 //*************************************************************************************************
5203 template< typename Type // Data type of the matrix
5204  , size_t M // Number of rows
5205  , size_t N > // Number of columns
5206 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr )
5207 {
5208  deallocate( static_cast<HybridMatrix*>( ptr ) );
5209 }
5211 //*************************************************************************************************
5212 
5213 
5214 //*************************************************************************************************
5221 template< typename Type // Data type of the matrix
5222  , size_t M // Number of rows
5223  , size_t N > // Number of columns
5224 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr )
5225 {
5226  deallocate( static_cast<HybridMatrix*>( ptr ) );
5227 }
5229 //*************************************************************************************************
5230 
5231 
5232 //*************************************************************************************************
5239 template< typename Type // Data type of the matrix
5240  , size_t M // Number of rows
5241  , size_t N > // Number of columns
5242 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
5243 {
5244  deallocate( static_cast<HybridMatrix*>( ptr ) );
5245 }
5247 //*************************************************************************************************
5248 
5249 
5250 //*************************************************************************************************
5257 template< typename Type // Data type of the matrix
5258  , size_t M // Number of rows
5259  , size_t N > // Number of columns
5260 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
5261 {
5262  deallocate( static_cast<HybridMatrix*>( ptr ) );
5263 }
5265 //*************************************************************************************************
5266 
5267 
5268 
5269 
5270 //=================================================================================================
5271 //
5272 // DEBUGGING FUNCTIONS
5273 //
5274 //=================================================================================================
5275 
5276 //*************************************************************************************************
5286 template< typename Type // Data type of the matrix
5287  , size_t M // Number of rows
5288  , size_t N > // Number of columns
5289 inline bool HybridMatrix<Type,M,N,true>::isIntact() const noexcept
5290 {
5291  if( m_ > M || n_ > N )
5292  return false;
5293 
5295  {
5296  for( size_t j=0UL; j<n_; ++j ) {
5297  for( size_t i=m_; i<MM; ++i ) {
5298  if( v_[i+j*MM] != Type() )
5299  return false;
5300  }
5301  }
5302 
5303  for( size_t j=n_; j<N; ++j ) {
5304  for( size_t i=0UL; i<MM; ++i ) {
5305  if( v_[i+j*MM] != Type() )
5306  return false;
5307  }
5308  }
5309  }
5310 
5311  return true;
5312 }
5314 //*************************************************************************************************
5315 
5316 
5317 
5318 
5319 //=================================================================================================
5320 //
5321 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5322 //
5323 //=================================================================================================
5324 
5325 //*************************************************************************************************
5336 template< typename Type // Data type of the matrix
5337  , size_t M // Number of rows
5338  , size_t N > // Number of columns
5339 template< typename Other > // Data type of the foreign expression
5340 inline bool HybridMatrix<Type,M,N,true>::canAlias( const Other* alias ) const noexcept
5341 {
5342  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5343 }
5345 //*************************************************************************************************
5346 
5347 
5348 //*************************************************************************************************
5359 template< typename Type // Data type of the matrix
5360  , size_t M // Number of rows
5361  , size_t N > // Number of columns
5362 template< typename Other > // Data type of the foreign expression
5363 inline bool HybridMatrix<Type,M,N,true>::isAliased( const Other* alias ) const noexcept
5364 {
5365  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5366 }
5368 //*************************************************************************************************
5369 
5370 
5371 //*************************************************************************************************
5381 template< typename Type // Data type of the matrix
5382  , size_t M // Number of rows
5383  , size_t N > // Number of columns
5384 inline bool HybridMatrix<Type,M,N,true>::isAligned() const noexcept
5385 {
5386  return ( usePadding || rows() % SIMDSIZE == 0UL );
5387 }
5389 //*************************************************************************************************
5390 
5391 
5392 //*************************************************************************************************
5407 template< typename Type // Data type of the matrix
5408  , size_t M // Number of rows
5409  , size_t N > // Number of columns
5411  HybridMatrix<Type,M,N,true>::load( size_t i, size_t j ) const noexcept
5412 {
5413  if( usePadding )
5414  return loada( i, j );
5415  else
5416  return loadu( i, j );
5417 }
5419 //*************************************************************************************************
5420 
5421 
5422 //*************************************************************************************************
5437 template< typename Type // Data type of the matrix
5438  , size_t M // Number of rows
5439  , size_t N > // Number of columns
5441  HybridMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const noexcept
5442 {
5443  using blaze::loada;
5444 
5446 
5447  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5448  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5449  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5450  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5451  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5452 
5453  return loada( &v_[i+j*MM] );
5454 }
5456 //*************************************************************************************************
5457 
5458 
5459 //*************************************************************************************************
5474 template< typename Type // Data type of the matrix
5475  , size_t M // Number of rows
5476  , size_t N > // Number of columns
5478  HybridMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const noexcept
5479 {
5480  using blaze::loadu;
5481 
5483 
5484  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5485  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5486  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5487 
5488  return loadu( &v_[i+j*MM] );
5489 }
5491 //*************************************************************************************************
5492 
5493 
5494 //*************************************************************************************************
5510 template< typename Type // Data type of the matrix
5511  , size_t M // Number of rows
5512  , size_t N > // Number of columns
5514  HybridMatrix<Type,M,N,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5515 {
5516  if( usePadding )
5517  storea( i, j, value );
5518  else
5519  storeu( i, j, value );
5520 }
5522 //*************************************************************************************************
5523 
5524 
5525 //*************************************************************************************************
5541 template< typename Type // Data type of the matrix
5542  , size_t M // Number of rows
5543  , size_t N > // Number of columns
5545  HybridMatrix<Type,M,N,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5546 {
5547  using blaze::storea;
5548 
5550 
5551  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5552  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5553  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5554  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5555  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5556 
5557  storea( &v_[i+j*MM], value );
5558 }
5560 //*************************************************************************************************
5561 
5562 
5563 //*************************************************************************************************
5579 template< typename Type // Data type of the matrix
5580  , size_t M // Number of rows
5581  , size_t N > // Number of columns
5583  HybridMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5584 {
5585  using blaze::storeu;
5586 
5588 
5589  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5590  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5591  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5592 
5593  storeu( &v_[i+j*MM], value );
5594 }
5596 //*************************************************************************************************
5597 
5598 
5599 //*************************************************************************************************
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>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5621 {
5622  using blaze::stream;
5623 
5625 
5626  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5627  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5628  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5629  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5630  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5631 
5632  stream( &v_[i+j*MM], value );
5633 }
5635 //*************************************************************************************************
5636 
5637 
5638 //*************************************************************************************************
5650 template< typename Type // Data type of the matrix
5651  , size_t M // Number of rows
5652  , size_t N > // Number of columns
5653 template< typename MT // Type of the right-hand side dense matrix
5654  , bool SO > // Storage order of the right-hand side dense matrix
5657 {
5658  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5659 
5660  for( size_t j=0UL; j<n_; ++j ) {
5661  for( size_t i=0UL; i<m_; ++i ) {
5662  v_[i+j*MM] = (~rhs)(i,j);
5663  }
5664  }
5665 }
5667 //*************************************************************************************************
5668 
5669 
5670 //*************************************************************************************************
5682 template< typename Type // Data type of the matrix
5683  , size_t M // Number of rows
5684  , size_t N > // Number of columns
5685 template< typename MT // Type of the right-hand side dense matrix
5686  , bool SO > // Storage order of the right-hand side dense matrix
5689 {
5691 
5692  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5693 
5694  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5695 
5696  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5697  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5698 
5699  for( size_t j=0UL; j<n_; ++j )
5700  {
5701  size_t i( 0UL );
5702 
5703  for( ; i<ipos; i+=SIMDSIZE ) {
5704  store( i, j, (~rhs).load(i,j) );
5705  }
5706  for( ; remainder && i<m_; ++i ) {
5707  v_[i+j*MM] = (~rhs)(i,j);
5708  }
5709  }
5710 }
5712 //*************************************************************************************************
5713 
5714 
5715 //*************************************************************************************************
5727 template< typename Type // Data type of the matrix
5728  , size_t M // Number of rows
5729  , size_t N > // Number of columns
5730 template< typename MT > // Type of the right-hand side sparse matrix
5732 {
5733  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5734 
5735  for( size_t j=0UL; j<n_; ++j )
5736  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5737  v_[element->index()+j*MM] = element->value();
5738 }
5740 //*************************************************************************************************
5741 
5742 
5743 //*************************************************************************************************
5755 template< typename Type // Data type of the matrix
5756  , size_t M // Number of rows
5757  , size_t N > // Number of columns
5758 template< typename MT > // Type of the right-hand side sparse matrix
5760 {
5762 
5763  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5764 
5765  for( size_t i=0UL; i<m_; ++i )
5766  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5767  v_[i+element->index()*MM] = element->value();
5768 }
5770 //*************************************************************************************************
5771 
5772 
5773 //*************************************************************************************************
5785 template< typename Type // Data type of the matrix
5786  , size_t M // Number of rows
5787  , size_t N > // Number of columns
5788 template< typename MT // Type of the right-hand side dense matrix
5789  , bool SO > // Storage order of the right-hand side dense matrix
5792 {
5793  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5794 
5795  for( size_t j=0UL; j<n_; ++j )
5796  {
5797  if( IsDiagonal<MT>::value )
5798  {
5799  v_[j+j*MM] += (~rhs)(j,j);
5800  }
5801  else
5802  {
5803  const size_t ibegin( ( IsLower<MT>::value )
5804  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5805  :( 0UL ) );
5806  const size_t iend ( ( IsUpper<MT>::value )
5807  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5808  :( m_ ) );
5809  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5810 
5811  for( size_t i=ibegin; i<iend; ++i ) {
5812  v_[i+j*MM] += (~rhs)(i,j);
5813  }
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 dense matrix
5837  , bool SO > // Storage order of the right-hand side dense matrix
5840 {
5843 
5844  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5845 
5846  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
5847 
5848  for( size_t j=0UL; j<n_; ++j )
5849  {
5850  const size_t ibegin( ( IsLower<MT>::value )
5851  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5852  :( 0UL ) );
5853  const size_t iend ( ( IsUpper<MT>::value )
5854  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5855  :( m_ ) );
5856  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5857 
5858  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5859  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5860 
5861  size_t i( ibegin );
5862 
5863  for( ; i<ipos; i+=SIMDSIZE ) {
5864  store( i, j, load(i,j) + (~rhs).load(i,j) );
5865  }
5866  for( ; remainder && i<iend; ++i ) {
5867  v_[i+j*MM] += (~rhs)(i,j);
5868  }
5869  }
5870 }
5872 //*************************************************************************************************
5873 
5874 
5875 //*************************************************************************************************
5887 template< typename Type // Data type of the matrix
5888  , size_t M // Number of rows
5889  , size_t N > // Number of columns
5890 template< typename MT > // Type of the right-hand side sparse matrix
5892 {
5893  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5894 
5895  for( size_t j=0UL; j<n_; ++j )
5896  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5897  v_[element->index()+j*MM] += element->value();
5898 }
5900 //*************************************************************************************************
5901 
5902 
5903 //*************************************************************************************************
5915 template< typename Type // Data type of the matrix
5916  , size_t M // Number of rows
5917  , size_t N > // Number of columns
5918 template< typename MT > // Type of the right-hand side sparse matrix
5920 {
5922 
5923  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5924 
5925  for( size_t i=0UL; i<m_; ++i )
5926  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5927  v_[i+element->index()*MM] += element->value();
5928 }
5930 //*************************************************************************************************
5931 
5932 
5933 //*************************************************************************************************
5945 template< typename Type // Data type of the matrix
5946  , size_t M // Number of rows
5947  , size_t N > // Number of columns
5948 template< typename MT // Type of the right-hand side dense matrix
5949  , bool SO > // Storage order of the right-hand side dense matrix
5952 {
5953  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5954 
5955  for( size_t j=0UL; j<n_; ++j )
5956  {
5957  if( IsDiagonal<MT>::value )
5958  {
5959  v_[j+j*MM] -= (~rhs)(j,j);
5960  }
5961  else
5962  {
5963  const size_t ibegin( ( IsLower<MT>::value )
5964  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5965  :( 0UL ) );
5966  const size_t iend ( ( IsUpper<MT>::value )
5967  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5968  :( m_ ) );
5969  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5970 
5971  for( size_t i=ibegin; i<iend; ++i ) {
5972  v_[i+j*MM] -= (~rhs)(i,j);
5973  }
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 dense matrix
5997  , bool SO > // Storage order of the right-hand side dense matrix
6000 {
6003 
6004  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6005 
6006  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
6007 
6008  for( size_t j=0UL; j<n_; ++j )
6009  {
6010  const size_t ibegin( ( IsLower<MT>::value )
6011  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
6012  :( 0UL ) );
6013  const size_t iend ( ( IsUpper<MT>::value )
6014  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
6015  :( m_ ) );
6016  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
6017 
6018  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
6019  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
6020 
6021  size_t i( ibegin );
6022 
6023  for( ; i<ipos; i+=SIMDSIZE ) {
6024  store( i, j, load(i,j) - (~rhs).load(i,j) );
6025  }
6026  for( ; remainder && i<iend; ++i ) {
6027  v_[i+j*MM] -= (~rhs)(i,j);
6028  }
6029  }
6030 }
6032 //*************************************************************************************************
6033 
6034 
6035 //*************************************************************************************************
6047 template< typename Type // Data type of the matrix
6048  , size_t M // Number of rows
6049  , size_t N > // Number of columns
6050 template< typename MT > // Type of the right-hand side sparse matrix
6052 {
6053  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6054 
6055  typedef ConstIterator_<MT> RhsConstIterator;
6056 
6057  for( size_t j=0UL; j<n_; ++j )
6058  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6059  v_[element->index()+j*MM] -= element->value();
6060 }
6062 //*************************************************************************************************
6063 
6064 
6065 //*************************************************************************************************
6077 template< typename Type // Data type of the matrix
6078  , size_t M // Number of rows
6079  , size_t N > // Number of columns
6080 template< typename MT > // Type of the right-hand side sparse matrix
6082 {
6084 
6085  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6086 
6087  typedef ConstIterator_<MT> RhsConstIterator;
6088 
6089  for( size_t i=0UL; i<m_; ++i )
6090  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6091  v_[i+element->index()*MM] -= element->value();
6092 }
6094 //*************************************************************************************************
6095 
6096 
6097 
6098 
6099 
6100 
6101 
6102 
6103 //=================================================================================================
6104 //
6105 // UNDEFINED CLASS TEMPLATE SPECIALIZATIONS
6106 //
6107 //=================================================================================================
6108 
6109 //*************************************************************************************************
6117 template< typename Type // Data type of the matrix
6118  , size_t M // Number of rows
6119  , bool SO > // Storage order
6120 class HybridMatrix<Type,M,0UL,SO>;
6122 //*************************************************************************************************
6123 
6124 
6125 //*************************************************************************************************
6133 template< typename Type // Data type of the matrix
6134  , size_t N // Number of columns
6135  , bool SO > // Storage order
6136 class HybridMatrix<Type,0UL,N,SO>;
6138 //*************************************************************************************************
6139 
6140 
6141 //*************************************************************************************************
6149 template< typename Type // Data type of the matrix
6150  , bool SO > // Storage order
6151 class HybridMatrix<Type,0UL,0UL,SO>;
6153 //*************************************************************************************************
6154 
6155 
6156 
6157 
6158 
6159 
6160 
6161 
6162 //=================================================================================================
6163 //
6164 // STATICMATRIX OPERATORS
6165 //
6166 //=================================================================================================
6167 
6168 //*************************************************************************************************
6171 template< typename Type, size_t M, size_t N, bool SO >
6172 inline void reset( HybridMatrix<Type,M,N,SO>& m );
6173 
6174 template< typename Type, size_t M, size_t N, bool SO >
6175 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i );
6176 
6177 template< typename Type, size_t M, size_t N, bool SO >
6178 inline void clear( HybridMatrix<Type,M,N,SO>& m );
6179 
6180 template< bool RF, typename Type, size_t M, size_t N, bool SO >
6181 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m );
6182 
6183 template< typename Type, size_t M, size_t N, bool SO >
6184 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m ) noexcept;
6185 
6186 template< typename Type, size_t M, size_t N, bool SO >
6187 inline void swap( HybridMatrix<Type,M,N,SO>& a, HybridMatrix<Type,M,N,SO>& b ) noexcept;
6189 //*************************************************************************************************
6190 
6191 
6192 //*************************************************************************************************
6199 template< typename Type // Data type of the matrix
6200  , size_t M // Number of rows
6201  , size_t N // Number of columns
6202  , bool SO > // Storage order
6204 {
6205  m.reset();
6206 }
6207 //*************************************************************************************************
6208 
6209 
6210 //*************************************************************************************************
6223 template< typename Type // Data type of the matrix
6224  , size_t M // Number of rows
6225  , size_t N // Number of columns
6226  , bool SO > // Storage order
6227 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i )
6228 {
6229  m.reset( i );
6230 }
6231 //*************************************************************************************************
6232 
6233 
6234 //*************************************************************************************************
6241 template< typename Type // Data type of the matrix
6242  , size_t M // Number of rows
6243  , size_t N // Number of columns
6244  , bool SO > // Storage order
6246 {
6247  m.clear();
6248 }
6249 //*************************************************************************************************
6250 
6251 
6252 //*************************************************************************************************
6277 template< bool RF // Relaxation flag
6278  , typename Type // Data type of the matrix
6279  , size_t M // Number of rows
6280  , size_t N // Number of columns
6281  , bool SO > // Storage order
6282 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m )
6283 {
6284  return ( m.rows() == 0UL && m.columns() == 0UL );
6285 }
6286 //*************************************************************************************************
6287 
6288 
6289 //*************************************************************************************************
6307 template< typename Type // Data type of the matrix
6308  , size_t M // Number of rows
6309  , size_t N // Number of columns
6310  , bool SO > // Storage order
6311 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m ) noexcept
6312 {
6313  return m.isIntact();
6314 }
6315 //*************************************************************************************************
6316 
6317 
6318 //*************************************************************************************************
6326 template< typename Type // Data type of the matrix
6327  , size_t M // Number of rows
6328  , size_t N // Number of columns
6329  , bool SO > // Storage order
6331 {
6332  a.swap( b );
6333 }
6334 //*************************************************************************************************
6335 
6336 
6337 
6338 
6339 //=================================================================================================
6340 //
6341 // HASCONSTDATAACCESS SPECIALIZATIONS
6342 //
6343 //=================================================================================================
6344 
6345 //*************************************************************************************************
6347 template< typename T, size_t M, size_t N, bool SO >
6348 struct HasConstDataAccess< HybridMatrix<T,M,N,SO> > : public TrueType
6349 {};
6351 //*************************************************************************************************
6352 
6353 
6354 
6355 
6356 //=================================================================================================
6357 //
6358 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6359 //
6360 //=================================================================================================
6361 
6362 //*************************************************************************************************
6364 template< typename T, size_t M, size_t N, bool SO >
6365 struct HasMutableDataAccess< HybridMatrix<T,M,N,SO> > : public TrueType
6366 {};
6368 //*************************************************************************************************
6369 
6370 
6371 
6372 
6373 //=================================================================================================
6374 //
6375 // ISALIGNED SPECIALIZATIONS
6376 //
6377 //=================================================================================================
6378 
6379 //*************************************************************************************************
6381 template< typename T, size_t M, size_t N, bool SO >
6382 struct IsAligned< HybridMatrix<T,M,N,SO> > : public BoolConstant<usePadding>
6383 {};
6385 //*************************************************************************************************
6386 
6387 
6388 
6389 
6390 //=================================================================================================
6391 //
6392 // ISPADDED SPECIALIZATIONS
6393 //
6394 //=================================================================================================
6395 
6396 //*************************************************************************************************
6398 template< typename T, size_t M, size_t N, bool SO >
6399 struct IsPadded< HybridMatrix<T,M,N,SO> > : public BoolConstant<usePadding>
6400 {};
6402 //*************************************************************************************************
6403 
6404 
6405 
6406 
6407 //=================================================================================================
6408 //
6409 // ISRESIZABLE SPECIALIZATIONS
6410 //
6411 //=================================================================================================
6412 
6413 //*************************************************************************************************
6415 template< typename T, size_t M, size_t N, bool SO >
6416 struct IsResizable< HybridMatrix<T,M,N,SO> > : public TrueType
6417 {};
6419 //*************************************************************************************************
6420 
6421 
6422 
6423 
6424 //=================================================================================================
6425 //
6426 // ADDTRAIT SPECIALIZATIONS
6427 //
6428 //=================================================================================================
6429 
6430 //*************************************************************************************************
6432 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6433 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6434 {
6435  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, SO >;
6436 };
6437 
6438 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6439 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6440 {
6441  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, false >;
6442 };
6443 
6444 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6445 struct AddTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6446 {
6447  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, SO >;
6448 };
6449 
6450 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6451 struct AddTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6452 {
6453  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, false >;
6454 };
6455 
6456 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6457 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6458 {
6459  using Type = HybridMatrix< AddTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6460 };
6461 
6462 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6463 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6464 {
6465  using Type = HybridMatrix< AddTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6466 };
6468 //*************************************************************************************************
6469 
6470 
6471 
6472 
6473 //=================================================================================================
6474 //
6475 // SUBTRAIT SPECIALIZATIONS
6476 //
6477 //=================================================================================================
6478 
6479 //*************************************************************************************************
6481 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6482 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6483 {
6484  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, SO >;
6485 };
6486 
6487 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6488 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6489 {
6490  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, false >;
6491 };
6492 
6493 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6494 struct SubTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6495 {
6496  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, SO >;
6497 };
6498 
6499 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6500 struct SubTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6501 {
6502  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, false >;
6503 };
6504 
6505 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6506 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6507 {
6508  using Type = HybridMatrix< SubTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6509 };
6510 
6511 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6512 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6513 {
6514  using Type = HybridMatrix< SubTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6515 };
6517 //*************************************************************************************************
6518 
6519 
6520 
6521 
6522 //=================================================================================================
6523 //
6524 // MULTTRAIT SPECIALIZATIONS
6525 //
6526 //=================================================================================================
6527 
6528 //*************************************************************************************************
6530 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6531 struct MultTrait< HybridMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6532 {
6533  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6534 };
6535 
6536 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6537 struct MultTrait< T1, HybridMatrix<T2,M,N,SO>, EnableIf_<IsNumeric<T1> > >
6538 {
6539  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6540 };
6541 
6542 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6543 struct MultTrait< HybridMatrix<T1,M,N,SO>, StaticVector<T2,K,false> >
6544 {
6545  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6546 };
6547 
6548 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6549 struct MultTrait< StaticVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6550 {
6551  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6552 };
6553 
6554 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6555 struct MultTrait< HybridMatrix<T1,M,N,SO>, HybridVector<T2,K,false> >
6556 {
6557  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6558 };
6559 
6560 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6561 struct MultTrait< HybridVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6562 {
6563  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6564 };
6565 
6566 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6567 struct MultTrait< HybridMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
6568 {
6569  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6570 };
6571 
6572 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6573 struct MultTrait< DynamicVector<T1,true>, HybridMatrix<T2,M,N,SO> >
6574 {
6575  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6576 };
6577 
6578 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6579 struct MultTrait< HybridMatrix<T1,M,N,SO>, CustomVector<T2,AF,PF,false> >
6580 {
6581  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6582 };
6583 
6584 template< typename T1, bool AF, bool PF, typename T2, size_t M, size_t N, bool SO >
6585 struct MultTrait< CustomVector<T1,AF,PF,true>, HybridMatrix<T2,M,N,SO> >
6586 {
6587  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6588 };
6589 
6590 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6591 struct MultTrait< HybridMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
6592 {
6593  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6594 };
6595 
6596 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6597 struct MultTrait< CompressedVector<T1,true>, HybridMatrix<T2,M,N,SO> >
6598 {
6599  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6600 };
6601 
6602 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6603 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6604 {
6605  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
6606 };
6607 
6608 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6609 struct MultTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6610 {
6611  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
6612 };
6613 
6614 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6615 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6616 {
6617  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
6618 };
6620 //*************************************************************************************************
6621 
6622 
6623 
6624 
6625 //=================================================================================================
6626 //
6627 // DIVTRAIT SPECIALIZATIONS
6628 //
6629 //=================================================================================================
6630 
6631 //*************************************************************************************************
6633 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6634 struct DivTrait< HybridMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6635 {
6636  using Type = HybridMatrix< DivTrait_<T1,T2>, M, N, SO >;
6637 };
6639 //*************************************************************************************************
6640 
6641 
6642 
6643 
6644 //=================================================================================================
6645 //
6646 // HIGHTYPE SPECIALIZATIONS
6647 //
6648 //=================================================================================================
6649 
6650 //*************************************************************************************************
6652 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6653 struct HighType< HybridMatrix<T1,M,N,SO>, HybridMatrix<T2,M,N,SO> >
6654 {
6655  using Type = HybridMatrix< typename HighType<T1,T2>::Type, M, N, SO >;
6656 };
6658 //*************************************************************************************************
6659 
6660 
6661 
6662 
6663 //=================================================================================================
6664 //
6665 // LOWTYPE SPECIALIZATIONS
6666 //
6667 //=================================================================================================
6668 
6669 //*************************************************************************************************
6671 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6672 struct LowType< HybridMatrix<T1,M,N,SO>, HybridMatrix<T2,M,N,SO> >
6673 {
6674  using Type = HybridMatrix< typename LowType<T1,T2>::Type, M, N, SO >;
6675 };
6677 //*************************************************************************************************
6678 
6679 
6680 
6681 
6682 //=================================================================================================
6683 //
6684 // SUBMATRIXTRAIT SPECIALIZATIONS
6685 //
6686 //=================================================================================================
6687 
6688 //*************************************************************************************************
6690 template< typename T1, size_t M, size_t N, bool SO >
6691 struct SubmatrixTrait< HybridMatrix<T1,M,N,SO> >
6692 {
6693  using Type = HybridMatrix<T1,M,N,SO>;
6694 };
6696 //*************************************************************************************************
6697 
6698 
6699 
6700 
6701 //=================================================================================================
6702 //
6703 // ROWTRAIT SPECIALIZATIONS
6704 //
6705 //=================================================================================================
6706 
6707 //*************************************************************************************************
6709 template< typename T1, size_t M, size_t N, bool SO >
6710 struct RowTrait< HybridMatrix<T1,M,N,SO> >
6711 {
6712  using Type = HybridVector<T1,N,true>;
6713 };
6715 //*************************************************************************************************
6716 
6717 
6718 
6719 
6720 //=================================================================================================
6721 //
6722 // COLUMNTRAIT SPECIALIZATIONS
6723 //
6724 //=================================================================================================
6725 
6726 //*************************************************************************************************
6728 template< typename T1, size_t M, size_t N, bool SO >
6729 struct ColumnTrait< HybridMatrix<T1,M,N,SO> >
6730 {
6731  using Type = HybridVector<T1,M,false>;
6732 };
6734 //*************************************************************************************************
6735 
6736 } // namespace blaze
6737 
6738 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:133
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_CONST(T)
Constraint on the data type.In case the given data type is a const-qualified type, a compilation error is created.
Definition: Const.h:79
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Header file for auxiliary alias declarations.
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:79
Availability of a SIMD subtraction for the given data types.Depending on the available instruction se...
Definition: HasSIMDSub.h:163
Header file for mathematical functions.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
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:1263
Header file for the subtraction trait.
Type ElementType
Type of the matrix elements.
Definition: HybridMatrix.h:221
Header file for basic type definitions.
Header file for the row trait.
Base template for the SubmatrixTrait class.
Definition: SubmatrixTrait.h:118
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:117
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.
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:261
Generic wrapper for a compile time constant integral value.The IntegralConstant class template repres...
Definition: IntegralConstant.h:71
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
Header file for the IsSame and IsStrictlySame type traits.
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:315
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1143
Header file for the IsColumnMajorMatrix type trait.
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: HybridMatrix.h:995
constexpr size_t spacing() const noexcept
Returns the spacing between the beginning of two rows.
Definition: HybridMatrix.h:1705
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: HybridMatrix.h:229
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
Availability of a SIMD addition for the given data types.Depending on the available instruction set (...
Definition: HasSIMDAdd.h:163
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1215
#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
const Type & ConstReference
Reference to a constant matrix value.
Definition: HybridMatrix.h:227
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: HybridMatrix.h:222
Type relationship analysis.This class tests if the two data types A and B are equal. For this type comparison, the cv-qualifiers of both data types are ignored. If A and B are the same data type (ignoring the cv-qualifiers), then the value member constant is set to true, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to false, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:138
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: HybridMatrix.h:1670
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
Header file for memory allocation and deallocation functionality.
System settings for performance optimizations.
HybridMatrix< Type, N, M,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: HybridMatrix.h:220
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1191
Type & Reference
Reference to a non-constant matrix value.
Definition: HybridMatrix.h:226
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1321
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:323
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1802
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:71
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:119
Constraint on the data type.
Header file for the std::initializer_list aliases.
Header file for the SparseMatrix base class.
Efficient implementation of a dynamically sized vector with static memory.The HybridVector class temp...
Definition: Forward.h:59
Compile time check for low-level access to mutable data.This type trait tests whether the given data ...
Definition: HasMutableDataAccess.h:75
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: HybridMatrix.h:2426
Compile time check for the alignment of data types.This type trait tests whether the given data type ...
Definition: IsAligned.h:87
const This & CompositeType
Data type for composite expression templates.
Definition: HybridMatrix.h:224
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: HybridMatrix.h:1912
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: HybridMatrix.h:1763
Base template for the RowTrait class.
Definition: RowTrait.h:117
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:143
Header file for the DisableIf class template.
Header file for the 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.
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:143
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5635
HybridMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: HybridMatrix.h:1289
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:2625
Compile time check for row-major matrix types.This type trait tests whether or not the given template...
Definition: IsRowMajorMatrix.h:83
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:2556
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
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:537
Type * Pointer
Pointer to a non-constant matrix value.
Definition: HybridMatrix.h:228
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:946
const Type & ReturnType
Return type for expression template evaluations.
Definition: HybridMatrix.h:223
Header file for the IsLower type trait.
size_t m_
The current number of rows of the matrix.
Definition: HybridMatrix.h:501
Header file for the IsAligned type trait.
HybridMatrix< Type, M, N, SO > This
Type of this HybridMatrix instance.
Definition: HybridMatrix.h:216
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
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:1817
Header file for the exception macros of the math module.
HybridMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: HybridMatrix.h:2076
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:249
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:553
Header file for the IsPadded type trait.
Header file for the IsVectorizable type trait.
HybridMatrix< Type, M, N,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: HybridMatrix.h:219
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:2662
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:1979
Header file for the IsSIMDCombinable type trait.
AlignedArray< Type, M *NN > v_
The statically allocated matrix elements.
Definition: HybridMatrix.h:491
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:2587
#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
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:261
HybridMatrix< NewType, M, N, SO > Other
The type of the other HybridMatrix.
Definition: HybridMatrix.h:240
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: HybridMatrix.h:1054
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1285
size_t determineColumns(initializer_list< initializer_list< Type > > list) noexcept
Determine the maximum number of columns specified by the given initializer list.
Definition: InitializerList.h:80
DenseMatrix< This, SO > BaseType
Base type of this HybridMatrix instance.
Definition: HybridMatrix.h:217
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:143
Compile time check for column-major matrix types.This type trait tests whether or not the given templ...
Definition: IsColumnMajorMatrix.h:83
HybridMatrix & transpose()
In-place transpose of the matrix.
Definition: HybridMatrix.h:2021
Base template for the MultTrait class.
Definition: MultTrait.h:143
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:2520
Header file for the division trait.
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: HybridMatrix.h:218
Constraint on the data type.
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: HybridMatrix.h:231
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:2384
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:94
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
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:225
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: HybridMatrix.h:2453
Base template for the DivTrait class.
Definition: DivTrait.h:143
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric< T >::value)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
Rebind mechanism to obtain a HybridMatrix with different data/element type.
Definition: HybridMatrix.h:239
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
DenseIterator< const Type, usePadding > ConstIterator
Iterator over constant elements.
Definition: HybridMatrix.h:232
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
constexpr bool usePadding
Configuration of the padding of dense vectors and matrices.This configuration switch enables/disables...
Definition: Optimizations.h:52
Header file for the IsRowMajorMatrix type trait.
Initializer list type of the Blaze library.
Header file for the alignment check function.
typename InvExprTrait< T >::Type InvExprTrait_
Auxiliary alias declaration for the InvExprTrait class template.The InvExprTrait_ alias declaration p...
Definition: InvExprTrait.h:134
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:2483
size_t n_
The current number of columns of the matrix.
Definition: HybridMatrix.h:502
Header file for the IntegralConstant class template.
void clear()
Clearing the hybrid matrix.
Definition: HybridMatrix.h:1865
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:78
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Base template for the SubTrait class.
Definition: SubTrait.h:143
#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:1303
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:1961
#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
Header file for the IsResizable type trait.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: HybridMatrix.h:1686
System settings for the inline keywords.
HybridMatrix< Type, NewM, NewN, SO > Other
The type of the other HybridMatrix.
Definition: HybridMatrix.h:250
#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:1721
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: HybridMatrix.h:2406
bool isIntact() const noexcept
Returns whether the invariants of the hybrid matrix are intact.
Definition: HybridMatrix.h:2334
Header file for the HighType type trait.
Header file for the TrueType type/value trait base class.
constexpr bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56