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>
87 #include <blaze/system/Inline.h>
92 #include <blaze/util/Assert.h>
99 #include <blaze/util/DisableIf.h>
100 #include <blaze/util/EnableIf.h>
102 #include <blaze/util/Memory.h>
104 #include <blaze/util/mpl/SizeT.h>
105 #include <blaze/util/StaticAssert.h>
106 #include <blaze/util/Template.h>
107 #include <blaze/util/TrueType.h>
108 #include <blaze/util/Types.h>
112 #include <blaze/util/Unused.h>
113 
114 
115 namespace blaze {
116 
117 //=================================================================================================
118 //
119 // CLASS DEFINITION
120 //
121 //=================================================================================================
122 
123 //*************************************************************************************************
209 template< typename Type // Data type of the matrix
210  , size_t M // Number of rows
211  , size_t N // Number of columns
212  , bool SO = defaultStorageOrder > // Storage order
213 class HybridMatrix : public DenseMatrix< HybridMatrix<Type,M,N,SO>, SO >
214 {
215  public:
216  //**Type definitions****************************************************************************
219  typedef This ResultType;
222  typedef Type ElementType;
224  typedef const Type& ReturnType;
225  typedef const This& CompositeType;
226 
227  typedef Type& Reference;
228  typedef const Type& ConstReference;
229  typedef Type* Pointer;
230  typedef const Type* ConstPointer;
231 
234  //**********************************************************************************************
235 
236  //**Rebind struct definition********************************************************************
239  template< typename ET > // Data type of the other matrix
240  struct Rebind {
242  };
243  //**********************************************************************************************
244 
245  //**Compilation flags***************************************************************************
247 
251  enum : bool { simdEnabled = IsVectorizable<Type>::value };
252 
254 
257  enum : bool { smpAssignable = false };
258  //**********************************************************************************************
259 
260  //**Constructors********************************************************************************
263  explicit inline HybridMatrix();
264  explicit inline HybridMatrix( size_t m, size_t n );
265  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
266  explicit inline HybridMatrix( initializer_list< initializer_list<Type> > list );
267 
268  template< typename Other >
269  explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
270 
271  template< typename Other, size_t M2, size_t N2 >
272  explicit inline HybridMatrix( const Other (&array)[M2][N2] );
273 
274  inline HybridMatrix( const HybridMatrix& m );
275  template< typename MT, bool SO2 > inline HybridMatrix( const Matrix<MT,SO2>& m );
277  //**********************************************************************************************
278 
279  //**Destructor**********************************************************************************
280  // No explicitly declared destructor.
281  //**********************************************************************************************
282 
283  //**Data access functions***********************************************************************
286  inline Reference operator()( size_t i, size_t j ) noexcept;
287  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
288  inline Reference at( size_t i, size_t j );
289  inline ConstReference at( size_t i, size_t j ) const;
290  inline Pointer data () noexcept;
291  inline ConstPointer data () const noexcept;
292  inline Pointer data ( size_t i ) noexcept;
293  inline ConstPointer data ( size_t i ) const noexcept;
294  inline Iterator begin ( size_t i ) noexcept;
295  inline ConstIterator begin ( size_t i ) const noexcept;
296  inline ConstIterator cbegin( size_t i ) const noexcept;
297  inline Iterator end ( size_t i ) noexcept;
298  inline ConstIterator end ( size_t i ) const noexcept;
299  inline ConstIterator cend ( size_t i ) const noexcept;
301  //**********************************************************************************************
302 
303  //**Assignment operators************************************************************************
306  inline HybridMatrix& operator=( const Type& set );
307  inline HybridMatrix& operator=( initializer_list< initializer_list<Type> > list );
308 
309  template< typename Other, size_t M2, size_t N2 >
310  inline HybridMatrix& operator=( const Other (&array)[M2][N2] );
311 
312  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
313  template< typename MT, bool SO2 > inline HybridMatrix& operator= ( const Matrix<MT,SO2>& rhs );
314  template< typename MT, bool SO2 > inline HybridMatrix& operator+=( const Matrix<MT,SO2>& rhs );
315  template< typename MT, bool SO2 > inline HybridMatrix& operator-=( const Matrix<MT,SO2>& rhs );
316  template< typename MT, bool SO2 > inline HybridMatrix& operator*=( const Matrix<MT,SO2>& rhs );
317 
318  template< typename Other >
319  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator*=( Other rhs );
320 
321  template< typename Other >
322  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator/=( Other rhs );
324  //**********************************************************************************************
325 
326  //**Utility functions***************************************************************************
329  inline size_t rows() const noexcept;
330  inline size_t columns() const noexcept;
331  inline constexpr size_t spacing() const noexcept;
332  inline constexpr size_t capacity() const noexcept;
333  inline size_t capacity( size_t i ) const noexcept;
334  inline size_t nonZeros() const;
335  inline size_t nonZeros( size_t i ) const;
336  inline void reset();
337  inline void reset( size_t i );
338  inline void clear();
339  void resize ( size_t m, size_t n, bool preserve=true );
340  inline void extend ( size_t m, size_t n, bool preserve=true );
341  inline HybridMatrix& transpose();
342  inline HybridMatrix& ctranspose();
343  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
344  inline void swap( HybridMatrix& m ) noexcept;
346  //**********************************************************************************************
347 
348  //**Memory functions****************************************************************************
351  static inline void* operator new ( std::size_t size );
352  static inline void* operator new[]( std::size_t size );
353  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
354  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
355 
356  static inline void operator delete ( void* ptr );
357  static inline void operator delete[]( void* ptr );
358  static inline void operator delete ( void* ptr, const std::nothrow_t& );
359  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
361  //**********************************************************************************************
362 
363  private:
364  //**********************************************************************************************
366  template< typename MT >
368  struct VectorizedAssign {
369  enum : bool { value = useOptimizedKernels &&
370  simdEnabled && MT::simdEnabled &&
371  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
372  IsRowMajorMatrix<MT>::value };
373  };
375  //**********************************************************************************************
376 
377  //**********************************************************************************************
379  template< typename MT >
381  struct VectorizedAddAssign {
382  enum : bool { value = useOptimizedKernels &&
383  simdEnabled && MT::simdEnabled &&
384  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
385  HasSIMDAdd< Type, ElementType_<MT> >::value &&
386  IsRowMajorMatrix<MT>::value &&
387  !IsDiagonal<MT>::value };
388  };
390  //**********************************************************************************************
391 
392  //**********************************************************************************************
394  template< typename MT >
396  struct VectorizedSubAssign {
397  enum : bool { value = useOptimizedKernels &&
398  simdEnabled && MT::simdEnabled &&
399  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
400  HasSIMDSub< Type, ElementType_<MT> >::value &&
401  IsRowMajorMatrix<MT>::value &&
402  !IsDiagonal<MT>::value };
403  };
405  //**********************************************************************************************
406 
407  //**********************************************************************************************
409  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
410  //**********************************************************************************************
411 
412  public:
413  //**Debugging functions*************************************************************************
416  inline bool isIntact() const noexcept;
418  //**********************************************************************************************
419 
420  //**Expression template evaluation functions****************************************************
423  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
424  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
425 
426  inline bool isAligned() const noexcept;
427 
428  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
429  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
430  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
431 
432  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
433  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
434  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
435  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
436 
437  template< typename MT, bool SO2 >
438  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
439 
440  template< typename MT, bool SO2 >
441  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO2>& rhs );
442 
443  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
444  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
445 
446  template< typename MT, bool SO2 >
447  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
448 
449  template< typename MT, bool SO2 >
450  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO2>& rhs );
451 
452  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
453  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
454 
455  template< typename MT, bool SO2 >
456  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
457 
458  template< typename MT, bool SO2 >
459  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO2>& rhs );
460 
461  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
462  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
464  //**********************************************************************************************
465 
466  private:
467  //**********************************************************************************************
469  enum : size_t { NN = ( usePadding )?( NextMultiple< SizeT<N>, SizeT<SIMDSIZE> >::value ):( N ) };
470  //**********************************************************************************************
471 
472  //**Member variables****************************************************************************
476 
485  size_t m_;
486  size_t n_;
487 
488  //**********************************************************************************************
489 
490  //**Compile time checks*************************************************************************
496  BLAZE_STATIC_ASSERT( !usePadding || NN % SIMDSIZE == 0UL );
497  BLAZE_STATIC_ASSERT( NN >= N );
499  //**********************************************************************************************
500 };
501 //*************************************************************************************************
502 
503 
504 
505 
506 //=================================================================================================
507 //
508 // CONSTRUCTORS
509 //
510 //=================================================================================================
511 
512 //*************************************************************************************************
517 template< typename Type // Data type of the matrix
518  , size_t M // Number of rows
519  , size_t N // Number of columns
520  , bool SO > // Storage order
522  : v_() // The statically allocated matrix elements
523  , m_( 0UL ) // The current number of rows of the matrix
524  , n_( 0UL ) // The current number of columns of the matrix
525 {
527 
528  if( IsNumeric<Type>::value ) {
529  for( size_t i=0UL; i<M*NN; ++i )
530  v_[i] = Type();
531  }
532 
533  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
534 }
535 //*************************************************************************************************
536 
537 
538 //*************************************************************************************************
551 template< typename Type // Data type of the matrix
552  , size_t M // Number of rows
553  , size_t N // Number of columns
554  , bool SO > // Storage order
555 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n )
556  : v_() // The statically allocated matrix elements
557  , m_( m ) // The current number of rows of the matrix
558  , n_( n ) // The current number of columns of the matrix
559 {
561 
562  if( m > M ) {
563  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
564  }
565 
566  if( n > N ) {
567  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
568  }
569 
570  if( IsNumeric<Type>::value ) {
571  for( size_t i=0UL; i<M*NN; ++i )
572  v_[i] = Type();
573  }
574 
575  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
576 }
577 //*************************************************************************************************
578 
579 
580 //*************************************************************************************************
594 template< typename Type // Data type of the matrix
595  , size_t M // Number of rows
596  , size_t N // Number of columns
597  , bool SO > // Storage order
598 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Type& init )
599  : v_() // The statically allocated matrix elements
600  , m_( m ) // The current number of rows of the matrix
601  , n_( n ) // The current number of columns of the matrix
602 {
604 
605  if( m > M ) {
606  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
607  }
608 
609  if( n > N ) {
610  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
611  }
612 
613  for( size_t i=0UL; i<m; ++i ) {
614  for( size_t j=0UL; j<n; ++j )
615  v_[i*NN+j] = init;
616 
617  if( IsNumeric<Type>::value ) {
618  for( size_t j=n; j<NN; ++j )
619  v_[i*NN+j] = Type();
620  }
621  }
622 
623  if( IsNumeric<Type>::value ) {
624  for( size_t i=m; i<M; ++i )
625  for( size_t j=0UL; j<NN; ++j )
626  v_[i*NN+j] = Type();
627  }
628 
629  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
630 }
631 //*************************************************************************************************
632 
633 
634 //*************************************************************************************************
658 template< typename Type // Data type of the matrix
659  , size_t M // Number of rows
660  , size_t N // Number of columns
661  , bool SO > // Storage order
663  : v_() // The statically allocated matrix elements
664  , m_( list.size() ) // The current number of rows of the matrix
665  , n_( determineColumns( list ) ) // The current number of columns of the matrix
666 {
668 
669  if( m_ > M ) {
670  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
671  }
672 
673  if( n_ > N ) {
674  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
675  }
676 
677  size_t i( 0UL );
678 
679  for( const auto& rowList : list ) {
680  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
681  ++i;
682  }
683 
684  if( IsNumeric<Type>::value ) {
685  for( ; i<M; ++i )
686  for( size_t j=0UL; j<NN; ++j )
687  v_[i*NN+j] = Type();
688  }
689 
690  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
691 }
692 //*************************************************************************************************
693 
694 
695 //*************************************************************************************************
722 template< typename Type // Data type of the matrix
723  , size_t M // Number of rows
724  , size_t N // Number of columns
725  , bool SO > // Storage order
726 template< typename Other > // Data type of the initialization array
727 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Other* array )
728  : v_() // The statically allocated matrix elements
729  , m_( m ) // The current number of rows of the matrix
730  , n_( n ) // The current number of columns of the matrix
731 {
733 
734  if( m > M ) {
735  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
736  }
737 
738  if( n > N ) {
739  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
740  }
741 
742  for( size_t i=0UL; i<m; ++i ) {
743  for( size_t j=0UL; j<n; ++j )
744  v_[i*NN+j] = array[i*n+j];
745 
746  if( IsNumeric<Type>::value ) {
747  for( size_t j=n; j<NN; ++j )
748  v_[i*NN+j] = Type();
749  }
750  }
751 
752  if( IsNumeric<Type>::value ) {
753  for( size_t i=m; i<M; ++i )
754  for( size_t j=0UL; j<NN; ++j )
755  v_[i*NN+j] = Type();
756  }
757 
758  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
759 }
760 //*************************************************************************************************
761 
762 
763 //*************************************************************************************************
784 template< typename Type // Data type of the matrix
785  , size_t M // Number of rows
786  , size_t N // Number of columns
787  , bool SO > // Storage order
788 template< typename Other // Data type of the initialization array
789  , size_t M2 // Number of rows of the initialization array
790  , size_t N2 > // Number of columns of the initialization array
791 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( const Other (&array)[M2][N2] )
792  : v_() // The statically allocated matrix elements
793  , m_( M2 ) // The current number of rows of the matrix
794  , n_( N2 ) // The current number of columns of the matrix
795 {
796  BLAZE_STATIC_ASSERT( M2 <= M );
797  BLAZE_STATIC_ASSERT( N2 <= N );
799 
800  for( size_t i=0UL; i<M2; ++i ) {
801  for( size_t j=0UL; j<N2; ++j )
802  v_[i*NN+j] = array[i][j];
803 
804  if( IsNumeric<Type>::value ) {
805  for( size_t j=N2; j<NN; ++j )
806  v_[i*NN+j] = Type();
807  }
808  }
809 
810  if( IsNumeric<Type>::value ) {
811  for( size_t i=M2; i<M; ++i )
812  for( size_t j=0UL; j<NN; ++j )
813  v_[i*NN+j] = Type();
814  }
815 
816  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
817 }
818 //*************************************************************************************************
819 
820 
821 //*************************************************************************************************
829 template< typename Type // Data type of the matrix
830  , size_t M // Number of rows
831  , size_t N // Number of columns
832  , bool SO > // Storage order
834  : v_() // The statically allocated matrix elements
835  , m_( m.m_ ) // The current number of rows of the matrix
836  , n_( m.n_ ) // The current number of columns of the matrix
837 {
839 
840  for( size_t i=0UL; i<m_; ++i ) {
841  for( size_t j=0UL; j<n_; ++j )
842  v_[i*NN+j] = m.v_[i*NN+j];
843 
844  if( IsNumeric<Type>::value ) {
845  for( size_t j=n_; j<NN; ++j )
846  v_[i*NN+j] = Type();
847  }
848  }
849 
850  if( IsNumeric<Type>::value ) {
851  for( size_t i=m_; i<M; ++i )
852  for( size_t j=0UL; j<NN; ++j )
853  v_[i*NN+j] = Type();
854  }
855 
856  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
857 }
858 //*************************************************************************************************
859 
860 
861 //*************************************************************************************************
867 template< typename Type // Data type of the matrix
868  , size_t M // Number of rows
869  , size_t N // Number of columns
870  , bool SO > // Storage order
871 template< typename MT // Type of the foreign matrix
872  , bool SO2 > // Storage order of the foreign matrix
874  : v_() // The statically allocated matrix elements
875  , m_( (~m).rows() ) // The current number of rows of the matrix
876  , n_( (~m).columns() ) // The current number of columns of the matrix
877 {
878  using blaze::assign;
879 
881 
882  if( (~m).rows() > M || (~m).columns() > N ) {
883  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
884  }
885 
886  for( size_t i=0UL; i<m_; ++i ) {
887  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : n_ );
888  j<( IsNumeric<Type>::value ? NN : n_ );
889  ++j ) {
890  v_[i*NN+j] = Type();
891  }
892  }
893 
894  if( IsNumeric<Type>::value ) {
895  for( size_t i=m_; i<M; ++i )
896  for( size_t j=0UL; j<NN; ++j )
897  v_[i*NN+j] = Type();
898  }
899 
900  assign( *this, ~m );
901 
902  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
903 }
904 //*************************************************************************************************
905 
906 
907 
908 
909 //=================================================================================================
910 //
911 // DATA ACCESS FUNCTIONS
912 //
913 //=================================================================================================
914 
915 //*************************************************************************************************
925 template< typename Type // Data type of the matrix
926  , size_t M // Number of rows
927  , size_t N // Number of columns
928  , bool SO > // Storage order
930  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) noexcept
931 {
932  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
933  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
934  return v_[i*NN+j];
935 }
936 //*************************************************************************************************
937 
938 
939 //*************************************************************************************************
949 template< typename Type // Data type of the matrix
950  , size_t M // Number of rows
951  , size_t N // Number of columns
952  , bool SO > // Storage order
954  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const noexcept
955 {
956  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
957  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
958  return v_[i*NN+j];
959 }
960 //*************************************************************************************************
961 
962 
963 //*************************************************************************************************
974 template< typename Type // Data type of the matrix
975  , size_t M // Number of rows
976  , size_t N // Number of columns
977  , bool SO > // Storage order
979  HybridMatrix<Type,M,N,SO>::at( size_t i, size_t j )
980 {
981  if( i >= m_ ) {
982  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
983  }
984  if( j >= n_ ) {
985  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
986  }
987  return (*this)(i,j);
988 }
989 //*************************************************************************************************
990 
991 
992 //*************************************************************************************************
1003 template< typename Type // Data type of the matrix
1004  , size_t M // Number of rows
1005  , size_t N // Number of columns
1006  , bool SO > // Storage order
1008  HybridMatrix<Type,M,N,SO>::at( size_t i, size_t j ) const
1009 {
1010  if( i >= m_ ) {
1011  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
1012  }
1013  if( j >= n_ ) {
1014  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
1015  }
1016  return (*this)(i,j);
1017 }
1018 //*************************************************************************************************
1019 
1020 
1021 //*************************************************************************************************
1033 template< typename Type // Data type of the matrix
1034  , size_t M // Number of rows
1035  , size_t N // Number of columns
1036  , bool SO > // Storage order
1037 inline typename HybridMatrix<Type,M,N,SO>::Pointer
1039 {
1040  return v_;
1041 }
1042 //*************************************************************************************************
1043 
1044 
1045 //*************************************************************************************************
1057 template< typename Type // Data type of the matrix
1058  , size_t M // Number of rows
1059  , size_t N // Number of columns
1060  , bool SO > // Storage order
1063 {
1064  return v_;
1065 }
1066 //*************************************************************************************************
1067 
1068 
1069 //*************************************************************************************************
1077 template< typename Type // Data type of the matrix
1078  , size_t M // Number of rows
1079  , size_t N // Number of columns
1080  , bool SO > // Storage order
1081 inline typename HybridMatrix<Type,M,N,SO>::Pointer
1082  HybridMatrix<Type,M,N,SO>::data( size_t i ) noexcept
1083 {
1084  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1085  return v_ + i*NN;
1086 }
1087 //*************************************************************************************************
1088 
1089 
1090 //*************************************************************************************************
1098 template< typename Type // Data type of the matrix
1099  , size_t M // Number of rows
1100  , size_t N // Number of columns
1101  , bool SO > // Storage order
1103  HybridMatrix<Type,M,N,SO>::data( size_t i ) const noexcept
1104 {
1105  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1106  return v_ + i*NN;
1107 }
1108 //*************************************************************************************************
1109 
1110 
1111 //*************************************************************************************************
1122 template< typename Type // Data type of the matrix
1123  , size_t M // Number of rows
1124  , size_t N // Number of columns
1125  , bool SO > // Storage order
1128 {
1129  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1130  return Iterator( v_ + i*NN );
1131 }
1132 //*************************************************************************************************
1133 
1134 
1135 //*************************************************************************************************
1146 template< typename Type // Data type of the matrix
1147  , size_t M // Number of rows
1148  , size_t N // Number of columns
1149  , bool SO > // Storage order
1151  HybridMatrix<Type,M,N,SO>::begin( size_t i ) const noexcept
1152 {
1153  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1154  return ConstIterator( v_ + i*NN );
1155 }
1156 //*************************************************************************************************
1157 
1158 
1159 //*************************************************************************************************
1170 template< typename Type // Data type of the matrix
1171  , size_t M // Number of rows
1172  , size_t N // Number of columns
1173  , bool SO > // Storage order
1175  HybridMatrix<Type,M,N,SO>::cbegin( size_t i ) const noexcept
1176 {
1177  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1178  return ConstIterator( v_ + i*NN );
1179 }
1180 //*************************************************************************************************
1181 
1182 
1183 //*************************************************************************************************
1194 template< typename Type // Data type of the matrix
1195  , size_t M // Number of rows
1196  , size_t N // Number of columns
1197  , bool SO > // Storage order
1199  HybridMatrix<Type,M,N,SO>::end( size_t i ) noexcept
1200 {
1201  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1202  return Iterator( v_ + i*NN + N );
1203 }
1204 //*************************************************************************************************
1205 
1206 
1207 //*************************************************************************************************
1218 template< typename Type // Data type of the matrix
1219  , size_t M // Number of rows
1220  , size_t N // Number of columns
1221  , bool SO > // Storage order
1223  HybridMatrix<Type,M,N,SO>::end( size_t i ) const noexcept
1224 {
1225  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1226  return ConstIterator( v_ + i*NN + N );
1227 }
1228 //*************************************************************************************************
1229 
1230 
1231 //*************************************************************************************************
1242 template< typename Type // Data type of the matrix
1243  , size_t M // Number of rows
1244  , size_t N // Number of columns
1245  , bool SO > // Storage order
1247  HybridMatrix<Type,M,N,SO>::cend( size_t i ) const noexcept
1248 {
1249  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1250  return ConstIterator( v_ + i*NN + N );
1251 }
1252 //*************************************************************************************************
1253 
1254 
1255 
1256 
1257 //=================================================================================================
1258 //
1259 // ASSIGNMENT OPERATORS
1260 //
1261 //=================================================================================================
1262 
1263 //*************************************************************************************************
1269 template< typename Type // Data type of the matrix
1270  , size_t M // Number of rows
1271  , size_t N // Number of columns
1272  , bool SO > // Storage order
1274 {
1275  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1276  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1277 
1278  for( size_t i=0UL; i<m_; ++i )
1279  for( size_t j=0UL; j<n_; ++j )
1280  v_[i*NN+j] = set;
1281 
1282  return *this;
1283 }
1284 //*************************************************************************************************
1285 
1286 
1287 //*************************************************************************************************
1312 template< typename Type // Data type of the matrix
1313  , size_t M // Number of rows
1314  , size_t N // Number of columns
1315  , bool SO > // Storage order
1318 {
1319  const size_t m( list.size() );
1320  const size_t n( determineColumns( list ) );
1321 
1322  if( m > M ) {
1323  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1324  }
1325 
1326  if( n > N ) {
1327  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1328  }
1329 
1330  resize( m, n, false );
1331 
1332  size_t i( 0UL );
1333 
1334  for( const auto& rowList : list ) {
1335  std::fill( std::copy( rowList.begin(), rowList.end(), v_+i*NN ), v_+(i+1UL)*NN, Type() );
1336  ++i;
1337  }
1338 
1339  return *this;
1340 }
1341 //*************************************************************************************************
1342 
1343 
1344 //*************************************************************************************************
1365 template< typename Type // Data type of the matrix
1366  , size_t M // Number of rows
1367  , size_t N // Number of columns
1368  , bool SO > // Storage order
1369 template< typename Other // Data type of the initialization array
1370  , size_t M2 // Number of rows of the initialization array
1371  , size_t N2 > // Number of columns of the initialization array
1373 {
1374  BLAZE_STATIC_ASSERT( M2 <= M );
1375  BLAZE_STATIC_ASSERT( N2 <= N );
1376 
1377  resize( M2, N2 );
1378 
1379  for( size_t i=0UL; i<M2; ++i )
1380  for( size_t j=0UL; j<N2; ++j )
1381  v_[i*NN+j] = array[i][j];
1382 
1383  return *this;
1384 }
1385 //*************************************************************************************************
1386 
1387 
1388 //*************************************************************************************************
1396 template< typename Type // Data type of the matrix
1397  , size_t M // Number of rows
1398  , size_t N // Number of columns
1399  , bool SO > // Storage order
1401 {
1402  using blaze::assign;
1403 
1404  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1405  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1406 
1407  resize( rhs.rows(), rhs.columns() );
1408  assign( *this, ~rhs );
1409 
1410  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1411 
1412  return *this;
1413 }
1414 //*************************************************************************************************
1415 
1416 
1417 //*************************************************************************************************
1428 template< typename Type // Data type of the matrix
1429  , size_t M // Number of rows
1430  , size_t N // Number of columns
1431  , bool SO > // Storage order
1432 template< typename MT // Type of the right-hand side matrix
1433  , bool SO2 > // Storage order of the right-hand side matrix
1435 {
1436  using blaze::assign;
1437 
1438  typedef TransExprTrait_<This> TT;
1439  typedef CTransExprTrait_<This> CT;
1440  typedef InvExprTrait_<This> IT;
1441 
1442  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
1443  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
1444  }
1445 
1446  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1447  transpose();
1448  }
1449  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1450  ctranspose();
1451  }
1452  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
1453  HybridMatrix tmp( ~rhs );
1454  resize( tmp.rows(), tmp.columns() );
1455  assign( *this, tmp );
1456  }
1457  else {
1458  resize( (~rhs).rows(), (~rhs).columns() );
1460  reset();
1461  assign( *this, ~rhs );
1462  }
1463 
1464  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1465 
1466  return *this;
1467 }
1468 //*************************************************************************************************
1469 
1470 
1471 //*************************************************************************************************
1481 template< typename Type // Data type of the matrix
1482  , size_t M // Number of rows
1483  , size_t N // Number of columns
1484  , bool SO > // Storage order
1485 template< typename MT // Type of the right-hand side matrix
1486  , bool SO2 > // Storage order of the right-hand side matrix
1488 {
1489  using blaze::addAssign;
1490 
1491  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1492  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1493  }
1494 
1495  if( (~rhs).canAlias( this ) ) {
1496  const ResultType_<MT> tmp( ~rhs );
1497  addAssign( *this, tmp );
1498  }
1499  else {
1500  addAssign( *this, ~rhs );
1501  }
1502 
1503  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1504 
1505  return *this;
1506 }
1507 //*************************************************************************************************
1508 
1509 
1510 //*************************************************************************************************
1520 template< typename Type // Data type of the matrix
1521  , size_t M // Number of rows
1522  , size_t N // Number of columns
1523  , bool SO > // Storage order
1524 template< typename MT // Type of the right-hand side matrix
1525  , bool SO2 > // Storage order of the right-hand side matrix
1527 {
1528  using blaze::subAssign;
1529 
1530  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1531  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1532  }
1533 
1534  if( (~rhs).canAlias( this ) ) {
1535  const ResultType_<MT> tmp( ~rhs );
1536  subAssign( *this, tmp );
1537  }
1538  else {
1539  subAssign( *this, ~rhs );
1540  }
1541 
1542  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1543 
1544  return *this;
1545 }
1546 //*************************************************************************************************
1547 
1548 
1549 //*************************************************************************************************
1559 template< typename Type // Data type of the matrix
1560  , size_t M // Number of rows
1561  , size_t N // Number of columns
1562  , bool SO > // Storage order
1563 template< typename MT // Type of the right-hand side matrix
1564  , bool SO2 > // Storage order of the right-hand side matrix
1566 {
1567  if( n_ != (~rhs).rows() || (~rhs).columns() > N ) {
1568  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1569  }
1570 
1571  const HybridMatrix tmp( *this * (~rhs) );
1572  this->operator=( tmp );
1573 
1574  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1575 
1576  return *this;
1577 }
1578 //*************************************************************************************************
1579 
1580 
1581 //*************************************************************************************************
1588 template< typename Type // Data type of the matrix
1589  , size_t M // Number of rows
1590  , size_t N // Number of columns
1591  , bool SO > // Storage order
1592 template< typename Other > // Data type of the right-hand side scalar
1595 {
1596  using blaze::assign;
1597 
1598  assign( *this, (*this) * rhs );
1599 
1600  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1601 
1602  return *this;
1603 }
1604 //*************************************************************************************************
1605 
1606 
1607 //*************************************************************************************************
1616 template< typename Type // Data type of the matrix
1617  , size_t M // Number of rows
1618  , size_t N // Number of columns
1619  , bool SO > // Storage order
1620 template< typename Other > // Data type of the right-hand side scalar
1621 inline EnableIf_<IsNumeric<Other>, HybridMatrix<Type,M,N,SO> >&
1623 {
1624  using blaze::assign;
1625 
1626  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1627 
1628  assign( *this, (*this) / rhs );
1629 
1630  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
1631 
1632  return *this;
1633 }
1634 //*************************************************************************************************
1635 
1636 
1637 
1638 
1639 //=================================================================================================
1640 //
1641 // UTILITY FUNCTIONS
1642 //
1643 //=================================================================================================
1644 
1645 //*************************************************************************************************
1650 template< typename Type // Data type of the matrix
1651  , size_t M // Number of rows
1652  , size_t N // Number of columns
1653  , bool SO > // Storage order
1654 inline size_t HybridMatrix<Type,M,N,SO>::rows() const noexcept
1655 {
1656  return m_;
1657 }
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>::columns() const noexcept
1671 {
1672  return n_;
1673 }
1674 //*************************************************************************************************
1675 
1676 
1677 //*************************************************************************************************
1685 template< typename Type // Data type of the matrix
1686  , size_t M // Number of rows
1687  , size_t N // Number of columns
1688  , bool SO > // Storage order
1689 inline constexpr size_t HybridMatrix<Type,M,N,SO>::spacing() const noexcept
1690 {
1691  return NN;
1692 }
1693 //*************************************************************************************************
1694 
1695 
1696 //*************************************************************************************************
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>::capacity() const noexcept
1706 {
1707  return M*NN;
1708 }
1709 //*************************************************************************************************
1710 
1711 
1712 //*************************************************************************************************
1723 template< typename Type // Data type of the matrix
1724  , size_t M // Number of rows
1725  , size_t N // Number of columns
1726  , bool SO > // Storage order
1727 inline size_t HybridMatrix<Type,M,N,SO>::capacity( size_t i ) const noexcept
1728 {
1729  UNUSED_PARAMETER( i );
1730 
1731  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1732 
1733  return NN;
1734 }
1735 //*************************************************************************************************
1736 
1737 
1738 //*************************************************************************************************
1743 template< typename Type // Data type of the matrix
1744  , size_t M // Number of rows
1745  , size_t N // Number of columns
1746  , bool SO > // Storage order
1748 {
1749  size_t nonzeros( 0UL );
1750 
1751  for( size_t i=0UL; i<m_; ++i )
1752  for( size_t j=0UL; j<n_; ++j )
1753  if( !isDefault( v_[i*NN+j] ) )
1754  ++nonzeros;
1755 
1756  return nonzeros;
1757 }
1758 //*************************************************************************************************
1759 
1760 
1761 //*************************************************************************************************
1772 template< typename Type // Data type of the matrix
1773  , size_t M // Number of rows
1774  , size_t N // Number of columns
1775  , bool SO > // Storage order
1776 inline size_t HybridMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1777 {
1778  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1779 
1780  const size_t jend( i*NN + n_ );
1781  size_t nonzeros( 0UL );
1782 
1783  for( size_t j=i*NN; j<jend; ++j )
1784  if( !isDefault( v_[j] ) )
1785  ++nonzeros;
1786 
1787  return nonzeros;
1788 }
1789 //*************************************************************************************************
1790 
1791 
1792 //*************************************************************************************************
1797 template< typename Type // Data type of the matrix
1798  , size_t M // Number of rows
1799  , size_t N // Number of columns
1800  , bool SO > // Storage order
1802 {
1803  using blaze::clear;
1804 
1805  for( size_t i=0UL; i<m_; ++i )
1806  for( size_t j=0UL; j<n_; ++j )
1807  clear( v_[i*NN+j] );
1808 }
1809 //*************************************************************************************************
1810 
1811 
1812 //*************************************************************************************************
1823 template< typename Type // Data type of the matrix
1824  , size_t M // Number of rows
1825  , size_t N // Number of columns
1826  , bool SO > // Storage order
1827 inline void HybridMatrix<Type,M,N,SO>::reset( size_t i )
1828 {
1829  using blaze::clear;
1830 
1831  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1832  for( size_t j=0UL; j<n_; ++j )
1833  clear( v_[i*NN+j] );
1834 }
1835 //*************************************************************************************************
1836 
1837 
1838 //*************************************************************************************************
1845 template< typename Type // Data type of the matrix
1846  , size_t M // Number of rows
1847  , size_t N // Number of columns
1848  , bool SO > // Storage order
1850 {
1851  resize( 0UL, 0UL );
1852 }
1853 //*************************************************************************************************
1854 
1855 
1856 //*************************************************************************************************
1892 template< typename Type // Data type of the matrix
1893  , size_t M // Number of rows
1894  , size_t N // Number of columns
1895  , bool SO > // Storage order
1896 void HybridMatrix<Type,M,N,SO>::resize( size_t m, size_t n, bool preserve )
1897 {
1898  UNUSED_PARAMETER( preserve );
1899 
1900  if( m > M ) {
1901  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1902  }
1903 
1904  if( n > N ) {
1905  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1906  }
1907 
1908  if( IsVectorizable<Type>::value && n < n_ ) {
1909  for( size_t i=0UL; i<m; ++i )
1910  for( size_t j=n; j<n_; ++j )
1911  v_[i*NN+j] = Type();
1912  }
1913 
1914  if( IsVectorizable<Type>::value && m < m_ ) {
1915  for( size_t i=m; i<m_; ++i )
1916  for( size_t j=0UL; j<n_; ++j )
1917  v_[i*NN+j] = Type();
1918  }
1919 
1920  m_ = m;
1921  n_ = n;
1922 }
1923 //*************************************************************************************************
1924 
1925 
1926 //*************************************************************************************************
1941 template< typename Type // Data type of the matrix
1942  , size_t M // Number of rows
1943  , size_t N // Number of columns
1944  , bool SO > // Storage order
1945 inline void HybridMatrix<Type,M,N,SO>::extend( size_t m, size_t n, bool preserve )
1946 {
1947  UNUSED_PARAMETER( preserve );
1948  resize( m_+m, n_+n );
1949 }
1950 //*************************************************************************************************
1951 
1952 
1953 //*************************************************************************************************
1964 template< typename Type // Data type of the matrix
1965  , size_t M // Number of rows
1966  , size_t N // Number of columns
1967  , bool SO > // Storage order
1969 {
1970  using std::swap;
1971 
1972  if( m_ > N || n_ > M ) {
1973  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1974  }
1975 
1976  const size_t maxsize( max( m_, n_ ) );
1977  for( size_t i=1UL; i<maxsize; ++i ) {
1978  for( size_t j=0UL; j<i; ++j ) {
1979  swap( v_[i*NN+j], v_[j*NN+i] );
1980  }
1981  }
1982 
1983  if( IsVectorizable<Type>::value && m_ < n_ ) {
1984  for( size_t i=0UL; i<m_; ++i ) {
1985  for( size_t j=m_; j<n_; ++j ) {
1986  v_[i*NN+j] = Type();
1987  }
1988  }
1989  }
1990 
1991  if( IsVectorizable<Type>::value && m_ > n_ ) {
1992  for( size_t i=n_; i<m_; ++i ) {
1993  for( size_t j=0UL; j<n_; ++j ) {
1994  v_[i*NN+j] = Type();
1995  }
1996  }
1997  }
1998 
1999  swap( m_, n_ );
2000 
2001  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2002 
2003  return *this;
2004 }
2005 //*************************************************************************************************
2006 
2007 
2008 //*************************************************************************************************
2019 template< typename Type // Data type of the matrix
2020  , size_t M // Number of rows
2021  , size_t N // Number of columns
2022  , bool SO > // Storage order
2024 {
2025  using std::swap;
2026 
2027  if( m_ > N || n_ > M ) {
2028  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
2029  }
2030 
2031  const size_t maxsize( max( m_, n_ ) );
2032  for( size_t i=0UL; i<maxsize; ++i ) {
2033  for( size_t j=0UL; j<i; ++j ) {
2034  cswap( v_[i*NN+j], v_[j*NN+i] );
2035  }
2036  conjugate( v_[i*NN+i] );
2037  }
2038 
2039  if( IsVectorizable<Type>::value && m_ < n_ ) {
2040  for( size_t i=0UL; i<m_; ++i ) {
2041  for( size_t j=m_; j<n_; ++j ) {
2042  v_[i*NN+j] = Type();
2043  }
2044  }
2045  }
2046 
2047  if( IsVectorizable<Type>::value && m_ > n_ ) {
2048  for( size_t i=n_; i<m_; ++i ) {
2049  for( size_t j=0UL; j<n_; ++j ) {
2050  v_[i*NN+j] = Type();
2051  }
2052  }
2053  }
2054 
2055  swap( m_, n_ );
2056 
2057  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
2058 
2059  return *this;
2060 }
2061 //*************************************************************************************************
2062 
2063 
2064 //*************************************************************************************************
2070 template< typename Type // Data type of the matrix
2071  , size_t M // Number of rows
2072  , size_t N // Number of columns
2073  , bool SO > // Storage order
2074 template< typename Other > // Data type of the scalar value
2076 {
2077  for( size_t i=0UL; i<m_; ++i )
2078  for( size_t j=0UL; j<n_; ++j )
2079  v_[i*NN+j] *= scalar;
2080 
2081  return *this;
2082 }
2083 //*************************************************************************************************
2084 
2085 
2086 //*************************************************************************************************
2092 template< typename Type // Data type of the matrix
2093  , size_t M // Number of rows
2094  , size_t N // Number of columns
2095  , bool SO > // Storage order
2097 {
2098  using std::swap;
2099 
2100  const size_t maxrows( max( m_, m.m_ ) );
2101  const size_t maxcols( max( n_, m.n_ ) );
2102 
2103  for( size_t i=0UL; i<maxrows; ++i ) {
2104  for( size_t j=0UL; j<maxcols; ++j ) {
2105  swap( v_[i*NN+j], m(i,j) );
2106  }
2107  }
2108 
2109  swap( m_, m.m_ );
2110  swap( n_, m.n_ );
2111 }
2112 //*************************************************************************************************
2113 
2114 
2115 
2116 
2117 //=================================================================================================
2118 //
2119 // MEMORY FUNCTIONS
2120 //
2121 //=================================================================================================
2122 
2123 //*************************************************************************************************
2133 template< typename Type // Data type of the matrix
2134  , size_t M // Number of rows
2135  , size_t N // Number of columns
2136  , bool SO > // Storage order
2137 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size )
2138 {
2140 
2141  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2142 
2143  return allocate<HybridMatrix>( 1UL );
2144 }
2145 //*************************************************************************************************
2146 
2147 
2148 //*************************************************************************************************
2158 template< typename Type // Data type of the matrix
2159  , size_t M // Number of rows
2160  , size_t N // Number of columns
2161  , bool SO > // Storage order
2162 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
2163 {
2164  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2165  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2166 
2167  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
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, const std::nothrow_t& )
2187 {
2188  UNUSED_PARAMETER( size );
2189 
2190  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2191 
2192  return allocate<HybridMatrix>( 1UL );
2193 }
2194 //*************************************************************************************************
2195 
2196 
2197 //*************************************************************************************************
2207 template< typename Type // Data type of the matrix
2208  , size_t M // Number of rows
2209  , size_t N // Number of columns
2210  , bool SO > // Storage order
2211 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2212 {
2213  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2214  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2215 
2216  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2217 }
2218 //*************************************************************************************************
2219 
2220 
2221 //*************************************************************************************************
2227 template< typename Type // Data type of the matrix
2228  , size_t M // Number of rows
2229  , size_t N // Number of columns
2230  , bool SO > // Storage order
2231 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr )
2232 {
2233  deallocate( static_cast<HybridMatrix*>( ptr ) );
2234 }
2235 //*************************************************************************************************
2236 
2237 
2238 //*************************************************************************************************
2244 template< typename Type // Data type of the matrix
2245  , size_t M // Number of rows
2246  , size_t N // Number of columns
2247  , bool SO > // Storage order
2248 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2249 {
2250  deallocate( static_cast<HybridMatrix*>( ptr ) );
2251 }
2252 //*************************************************************************************************
2253 
2254 
2255 //*************************************************************************************************
2261 template< typename Type // Data type of the matrix
2262  , size_t M // Number of rows
2263  , size_t N // Number of columns
2264  , bool SO > // Storage order
2265 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2266 {
2267  deallocate( static_cast<HybridMatrix*>( ptr ) );
2268 }
2269 //*************************************************************************************************
2270 
2271 
2272 //*************************************************************************************************
2278 template< typename Type // Data type of the matrix
2279  , size_t M // Number of rows
2280  , size_t N // Number of columns
2281  , bool SO > // Storage order
2282 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2283 {
2284  deallocate( static_cast<HybridMatrix*>( ptr ) );
2285 }
2286 //*************************************************************************************************
2287 
2288 
2289 
2290 
2291 //=================================================================================================
2292 //
2293 // DEBUGGING FUNCTIONS
2294 //
2295 //=================================================================================================
2296 
2297 //*************************************************************************************************
2306 template< typename Type // Data type of the matrix
2307  , size_t M // Number of rows
2308  , size_t N // Number of columns
2309  , bool SO > // Storage order
2310 inline bool HybridMatrix<Type,M,N,SO>::isIntact() const noexcept
2311 {
2312  if( m_ > M || n_ > N )
2313  return false;
2314 
2316  {
2317  for( size_t i=0UL; i<m_; ++i ) {
2318  for( size_t j=n_; j<NN; ++j ) {
2319  if( v_[i*NN+j] != Type() )
2320  return false;
2321  }
2322  }
2323 
2324  for( size_t i=m_; i<M; ++i ) {
2325  for( size_t j=0UL; j<NN; ++j ) {
2326  if( v_[i*NN+j] != Type() )
2327  return false;
2328  }
2329  }
2330  }
2331 
2332  return true;
2333 }
2334 //*************************************************************************************************
2335 
2336 
2337 
2338 
2339 //=================================================================================================
2340 //
2341 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2342 //
2343 //=================================================================================================
2344 
2345 //*************************************************************************************************
2355 template< typename Type // Data type of the matrix
2356  , size_t M // Number of rows
2357  , size_t N // Number of columns
2358  , bool SO > // Storage order
2359 template< typename Other > // Data type of the foreign expression
2360 inline bool HybridMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const noexcept
2361 {
2362  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2363 }
2364 //*************************************************************************************************
2365 
2366 
2367 //*************************************************************************************************
2377 template< typename Type // Data type of the matrix
2378  , size_t M // Number of rows
2379  , size_t N // Number of columns
2380  , bool SO > // Storage order
2381 template< typename Other > // Data type of the foreign expression
2382 inline bool HybridMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const noexcept
2383 {
2384  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2385 }
2386 //*************************************************************************************************
2387 
2388 
2389 //*************************************************************************************************
2398 template< typename Type // Data type of the matrix
2399  , size_t M // Number of rows
2400  , size_t N // Number of columns
2401  , bool SO > // Storage order
2402 inline bool HybridMatrix<Type,M,N,SO>::isAligned() const noexcept
2403 {
2404  return ( usePadding || columns() % SIMDSIZE == 0UL );
2405 }
2406 //*************************************************************************************************
2407 
2408 
2409 //*************************************************************************************************
2424 template< typename Type // Data type of the matrix
2425  , size_t M // Number of rows
2426  , size_t N // Number of columns
2427  , bool SO > // Storage order
2429  HybridMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const noexcept
2430 {
2431  if( usePadding )
2432  return loada( i, j );
2433  else
2434  return loadu( i, j );
2435 }
2436 //*************************************************************************************************
2437 
2438 
2439 //*************************************************************************************************
2454 template< typename Type // Data type of the matrix
2455  , size_t M // Number of rows
2456  , size_t N // Number of columns
2457  , bool SO > // Storage order
2459  HybridMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const noexcept
2460 {
2461  using blaze::loada;
2462 
2464 
2465  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2466  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2467  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2468  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2469  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2470 
2471  return loada( &v_[i*NN+j] );
2472 }
2473 //*************************************************************************************************
2474 
2475 
2476 //*************************************************************************************************
2491 template< typename Type // Data type of the matrix
2492  , size_t M // Number of rows
2493  , size_t N // Number of columns
2494  , bool SO > // Storage order
2496  HybridMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const noexcept
2497 {
2498  using blaze::loadu;
2499 
2501 
2502  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2503  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2504  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2505 
2506  return loadu( &v_[i*NN+j] );
2507 }
2508 //*************************************************************************************************
2509 
2510 
2511 //*************************************************************************************************
2527 template< typename Type // Data type of the matrix
2528  , size_t M // Number of rows
2529  , size_t N // Number of columns
2530  , bool SO > // Storage order
2532  HybridMatrix<Type,M,N,SO>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2533 {
2534  if( usePadding )
2535  storea( i, j, value );
2536  else
2537  storeu( i, j, value );
2538 }
2539 //*************************************************************************************************
2540 
2541 
2542 //*************************************************************************************************
2558 template< typename Type // Data type of the matrix
2559  , size_t M // Number of rows
2560  , size_t N // Number of columns
2561  , bool SO > // Storage order
2563  HybridMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2564 {
2565  using blaze::storea;
2566 
2568 
2569  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2570  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2571  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2572  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2573  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2574 
2575  storea( &v_[i*NN+j], value );
2576 }
2577 //*************************************************************************************************
2578 
2579 
2580 //*************************************************************************************************
2596 template< typename Type // Data type of the matrix
2597  , size_t M // Number of rows
2598  , size_t N // Number of columns
2599  , bool SO > // Storage order
2601  HybridMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2602 {
2603  using blaze::storeu;
2604 
2606 
2607  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2608  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2609  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2610 
2611  storeu( &v_[i*NN+j], value );
2612 }
2613 //*************************************************************************************************
2614 
2615 
2616 //*************************************************************************************************
2633 template< typename Type // Data type of the matrix
2634  , size_t M // Number of rows
2635  , size_t N // Number of columns
2636  , bool SO > // Storage order
2638  HybridMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2639 {
2640  using blaze::stream;
2641 
2643 
2644  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2645  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2646  BLAZE_INTERNAL_ASSERT( j + SIMDSIZE <= NN, "Invalid column access index" );
2647  BLAZE_INTERNAL_ASSERT( !usePadding || j % SIMDSIZE == 0UL, "Invalid column access index" );
2648  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2649 
2650  stream( &v_[i*NN+j], value );
2651 }
2652 //*************************************************************************************************
2653 
2654 
2655 //*************************************************************************************************
2666 template< typename Type // Data type of the matrix
2667  , size_t M // Number of rows
2668  , size_t N // Number of columns
2669  , bool SO > // Storage order
2670 template< typename MT // Type of the right-hand side dense matrix
2671  , bool SO2 > // Storage order of the right-hand side dense matrix
2674 {
2675  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2676 
2677  for( size_t i=0UL; i<m_; ++i ) {
2678  for( size_t j=0UL; j<n_; ++j ) {
2679  v_[i*NN+j] = (~rhs)(i,j);
2680  }
2681  }
2682 }
2683 //*************************************************************************************************
2684 
2685 
2686 //*************************************************************************************************
2697 template< typename Type // Data type of the matrix
2698  , size_t M // Number of rows
2699  , size_t N // Number of columns
2700  , bool SO > // Storage order
2701 template< typename MT // Type of the right-hand side dense matrix
2702  , bool SO2 > // Storage order of the right-hand side dense matrix
2705 {
2707 
2708  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2709 
2710  const bool remainder( !usePadding || !IsPadded<MT>::value );
2711 
2712  const size_t jpos( ( remainder )?( n_ & size_t(-SIMDSIZE) ):( n_ ) );
2713  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2714 
2715  for( size_t i=0UL; i<m_; ++i )
2716  {
2717  size_t j( 0UL );
2718 
2719  for( ; j<jpos; j+=SIMDSIZE ) {
2720  store( i, j, (~rhs).load(i,j) );
2721  }
2722  for( ; remainder && j<n_; ++j ) {
2723  v_[i*NN+j] = (~rhs)(i,j);
2724  }
2725  }
2726 }
2727 //*************************************************************************************************
2728 
2729 
2730 //*************************************************************************************************
2741 template< typename Type // Data type of the matrix
2742  , size_t M // Number of rows
2743  , size_t N // Number of columns
2744  , bool SO > // Storage order
2745 template< typename MT > // Type of the right-hand side sparse matrix
2747 {
2748  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2749 
2750  for( size_t i=0UL; i<m_; ++i )
2751  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2752  v_[i*NN+element->index()] = element->value();
2753 }
2754 //*************************************************************************************************
2755 
2756 
2757 //*************************************************************************************************
2768 template< typename Type // Data type of the matrix
2769  , size_t M // Number of rows
2770  , size_t N // Number of columns
2771  , bool SO > // Storage order
2772 template< typename MT > // Type of the right-hand side sparse matrix
2774 {
2776 
2777  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2778 
2779  for( size_t j=0UL; j<n_; ++j )
2780  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2781  v_[element->index()*NN+j] = element->value();
2782 }
2783 //*************************************************************************************************
2784 
2785 
2786 //*************************************************************************************************
2797 template< typename Type // Data type of the matrix
2798  , size_t M // Number of rows
2799  , size_t N // Number of columns
2800  , bool SO > // Storage order
2801 template< typename MT // Type of the right-hand side dense matrix
2802  , bool SO2 > // Storage order of the right-hand side dense matrix
2805 {
2806  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2807 
2808  for( size_t i=0UL; i<m_; ++i )
2809  {
2810  if( IsDiagonal<MT>::value )
2811  {
2812  v_[i*NN+i] += (~rhs)(i,i);
2813  }
2814  else
2815  {
2816  const size_t jbegin( ( IsUpper<MT>::value )
2817  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2818  :( 0UL ) );
2819  const size_t jend ( ( IsLower<MT>::value )
2820  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2821  :( n_ ) );
2822  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2823 
2824  for( size_t j=jbegin; j<jend; ++j ) {
2825  v_[i*NN+j] += (~rhs)(i,j);
2826  }
2827  }
2828  }
2829 }
2830 //*************************************************************************************************
2831 
2832 
2833 //*************************************************************************************************
2844 template< typename Type // Data type of the matrix
2845  , size_t M // Number of rows
2846  , size_t N // Number of columns
2847  , bool SO > // Storage order
2848 template< typename MT // Type of the right-hand side dense matrix
2849  , bool SO2 > // Storage order of the right-hand side dense matrix
2850 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
2852 {
2855 
2856  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2857 
2858  const bool remainder( !usePadding || !IsPadded<MT>::value );
2859 
2860  for( size_t i=0UL; i<m_; ++i )
2861  {
2862  const size_t jbegin( ( IsUpper<MT>::value )
2863  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
2864  :( 0UL ) );
2865  const size_t jend ( ( IsLower<MT>::value )
2866  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2867  :( n_ ) );
2868  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2869 
2870  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
2871  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2872 
2873  size_t j( jbegin );
2874 
2875  for( ; j<jpos; j+=SIMDSIZE ) {
2876  store( i, j, load(i,j) + (~rhs).load(i,j) );
2877  }
2878  for( ; remainder && j<jend; ++j ) {
2879  v_[i*NN+j] += (~rhs)(i,j);
2880  }
2881  }
2882 }
2883 //*************************************************************************************************
2884 
2885 
2886 //*************************************************************************************************
2897 template< typename Type // Data type of the matrix
2898  , size_t M // Number of rows
2899  , size_t N // Number of columns
2900  , bool SO > // Storage order
2901 template< typename MT > // Type of the right-hand side sparse matrix
2903 {
2904  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2905 
2906  for( size_t i=0UL; i<m_; ++i )
2907  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2908  v_[i*NN+element->index()] += element->value();
2909 }
2910 //*************************************************************************************************
2911 
2912 
2913 //*************************************************************************************************
2924 template< typename Type // Data type of the matrix
2925  , size_t M // Number of rows
2926  , size_t N // Number of columns
2927  , bool SO > // Storage order
2928 template< typename MT > // Type of the right-hand side sparse matrix
2930 {
2932 
2933  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2934 
2935  for( size_t j=0UL; j<n_; ++j )
2936  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2937  v_[element->index()*NN+j] += element->value();
2938 }
2939 //*************************************************************************************************
2940 
2941 
2942 //*************************************************************************************************
2953 template< typename Type // Data type of the matrix
2954  , size_t M // Number of rows
2955  , size_t N // Number of columns
2956  , bool SO > // Storage order
2957 template< typename MT // Type of the right-hand side dense matrix
2958  , bool SO2 > // Storage order of the right-hand side dense matrix
2961 {
2962  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2963 
2964  for( size_t i=0UL; i<m_; ++i )
2965  {
2966  if( IsDiagonal<MT>::value )
2967  {
2968  v_[i*NN+i] -= (~rhs)(i,i);
2969  }
2970  else
2971  {
2972  const size_t jbegin( ( IsUpper<MT>::value )
2973  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2974  :( 0UL ) );
2975  const size_t jend ( ( IsLower<MT>::value )
2976  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2977  :( n_ ) );
2978  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2979 
2980  for( size_t j=jbegin; j<jend; ++j ) {
2981  v_[i*NN+j] -= (~rhs)(i,j);
2982  }
2983  }
2984  }
2985 }
2986 //*************************************************************************************************
2987 
2988 
2989 //*************************************************************************************************
3000 template< typename Type // Data type of the matrix
3001  , size_t M // Number of rows
3002  , size_t N // Number of columns
3003  , bool SO > // Storage order
3004 template< typename MT // Type of the right-hand side dense matrix
3005  , bool SO2 > // Storage order of the right-hand side dense matrix
3006 inline EnableIf_<typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
3008 {
3011 
3012  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3013 
3014  const bool remainder( !usePadding || !IsPadded<MT>::value );
3015 
3016  for( size_t i=0UL; i<m_; ++i )
3017  {
3018  const size_t jbegin( ( IsUpper<MT>::value )
3019  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-SIMDSIZE) )
3020  :( 0UL ) );
3021  const size_t jend ( ( IsLower<MT>::value )
3022  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
3023  :( n_ ) );
3024  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
3025 
3026  const size_t jpos( ( remainder )?( jend & size_t(-SIMDSIZE) ):( jend ) );
3027  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
3028 
3029  size_t j( jbegin );
3030 
3031  for( ; j<jpos; j+=SIMDSIZE ) {
3032  store( i, j, load(i,j) - (~rhs).load(i,j) );
3033  }
3034  for( ; remainder && j<jend; ++j ) {
3035  v_[i*NN+j] -= (~rhs)(i,j);
3036  }
3037  }
3038 }
3039 //*************************************************************************************************
3040 
3041 
3042 //*************************************************************************************************
3053 template< typename Type // Data type of the matrix
3054  , size_t M // Number of rows
3055  , size_t N // Number of columns
3056  , bool SO > // Storage order
3057 template< typename MT > // Type of the right-hand side sparse matrix
3059 {
3060  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3061 
3062  for( size_t i=0UL; i<m_; ++i )
3063  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3064  v_[i*NN+element->index()] -= element->value();
3065 }
3066 //*************************************************************************************************
3067 
3068 
3069 //*************************************************************************************************
3080 template< typename Type // Data type of the matrix
3081  , size_t M // Number of rows
3082  , size_t N // Number of columns
3083  , bool SO > // Storage order
3084 template< typename MT > // Type of the right-hand side sparse matrix
3086 {
3088 
3089  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
3090 
3091  for( size_t j=0UL; j<n_; ++j )
3092  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3093  v_[element->index()*NN+j] -= element->value();
3094 }
3095 //*************************************************************************************************
3096 
3097 
3098 
3099 
3100 
3101 
3102 
3103 
3104 //=================================================================================================
3105 //
3106 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
3107 //
3108 //=================================================================================================
3109 
3110 //*************************************************************************************************
3118 template< typename Type // Data type of the matrix
3119  , size_t M // Number of rows
3120  , size_t N > // Number of columns
3121 class HybridMatrix<Type,M,N,true> : public DenseMatrix< HybridMatrix<Type,M,N,true>, true >
3122 {
3123  public:
3124  //**Type definitions****************************************************************************
3127  typedef This ResultType;
3130  typedef Type ElementType;
3132  typedef const Type& ReturnType;
3133  typedef const This& CompositeType;
3134 
3135  typedef Type& Reference;
3136  typedef const Type& ConstReference;
3137  typedef Type* Pointer;
3138  typedef const Type* ConstPointer;
3139 
3142  //**********************************************************************************************
3143 
3144  //**Rebind struct definition********************************************************************
3147  template< typename ET > // Data type of the other matrix
3148  struct Rebind {
3150  };
3151  //**********************************************************************************************
3152 
3153  //**Compilation flags***************************************************************************
3155 
3159  enum : bool { simdEnabled = IsVectorizable<Type>::value };
3160 
3162 
3165  enum : bool { smpAssignable = false };
3166  //**********************************************************************************************
3167 
3168  //**Constructors********************************************************************************
3171  explicit inline HybridMatrix();
3172  explicit inline HybridMatrix( size_t m, size_t n );
3173  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
3174  explicit inline HybridMatrix( initializer_list< initializer_list<Type> > list );
3175 
3176  template< typename Other >
3177  explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
3178 
3179  template< typename Other, size_t M2, size_t N2 >
3180  explicit inline HybridMatrix( const Other (&array)[M2][N2] );
3181 
3182  inline HybridMatrix( const HybridMatrix& m );
3183  template< typename MT, bool SO > inline HybridMatrix( const Matrix<MT,SO>& m );
3185  //**********************************************************************************************
3186 
3187  //**Destructor**********************************************************************************
3188  // No explicitly declared destructor.
3189  //**********************************************************************************************
3190 
3191  //**Data access functions***********************************************************************
3194  inline Reference operator()( size_t i, size_t j ) noexcept;
3195  inline ConstReference operator()( size_t i, size_t j ) const noexcept;
3196  inline Reference at( size_t i, size_t j );
3197  inline ConstReference at( size_t i, size_t j ) const;
3198  inline Pointer data () noexcept;
3199  inline ConstPointer data () const noexcept;
3200  inline Pointer data ( size_t j ) noexcept;
3201  inline ConstPointer data ( size_t j ) const noexcept;
3202  inline Iterator begin ( size_t j ) noexcept;
3203  inline ConstIterator begin ( size_t j ) const noexcept;
3204  inline ConstIterator cbegin( size_t j ) const noexcept;
3205  inline Iterator end ( size_t j ) noexcept;
3206  inline ConstIterator end ( size_t j ) const noexcept;
3207  inline ConstIterator cend ( size_t j ) const noexcept;
3209  //**********************************************************************************************
3210 
3211  //**Assignment operators************************************************************************
3214  inline HybridMatrix& operator=( const Type& set );
3215  inline HybridMatrix& operator=( initializer_list< initializer_list<Type> > list );
3216 
3217  template< typename Other, size_t M2, size_t N2 >
3218  inline HybridMatrix& operator=( const Other (&array)[M2][N2] );
3219 
3220  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
3221  template< typename MT, bool SO > inline HybridMatrix& operator= ( const Matrix<MT,SO>& rhs );
3222  template< typename MT, bool SO > inline HybridMatrix& operator+=( const Matrix<MT,SO>& rhs );
3223  template< typename MT, bool SO > inline HybridMatrix& operator-=( const Matrix<MT,SO>& rhs );
3224  template< typename MT, bool SO > inline HybridMatrix& operator*=( const Matrix<MT,SO>& rhs );
3225 
3226  template< typename Other >
3227  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator*=( Other rhs );
3228 
3229  template< typename Other >
3230  inline EnableIf_<IsNumeric<Other>, HybridMatrix >& operator/=( Other rhs );
3232  //**********************************************************************************************
3233 
3234  //**Utility functions***************************************************************************
3237  inline size_t rows() const noexcept;
3238  inline size_t columns() const noexcept;
3239  inline constexpr size_t spacing() const noexcept;
3240  inline constexpr size_t capacity() const noexcept;
3241  inline size_t capacity( size_t j ) const noexcept;
3242  inline size_t nonZeros() const;
3243  inline size_t nonZeros( size_t j ) const;
3244  inline void reset();
3245  inline void reset( size_t i );
3246  inline void clear();
3247  void resize ( size_t m, size_t n, bool preserve=true );
3248  inline void extend ( size_t m, size_t n, bool preserve=true );
3249  inline HybridMatrix& transpose();
3250  inline HybridMatrix& ctranspose();
3251  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
3252  inline void swap( HybridMatrix& m ) noexcept;
3254  //**********************************************************************************************
3255 
3256  //**Memory functions****************************************************************************
3259  static inline void* operator new ( std::size_t size );
3260  static inline void* operator new[]( std::size_t size );
3261  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3262  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3263 
3264  static inline void operator delete ( void* ptr );
3265  static inline void operator delete[]( void* ptr );
3266  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3267  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3269  //**********************************************************************************************
3270 
3271  private:
3272  //**********************************************************************************************
3274  template< typename MT >
3275  struct VectorizedAssign {
3276  enum : bool { value = useOptimizedKernels &&
3277  simdEnabled && MT::simdEnabled &&
3278  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3279  IsColumnMajorMatrix<MT>::value };
3280  };
3281  //**********************************************************************************************
3282 
3283  //**********************************************************************************************
3285  template< typename MT >
3286  struct VectorizedAddAssign {
3287  enum : bool { value = useOptimizedKernels &&
3288  simdEnabled && MT::simdEnabled &&
3289  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3290  HasSIMDAdd< Type, ElementType_<MT> >::value &&
3291  IsColumnMajorMatrix<MT>::value &&
3292  !IsDiagonal<MT>::value };
3293  };
3294  //**********************************************************************************************
3295 
3296  //**********************************************************************************************
3298  template< typename MT >
3299  struct VectorizedSubAssign {
3300  enum : bool { value = useOptimizedKernels &&
3301  simdEnabled && MT::simdEnabled &&
3302  AreSIMDCombinable< Type, ElementType_<MT> >::value &&
3303  HasSIMDSub< Type, ElementType_<MT> >::value &&
3304  IsColumnMajorMatrix<MT>::value &&
3305  !IsDiagonal<MT>::value };
3306  };
3307  //**********************************************************************************************
3308 
3309  //**********************************************************************************************
3311  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
3312  //**********************************************************************************************
3313 
3314  public:
3315  //**Debugging functions*************************************************************************
3318  inline bool isIntact() const noexcept;
3320  //**********************************************************************************************
3321 
3322  //**Expression template evaluation functions****************************************************
3325  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
3326  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
3327 
3328  inline bool isAligned() const noexcept;
3329 
3330  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
3331  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
3332  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
3333 
3334  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
3335  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
3336  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
3337  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
3338 
3339  template< typename MT, bool SO >
3340  inline DisableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3341 
3342  template< typename MT, bool SO >
3343  inline EnableIf_<VectorizedAssign<MT> > assign( const DenseMatrix<MT,SO>& rhs );
3344 
3345  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3346  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3347 
3348  template< typename MT, bool SO >
3349  inline DisableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3350 
3351  template< typename MT, bool SO >
3352  inline EnableIf_<VectorizedAddAssign<MT> > addAssign( const DenseMatrix<MT,SO>& rhs );
3353 
3354  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3355  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3356 
3357  template< typename MT, bool SO >
3358  inline DisableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3359 
3360  template< typename MT, bool SO >
3361  inline EnableIf_<VectorizedSubAssign<MT> > subAssign( const DenseMatrix<MT,SO>& rhs );
3362 
3363  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3364  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3366  //**********************************************************************************************
3367 
3368  private:
3369  //**********************************************************************************************
3371  enum : size_t { MM = ( usePadding )?( NextMultiple< SizeT<M>, SizeT<SIMDSIZE> >::value ):( M ) };
3372  //**********************************************************************************************
3373 
3374  //**Member variables****************************************************************************
3377  AlignedArray<Type,MM*N> v_;
3378 
3380  size_t m_;
3381  size_t n_;
3382 
3383  //**********************************************************************************************
3384 
3385  //**Compile time checks*************************************************************************
3390  BLAZE_STATIC_ASSERT( !usePadding || MM % SIMDSIZE == 0UL );
3391  BLAZE_STATIC_ASSERT( MM >= M );
3392  //**********************************************************************************************
3393 };
3395 //*************************************************************************************************
3396 
3397 
3398 
3399 
3400 //=================================================================================================
3401 //
3402 // CONSTRUCTORS
3403 //
3404 //=================================================================================================
3405 
3406 //*************************************************************************************************
3412 template< typename Type // Data type of the matrix
3413  , size_t M // Number of rows
3414  , size_t N > // Number of columns
3416  : v_() // The statically allocated matrix elements
3417  , m_( 0UL ) // The current number of rows of the matrix
3418  , n_( 0UL ) // The current number of columns of the matrix
3419 {
3420  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3421 
3422  if( IsNumeric<Type>::value ) {
3423  for( size_t i=0UL; i<MM*N; ++i )
3424  v_[i] = Type();
3425  }
3426 
3427  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3428 }
3430 //*************************************************************************************************
3431 
3432 
3433 //*************************************************************************************************
3447 template< typename Type // Data type of the matrix
3448  , size_t M // Number of rows
3449  , size_t N > // Number of columns
3450 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n )
3451  : v_() // The statically allocated matrix elements
3452  , m_( m ) // The current number of rows of the matrix
3453  , n_( n ) // The current number of columns of the matrix
3454 {
3455  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3456 
3457  if( m > M ) {
3458  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3459  }
3460 
3461  if( n > N ) {
3462  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3463  }
3464 
3465  if( IsNumeric<Type>::value ) {
3466  for( size_t i=0UL; i<MM*N; ++i )
3467  v_[i] = Type();
3468  }
3469 
3470  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3471 }
3473 //*************************************************************************************************
3474 
3475 
3476 //*************************************************************************************************
3491 template< typename Type // Data type of the matrix
3492  , size_t M // Number of rows
3493  , size_t N > // Number of columns
3494 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Type& init )
3495  : v_() // The statically allocated matrix elements
3496  , m_( m ) // The current number of rows of the matrix
3497  , n_( n ) // The current number of columns of the matrix
3498 {
3499  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3500 
3501  if( m > M ) {
3502  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3503  }
3504 
3505  if( n > N ) {
3506  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3507  }
3508 
3509  for( size_t j=0UL; j<n; ++j ) {
3510  for( size_t i=0UL; i<m; ++i )
3511  v_[i+j*MM] = init;
3512 
3513  if( IsNumeric<Type>::value ) {
3514  for( size_t i=m; i<MM; ++i )
3515  v_[i+j*MM] = Type();
3516  }
3517  }
3518 
3519  if( IsNumeric<Type>::value ) {
3520  for( size_t j=n; j<N; ++j )
3521  for( size_t i=0UL; i<MM; ++i )
3522  v_[i+j*MM] = Type();
3523  }
3524 
3525  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3526 }
3528 //*************************************************************************************************
3529 
3530 
3531 //*************************************************************************************************
3556 template< typename Type // Data type of the matrix
3557  , size_t M // Number of rows
3558  , size_t N > // Number of columns
3559 inline HybridMatrix<Type,M,N,true>::HybridMatrix( initializer_list< initializer_list<Type> > list )
3560  : v_() // The statically allocated matrix elements
3561  , m_( list.size() ) // The current number of rows of the matrix
3562  , n_( determineColumns( list ) ) // The current number of columns of the matrix
3563 {
3564  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3565 
3566  if( m_ > M ) {
3567  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3568  }
3569 
3570  if( n_ > N ) {
3571  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3572  }
3573 
3574  size_t i( 0UL );
3575 
3576  for( const auto& rowList : list ) {
3577  size_t j( 0UL );
3578  for( const auto& element : rowList ) {
3579  v_[i+j*MM] = element;
3580  ++j;
3581  }
3582  if( IsNumeric<Type>::value ) {
3583  for( ; j<N; ++j ) {
3584  v_[i+j*MM] = Type();
3585  }
3586  }
3587  ++i;
3588  }
3589 
3590  BLAZE_INTERNAL_ASSERT( i == m_, "Invalid number of elements detected" );
3591 
3592  if( IsNumeric<Type>::value ) {
3593  for( ; i<MM; ++i ) {
3594  for( size_t j=0UL; j<N; ++j ) {
3595  v_[i+j*MM] = Type();
3596  }
3597  }
3598  }
3599 
3600  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3601 }
3603 //*************************************************************************************************
3604 
3605 
3606 //*************************************************************************************************
3634 template< typename Type // Data type of the matrix
3635  , size_t M // Number of rows
3636  , size_t N > // Number of columns
3637 template< typename Other > // Data type of the initialization array
3638 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Other* array )
3639  : v_() // The statically allocated matrix elements
3640  , m_( m ) // The current number of rows of the matrix
3641  , n_( n ) // The current number of columns of the matrix
3642 {
3643  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3644 
3645  if( m > M ) {
3646  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3647  }
3648 
3649  if( n > N ) {
3650  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3651  }
3652 
3653  for( size_t j=0UL; j<n; ++j ) {
3654  for( size_t i=0UL; i<m; ++i )
3655  v_[i+j*MM] = array[i+j*m];
3656 
3657  if( IsNumeric<Type>::value ) {
3658  for( size_t i=m; i<MM; ++i )
3659  v_[i+j*MM] = Type();
3660  }
3661  }
3662 
3663  if( IsNumeric<Type>::value ) {
3664  for( size_t j=n; j<N; ++j )
3665  for( size_t i=0UL; i<MM; ++i )
3666  v_[i+j*MM] = Type();
3667  }
3668 
3669  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3670 }
3672 //*************************************************************************************************
3673 
3674 
3675 //*************************************************************************************************
3697 template< typename Type // Data type of the matrix
3698  , size_t M // Number of rows
3699  , size_t N > // Number of columns
3700 template< typename Other // Data type of the initialization array
3701  , size_t M2 // Number of rows of the initialization array
3702  , size_t N2 > // Number of columns of the initialization array
3703 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const Other (&array)[M2][N2] )
3704  : v_() // The statically allocated matrix elements
3705  , m_( M2 ) // The current number of rows of the matrix
3706  , n_( N2 ) // The current number of columns of the matrix
3707 {
3708  BLAZE_STATIC_ASSERT( M2 <= M );
3709  BLAZE_STATIC_ASSERT( N2 <= N );
3710  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3711 
3712  for( size_t j=0UL; j<N2; ++j ) {
3713  for( size_t i=0UL; i<M2; ++i )
3714  v_[i+j*MM] = array[i][j];
3715 
3716  if( IsNumeric<Type>::value ) {
3717  for( size_t i=M2; i<MM; ++i )
3718  v_[i+j*MM] = Type();
3719  }
3720  }
3721 
3722  if( IsNumeric<Type>::value ) {
3723  for( size_t j=N2; j<N; ++j )
3724  for( size_t i=0UL; i<MM; ++i )
3725  v_[i+j*MM] = Type();
3726  }
3727 
3728  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3729 }
3731 //*************************************************************************************************
3732 
3733 
3734 //*************************************************************************************************
3743 template< typename Type // Data type of the matrix
3744  , size_t M // Number of rows
3745  , size_t N > // Number of columns
3746 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const HybridMatrix& m )
3747  : v_() // The statically allocated matrix elements
3748  , m_( m.m_ ) // The current number of rows of the matrix
3749  , n_( m.n_ ) // The current number of columns of the matrix
3750 {
3751  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3752 
3753  for( size_t j=0UL; j<n_; ++j ) {
3754  for( size_t i=0UL; i<m_; ++i )
3755  v_[i+j*MM] = m.v_[i+j*MM];
3756 
3757  if( IsNumeric<Type>::value ) {
3758  for( size_t i=m_; i<MM; ++i )
3759  v_[i+j*MM] = Type();
3760  }
3761  }
3762 
3763  if( IsNumeric<Type>::value ) {
3764  for( size_t j=n_; 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 //*************************************************************************************************
3782 template< typename Type // Data type of the matrix
3783  , size_t M // Number of rows
3784  , size_t N > // Number of columns
3785 template< typename MT // Type of the foreign matrix
3786  , bool SO2 > // Storage order of the foreign matrix
3787 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const Matrix<MT,SO2>& m )
3788  : v_() // The statically allocated matrix elements
3789  , m_( (~m).rows() ) // The current number of rows of the matrix
3790  , n_( (~m).columns() ) // The current number of columns of the matrix
3791 {
3792  using blaze::assign;
3793 
3794  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3795 
3796  if( (~m).rows() > M || (~m).columns() > N ) {
3797  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
3798  }
3799 
3800  for( size_t j=0UL; j<n_; ++j ) {
3801  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : m_ );
3802  i<( IsNumeric<Type>::value ? MM : m_ );
3803  ++i ) {
3804  v_[i+j*MM] = Type();
3805  }
3806  }
3807 
3808  if( IsNumeric<Type>::value ) {
3809  for( size_t j=n_; j<N; ++j )
3810  for( size_t i=0UL; i<MM; ++i )
3811  v_[i+j*MM] = Type();
3812  }
3813 
3814  assign( *this, ~m );
3815 
3816  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
3817 }
3819 //*************************************************************************************************
3820 
3821 
3822 
3823 
3824 //=================================================================================================
3825 //
3826 // DATA ACCESS FUNCTIONS
3827 //
3828 //=================================================================================================
3829 
3830 //*************************************************************************************************
3841 template< typename Type // Data type of the matrix
3842  , size_t M // Number of rows
3843  , size_t N > // Number of columns
3845  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) noexcept
3846 {
3847  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3848  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3849  return v_[i+j*MM];
3850 }
3852 //*************************************************************************************************
3853 
3854 
3855 //*************************************************************************************************
3866 template< typename Type // Data type of the matrix
3867  , size_t M // Number of rows
3868  , size_t N > // Number of columns
3870  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const noexcept
3871 {
3872  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3873  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3874  return v_[i+j*MM];
3875 }
3877 //*************************************************************************************************
3878 
3879 
3880 //*************************************************************************************************
3892 template< typename Type // Data type of the matrix
3893  , size_t M // Number of rows
3894  , size_t N > // Number of columns
3896  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j )
3897 {
3898  if( i >= m_ ) {
3899  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3900  }
3901  if( j >= n_ ) {
3902  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3903  }
3904  return (*this)(i,j);
3905 }
3907 //*************************************************************************************************
3908 
3909 
3910 //*************************************************************************************************
3922 template< typename Type // Data type of the matrix
3923  , size_t M // Number of rows
3924  , size_t N > // Number of columns
3926  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
3927 {
3928  if( i >= m_ ) {
3929  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3930  }
3931  if( j >= n_ ) {
3932  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3933  }
3934  return (*this)(i,j);
3935 }
3937 //*************************************************************************************************
3938 
3939 
3940 //*************************************************************************************************
3952 template< typename Type // Data type of the matrix
3953  , size_t M // Number of rows
3954  , size_t N > // Number of columns
3955 inline typename HybridMatrix<Type,M,N,true>::Pointer
3957 {
3958  return v_;
3959 }
3961 //*************************************************************************************************
3962 
3963 
3964 //*************************************************************************************************
3976 template< typename Type // Data type of the matrix
3977  , size_t M // Number of rows
3978  , size_t N > // Number of columns
3979 inline typename HybridMatrix<Type,M,N,true>::ConstPointer
3980  HybridMatrix<Type,M,N,true>::data() const noexcept
3981 {
3982  return v_;
3983 }
3985 //*************************************************************************************************
3986 
3987 
3988 //*************************************************************************************************
3997 template< typename Type // Data type of the matrix
3998  , size_t M // Number of rows
3999  , size_t N > // Number of columns
4000 inline typename HybridMatrix<Type,M,N,true>::Pointer
4001  HybridMatrix<Type,M,N,true>::data( size_t j ) noexcept
4002 {
4003  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4004  return v_ + j*MM;
4005 }
4007 //*************************************************************************************************
4008 
4009 
4010 //*************************************************************************************************
4019 template< typename Type // Data type of the matrix
4020  , size_t M // Number of rows
4021  , size_t N > // Number of columns
4022 inline typename HybridMatrix<Type,M,N,true>::ConstPointer
4023  HybridMatrix<Type,M,N,true>::data( size_t j ) const noexcept
4024 {
4025  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4026  return v_ + j*MM;
4027 }
4029 //*************************************************************************************************
4030 
4031 
4032 //*************************************************************************************************
4039 template< typename Type // Data type of the matrix
4040  , size_t M // Number of rows
4041  , size_t N > // Number of columns
4043  HybridMatrix<Type,M,N,true>::begin( size_t j ) noexcept
4044 {
4045  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4046  return Iterator( v_ + j*MM );
4047 }
4049 //*************************************************************************************************
4050 
4051 
4052 //*************************************************************************************************
4059 template< typename Type // Data type of the matrix
4060  , size_t M // Number of rows
4061  , size_t N > // Number of columns
4063  HybridMatrix<Type,M,N,true>::begin( size_t j ) const noexcept
4064 {
4065  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4066  return ConstIterator( v_ + j*MM );
4067 }
4069 //*************************************************************************************************
4070 
4071 
4072 //*************************************************************************************************
4079 template< typename Type // Data type of the matrix
4080  , size_t M // Number of rows
4081  , size_t N > // Number of columns
4083  HybridMatrix<Type,M,N,true>::cbegin( size_t j ) const noexcept
4084 {
4085  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4086  return ConstIterator( v_ + j*MM );
4087 }
4089 //*************************************************************************************************
4090 
4091 
4092 //*************************************************************************************************
4099 template< typename Type // Data type of the matrix
4100  , size_t M // Number of rows
4101  , size_t N > // Number of columns
4103  HybridMatrix<Type,M,N,true>::end( size_t j ) noexcept
4104 {
4105  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4106  return Iterator( v_ + j*MM + M );
4107 }
4109 //*************************************************************************************************
4110 
4111 
4112 //*************************************************************************************************
4119 template< typename Type // Data type of the matrix
4120  , size_t M // Number of rows
4121  , size_t N > // Number of columns
4123  HybridMatrix<Type,M,N,true>::end( size_t j ) const noexcept
4124 {
4125  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4126  return ConstIterator( v_ + j*MM + M );
4127 }
4129 //*************************************************************************************************
4130 
4131 
4132 //*************************************************************************************************
4139 template< typename Type // Data type of the matrix
4140  , size_t M // Number of rows
4141  , size_t N > // Number of columns
4143  HybridMatrix<Type,M,N,true>::cend( size_t j ) const noexcept
4144 {
4145  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
4146  return ConstIterator( v_ + j*MM + M );
4147 }
4149 //*************************************************************************************************
4150 
4151 
4152 
4153 
4154 //=================================================================================================
4155 //
4156 // ASSIGNMENT OPERATORS
4157 //
4158 //=================================================================================================
4159 
4160 //*************************************************************************************************
4167 template< typename Type // Data type of the matrix
4168  , size_t M // Number of rows
4169  , size_t N > // Number of columns
4170 inline HybridMatrix<Type,M,N,true>&
4172 {
4173  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
4174  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
4175 
4176  for( size_t j=0UL; j<n_; ++j )
4177  for( size_t i=0UL; i<m_; ++i )
4178  v_[i+j*MM] = set;
4179 
4180  return *this;
4181 }
4183 //*************************************************************************************************
4184 
4185 
4186 //*************************************************************************************************
4212 template< typename Type // Data type of the matrix
4213  , size_t M // Number of rows
4214  , size_t N > // Number of columns
4215 inline HybridMatrix<Type,M,N,true>&
4216  HybridMatrix<Type,M,N,true>::operator=( initializer_list< initializer_list<Type> > list )
4217 {
4218  const size_t m( list.size() );
4219  const size_t n( determineColumns( list ) );
4220 
4221  if( m > M ) {
4222  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4223  }
4224 
4225  if( n > N ) {
4226  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4227  }
4228 
4229  resize( m, n, false );
4230 
4231  size_t i( 0UL );
4232 
4233  for( const auto& rowList : list ) {
4234  size_t j( 0UL );
4235  for( const auto& element : rowList ) {
4236  v_[i+j*MM] = element;
4237  ++j;
4238  }
4239  for( ; j<n_; ++j ) {
4240  v_[i+j*MM] = Type();
4241  }
4242  ++i;
4243  }
4244 
4245  return *this;
4246 }
4248 //*************************************************************************************************
4249 
4250 
4251 //*************************************************************************************************
4273 template< typename Type // Data type of the matrix
4274  , size_t M // Number of rows
4275  , size_t N > // Number of columns
4276 template< typename Other // Data type of the initialization array
4277  , size_t M2 // Number of rows of the initialization array
4278  , size_t N2 > // Number of columns of the initialization array
4279 inline HybridMatrix<Type,M,N,true>&
4280  HybridMatrix<Type,M,N,true>::operator=( const Other (&array)[M2][N2] )
4281 {
4282  BLAZE_STATIC_ASSERT( M2 <= M );
4283  BLAZE_STATIC_ASSERT( N2 <= N );
4284 
4285  resize( M2, N2 );
4286 
4287  for( size_t j=0UL; j<N2; ++j )
4288  for( size_t i=0UL; i<M2; ++i )
4289  v_[i+j*MM] = array[i][j];
4290 
4291  return *this;
4292 }
4294 //*************************************************************************************************
4295 
4296 
4297 //*************************************************************************************************
4306 template< typename Type // Data type of the matrix
4307  , size_t M // Number of rows
4308  , size_t N > // Number of columns
4309 inline HybridMatrix<Type,M,N,true>&
4310  HybridMatrix<Type,M,N,true>::operator=( const HybridMatrix& rhs )
4311 {
4312  using blaze::assign;
4313 
4314  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
4315  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
4316 
4317  resize( rhs.rows(), rhs.columns() );
4318  assign( *this, ~rhs );
4319 
4320  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4321 
4322  return *this;
4323 }
4325 //*************************************************************************************************
4326 
4327 
4328 //*************************************************************************************************
4340 template< typename Type // Data type of the matrix
4341  , size_t M // Number of rows
4342  , size_t N > // Number of columns
4343 template< typename MT // Type of the right-hand side matrix
4344  , bool SO > // Storage order of the right-hand side matrix
4345 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator=( const Matrix<MT,SO>& rhs )
4346 {
4347  using blaze::assign;
4348 
4349  typedef TransExprTrait_<This> TT;
4350  typedef CTransExprTrait_<This> CT;
4351  typedef InvExprTrait_<This> IT;
4352 
4353  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
4354  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
4355  }
4356 
4357  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
4358  transpose();
4359  }
4360  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
4361  ctranspose();
4362  }
4363  else if( !IsSame<MT,IT>::value && (~rhs).canAlias( this ) ) {
4364  HybridMatrix tmp( ~rhs );
4365  resize( tmp.rows(), tmp.columns() );
4366  assign( *this, tmp );
4367  }
4368  else {
4369  resize( (~rhs).rows(), (~rhs).columns() );
4370  if( IsSparseMatrix<MT>::value )
4371  reset();
4372  assign( *this, ~rhs );
4373  }
4374 
4375  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4376 
4377  return *this;
4378 }
4380 //*************************************************************************************************
4381 
4382 
4383 //*************************************************************************************************
4394 template< typename Type // Data type of the matrix
4395  , size_t M // Number of rows
4396  , size_t N > // Number of columns
4397 template< typename MT // Type of the right-hand side matrix
4398  , bool SO > // Storage order of the right-hand side matrix
4399 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator+=( const Matrix<MT,SO>& rhs )
4400 {
4401  using blaze::addAssign;
4402 
4403  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4404  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4405  }
4406 
4407  if( (~rhs).canAlias( this ) ) {
4408  const ResultType_<MT> tmp( ~rhs );
4409  addAssign( *this, tmp );
4410  }
4411  else {
4412  addAssign( *this, ~rhs );
4413  }
4414 
4415  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4416 
4417  return *this;
4418 }
4420 //*************************************************************************************************
4421 
4422 
4423 //*************************************************************************************************
4434 template< typename Type // Data type of the matrix
4435  , size_t M // Number of rows
4436  , size_t N > // Number of columns
4437 template< typename MT // Type of the right-hand side matrix
4438  , bool SO > // Storage order of the right-hand side matrix
4439 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator-=( const Matrix<MT,SO>& rhs )
4440 {
4441  using blaze::subAssign;
4442 
4443  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4444  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4445  }
4446 
4447  if( (~rhs).canAlias( this ) ) {
4448  const ResultType_<MT> tmp( ~rhs );
4449  subAssign( *this, tmp );
4450  }
4451  else {
4452  subAssign( *this, ~rhs );
4453  }
4454 
4455  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4456 
4457  return *this;
4458 }
4460 //*************************************************************************************************
4461 
4462 
4463 //*************************************************************************************************
4474 template< typename Type // Data type of the matrix
4475  , size_t M // Number of rows
4476  , size_t N > // Number of columns
4477 template< typename MT // Type of the right-hand side matrix
4478  , bool SO > // Storage order of the right-hand side matrix
4479 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator*=( const Matrix<MT,SO>& rhs )
4480 {
4481  if( n_ != (~rhs).rows() || (~rhs).columns() > N ) {
4482  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4483  }
4484 
4485  const HybridMatrix tmp( *this * (~rhs) );
4486  this->operator=( tmp );
4487 
4488  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4489 
4490  return *this;
4491 }
4493 //*************************************************************************************************
4494 
4495 
4496 //*************************************************************************************************
4504 template< typename Type // Data type of the matrix
4505  , size_t M // Number of rows
4506  , size_t N > // Number of columns
4507 template< typename Other > // Data type of the right-hand side scalar
4508 inline EnableIf_<IsNumeric<Other>, HybridMatrix<Type,M,N,true> >&
4510 {
4511  using blaze::assign;
4512 
4513  assign( *this, (*this) * rhs );
4514 
4515  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4516 
4517  return *this;
4518 }
4520 //*************************************************************************************************
4521 
4522 
4523 //*************************************************************************************************
4533 template< typename Type // Data type of the matrix
4534  , size_t M // Number of rows
4535  , size_t N > // Number of columns
4536 template< typename Other > // Data type of the right-hand side scalar
4537 inline EnableIf_<IsNumeric<Other>, HybridMatrix<Type,M,N,true> >&
4539 {
4540  using blaze::assign;
4541 
4542  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4543 
4544  assign( *this, (*this) / rhs );
4545 
4546  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4547 
4548  return *this;
4549 }
4551 //*************************************************************************************************
4552 
4553 
4554 
4555 
4556 //=================================================================================================
4557 //
4558 // UTILITY FUNCTIONS
4559 //
4560 //=================================================================================================
4561 
4562 //*************************************************************************************************
4568 template< typename Type // Data type of the matrix
4569  , size_t M // Number of rows
4570  , size_t N > // Number of columns
4571 inline size_t HybridMatrix<Type,M,N,true>::rows() const noexcept
4572 {
4573  return m_;
4574 }
4576 //*************************************************************************************************
4577 
4578 
4579 //*************************************************************************************************
4585 template< typename Type // Data type of the matrix
4586  , size_t M // Number of rows
4587  , size_t N > // Number of columns
4588 inline size_t HybridMatrix<Type,M,N,true>::columns() const noexcept
4589 {
4590  return n_;
4591 }
4593 //*************************************************************************************************
4594 
4595 
4596 //*************************************************************************************************
4605 template< typename Type // Data type of the matrix
4606  , size_t M // Number of rows
4607  , size_t N > // Number of columns
4608 inline constexpr size_t HybridMatrix<Type,M,N,true>::spacing() const noexcept
4609 {
4610  return MM;
4611 }
4613 //*************************************************************************************************
4614 
4615 
4616 //*************************************************************************************************
4622 template< typename Type // Data type of the matrix
4623  , size_t M // Number of rows
4624  , size_t N > // Number of columns
4625 inline constexpr size_t HybridMatrix<Type,M,N,true>::capacity() const noexcept
4626 {
4627  return MM*N;
4628 }
4630 //*************************************************************************************************
4631 
4632 
4633 //*************************************************************************************************
4640 template< typename Type // Data type of the matrix
4641  , size_t M // Number of rows
4642  , size_t N > // Number of columns
4643 inline size_t HybridMatrix<Type,M,N,true>::capacity( size_t j ) const noexcept
4644 {
4645  UNUSED_PARAMETER( j );
4646 
4647  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4648 
4649  return MM;
4650 }
4652 //*************************************************************************************************
4653 
4654 
4655 //*************************************************************************************************
4661 template< typename Type // Data type of the matrix
4662  , size_t M // Number of rows
4663  , size_t N > // Number of columns
4664 inline size_t HybridMatrix<Type,M,N,true>::nonZeros() const
4665 {
4666  size_t nonzeros( 0UL );
4667 
4668  for( size_t j=0UL; j<n_; ++j )
4669  for( size_t i=0UL; i<m_; ++i )
4670  if( !isDefault( v_[i+j*MM] ) )
4671  ++nonzeros;
4672 
4673  return nonzeros;
4674 }
4676 //*************************************************************************************************
4677 
4678 
4679 //*************************************************************************************************
4686 template< typename Type // Data type of the matrix
4687  , size_t M // Number of rows
4688  , size_t N > // Number of columns
4689 inline size_t HybridMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4690 {
4691  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4692 
4693  const size_t iend( j*MM + m_ );
4694  size_t nonzeros( 0UL );
4695 
4696  for( size_t i=j*MM; i<iend; ++i )
4697  if( !isDefault( v_[i] ) )
4698  ++nonzeros;
4699 
4700  return nonzeros;
4701 }
4703 //*************************************************************************************************
4704 
4705 
4706 //*************************************************************************************************
4712 template< typename Type // Data type of the matrix
4713  , size_t M // Number of rows
4714  , size_t N > // Number of columns
4716 {
4717  using blaze::clear;
4718 
4719  for( size_t j=0UL; j<n_; ++j )
4720  for( size_t i=0UL; i<m_; ++i )
4721  clear( v_[i+j*MM] );
4722 }
4724 //*************************************************************************************************
4725 
4726 
4727 //*************************************************************************************************
4737 template< typename Type // Data type of the matrix
4738  , size_t M // Number of rows
4739  , size_t N > // Number of columns
4740 inline void HybridMatrix<Type,M,N,true>::reset( size_t j )
4741 {
4742  using blaze::clear;
4743 
4744  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4745  for( size_t i=0UL; i<m_; ++i )
4746  clear( v_[i+j*MM] );
4747 }
4749 //*************************************************************************************************
4750 
4751 
4752 //*************************************************************************************************
4760 template< typename Type // Data type of the matrix
4761  , size_t M // Number of rows
4762  , size_t N > // Number of columns
4764 {
4765  resize( 0UL, 0UL );
4766 }
4768 //*************************************************************************************************
4769 
4770 
4771 //*************************************************************************************************
4808 template< typename Type // Data type of the matrix
4809  , size_t M // Number of rows
4810  , size_t N > // Number of columns
4811 void HybridMatrix<Type,M,N,true>::resize( size_t m, size_t n, bool preserve )
4812 {
4813  UNUSED_PARAMETER( preserve );
4814 
4815  if( m > M ) {
4816  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4817  }
4818 
4819  if( n > N ) {
4820  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4821  }
4822 
4823  if( IsVectorizable<Type>::value && m < m_ ) {
4824  for( size_t j=0UL; j<n; ++j )
4825  for( size_t i=m; i<m_; ++i )
4826  v_[i+j*MM] = Type();
4827  }
4828 
4829  if( IsVectorizable<Type>::value && n < n_ ) {
4830  for( size_t j=n; j<n_; ++j )
4831  for( size_t i=0UL; i<m_; ++i )
4832  v_[i+j*MM] = Type();
4833  }
4834 
4835  m_ = m;
4836  n_ = n;
4837 }
4839 //*************************************************************************************************
4840 
4841 
4842 //*************************************************************************************************
4858 template< typename Type // Data type of the matrix
4859  , size_t M // Number of rows
4860  , size_t N > // Number of columns
4861 inline void HybridMatrix<Type,M,N,true>::extend( size_t m, size_t n, bool preserve )
4862 {
4863  UNUSED_PARAMETER( preserve );
4864  resize( m_+m, n_+n );
4865 }
4867 //*************************************************************************************************
4868 
4869 
4870 //*************************************************************************************************
4882 template< typename Type // Data type of the matrix
4883  , size_t M // Number of rows
4884  , size_t N > // Number of columns
4885 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::transpose()
4886 {
4887  using std::swap;
4888 
4889  if( m_ > N || n_ > M ) {
4890  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4891  }
4892 
4893  const size_t maxsize( max( m_, n_ ) );
4894  for( size_t j=1UL; j<maxsize; ++j ) {
4895  for( size_t i=0UL; i<j; ++i ) {
4896  swap( v_[i+j*MM], v_[j+i*MM] );
4897  }
4898  }
4899 
4900  if( IsVectorizable<Type>::value && n_ < m_ ) {
4901  for( size_t j=0UL; j<n_; ++j ) {
4902  for( size_t i=n_; i<m_; ++i ) {
4903  v_[i+j*MM] = Type();
4904  }
4905  }
4906  }
4907 
4908  if( IsVectorizable<Type>::value && n_ > m_ ) {
4909  for( size_t j=m_; j<n_; ++j ) {
4910  for( size_t i=0UL; i<m_; ++i ) {
4911  v_[i+j*MM] = Type();
4912  }
4913  }
4914  }
4915 
4916  swap( m_, n_ );
4917 
4918  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4919 
4920  return *this;
4921 }
4923 //*************************************************************************************************
4924 
4925 
4926 //*************************************************************************************************
4938 template< typename Type // Data type of the matrix
4939  , size_t M // Number of rows
4940  , size_t N > // Number of columns
4941 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::ctranspose()
4942 {
4943  using std::swap;
4944 
4945  if( m_ > N || n_ > M ) {
4946  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4947  }
4948 
4949  const size_t maxsize( max( m_, n_ ) );
4950  for( size_t j=0UL; j<maxsize; ++j ) {
4951  for( size_t i=0UL; i<j; ++i ) {
4952  cswap( v_[i+j*MM], v_[j+i*MM] );
4953  }
4954  conjugate( v_[j+j*MM] );
4955  }
4956 
4957  if( IsVectorizable<Type>::value && n_ < m_ ) {
4958  for( size_t j=0UL; j<n_; ++j ) {
4959  for( size_t i=n_; i<m_; ++i ) {
4960  v_[i+j*MM] = Type();
4961  }
4962  }
4963  }
4964 
4965  if( IsVectorizable<Type>::value && n_ > m_ ) {
4966  for( size_t j=m_; j<n_; ++j ) {
4967  for( size_t i=0UL; i<m_; ++i ) {
4968  v_[i+j*MM] = Type();
4969  }
4970  }
4971  }
4972 
4973  swap( m_, n_ );
4974 
4975  BLAZE_INTERNAL_ASSERT( isIntact(), "Invariant violation detected" );
4976 
4977  return *this;
4978 }
4980 //*************************************************************************************************
4981 
4982 
4983 //*************************************************************************************************
4990 template< typename Type // Data type of the matrix
4991  , size_t M // Number of rows
4992  , size_t N > // Number of columns
4993 template< typename Other > // Data type of the scalar value
4994 inline HybridMatrix<Type,M,N,true>&
4995  HybridMatrix<Type,M,N,true>::scale( const Other& scalar )
4996 {
4997  for( size_t j=0UL; j<n_; ++j )
4998  for( size_t i=0UL; i<m_; ++i )
4999  v_[i+j*MM] *= scalar;
5000 
5001  return *this;
5002 }
5004 //*************************************************************************************************
5005 
5006 
5007 //*************************************************************************************************
5014 template< typename Type // Data type of the matrix
5015  , size_t M // Number of rows
5016  , size_t N > // Number of columns
5017 inline void HybridMatrix<Type,M,N,true>::swap( HybridMatrix& m ) noexcept
5018 {
5019  using std::swap;
5020 
5021  const size_t maxrows( max( m_, m.m_ ) );
5022  const size_t maxcols( max( n_, m.n_ ) );
5023 
5024  for( size_t j=0UL; j<maxcols; ++j ) {
5025  for( size_t i=0UL; i<maxrows; ++i ) {
5026  swap( v_[i+j*MM], m(i,j) );
5027  }
5028  }
5029 
5030  swap( m_, m.m_ );
5031  swap( n_, m.n_ );
5032 }
5034 //*************************************************************************************************
5035 
5036 
5037 
5038 
5039 //=================================================================================================
5040 //
5041 // MEMORY FUNCTIONS
5042 //
5043 //=================================================================================================
5044 
5045 //*************************************************************************************************
5056 template< typename Type // Data type of the matrix
5057  , size_t M // Number of rows
5058  , size_t N > // Number of columns
5059 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size )
5060 {
5061  UNUSED_PARAMETER( size );
5062 
5063  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5064 
5065  return allocate<HybridMatrix>( 1UL );
5066 }
5068 //*************************************************************************************************
5069 
5070 
5071 //*************************************************************************************************
5082 template< typename Type // Data type of the matrix
5083  , size_t M // Number of rows
5084  , size_t N > // Number of columns
5085 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size )
5086 {
5087  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5088  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5089 
5090  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5091 }
5093 //*************************************************************************************************
5094 
5095 
5096 //*************************************************************************************************
5107 template< typename Type // Data type of the matrix
5108  , size_t M // Number of rows
5109  , size_t N > // Number of columns
5110 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
5111 {
5112  UNUSED_PARAMETER( size );
5113 
5114  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
5115 
5116  return allocate<HybridMatrix>( 1UL );
5117 }
5119 //*************************************************************************************************
5120 
5121 
5122 //*************************************************************************************************
5133 template< typename Type // Data type of the matrix
5134  , size_t M // Number of rows
5135  , size_t N > // Number of columns
5136 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
5137 {
5138  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
5139  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
5140 
5141  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
5142 }
5144 //*************************************************************************************************
5145 
5146 
5147 //*************************************************************************************************
5154 template< typename Type // Data type of the matrix
5155  , size_t M // Number of rows
5156  , size_t N > // Number of columns
5157 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr )
5158 {
5159  deallocate( static_cast<HybridMatrix*>( ptr ) );
5160 }
5162 //*************************************************************************************************
5163 
5164 
5165 //*************************************************************************************************
5172 template< typename Type // Data type of the matrix
5173  , size_t M // Number of rows
5174  , size_t N > // Number of columns
5175 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr )
5176 {
5177  deallocate( static_cast<HybridMatrix*>( ptr ) );
5178 }
5180 //*************************************************************************************************
5181 
5182 
5183 //*************************************************************************************************
5190 template< typename Type // Data type of the matrix
5191  , size_t M // Number of rows
5192  , size_t N > // Number of columns
5193 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
5194 {
5195  deallocate( static_cast<HybridMatrix*>( ptr ) );
5196 }
5198 //*************************************************************************************************
5199 
5200 
5201 //*************************************************************************************************
5208 template< typename Type // Data type of the matrix
5209  , size_t M // Number of rows
5210  , size_t N > // Number of columns
5211 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
5212 {
5213  deallocate( static_cast<HybridMatrix*>( ptr ) );
5214 }
5216 //*************************************************************************************************
5217 
5218 
5219 
5220 
5221 //=================================================================================================
5222 //
5223 // DEBUGGING FUNCTIONS
5224 //
5225 //=================================================================================================
5226 
5227 //*************************************************************************************************
5237 template< typename Type // Data type of the matrix
5238  , size_t M // Number of rows
5239  , size_t N > // Number of columns
5240 inline bool HybridMatrix<Type,M,N,true>::isIntact() const noexcept
5241 {
5242  if( m_ > M || n_ > N )
5243  return false;
5244 
5245  if( IsNumeric<Type>::value )
5246  {
5247  for( size_t j=0UL; j<n_; ++j ) {
5248  for( size_t i=m_; i<MM; ++i ) {
5249  if( v_[i+j*MM] != Type() )
5250  return false;
5251  }
5252  }
5253 
5254  for( size_t j=n_; j<N; ++j ) {
5255  for( size_t i=0UL; i<MM; ++i ) {
5256  if( v_[i+j*MM] != Type() )
5257  return false;
5258  }
5259  }
5260  }
5261 
5262  return true;
5263 }
5265 //*************************************************************************************************
5266 
5267 
5268 
5269 
5270 //=================================================================================================
5271 //
5272 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5273 //
5274 //=================================================================================================
5275 
5276 //*************************************************************************************************
5287 template< typename Type // Data type of the matrix
5288  , size_t M // Number of rows
5289  , size_t N > // Number of columns
5290 template< typename Other > // Data type of the foreign expression
5291 inline bool HybridMatrix<Type,M,N,true>::canAlias( const Other* alias ) const noexcept
5292 {
5293  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5294 }
5296 //*************************************************************************************************
5297 
5298 
5299 //*************************************************************************************************
5310 template< typename Type // Data type of the matrix
5311  , size_t M // Number of rows
5312  , size_t N > // Number of columns
5313 template< typename Other > // Data type of the foreign expression
5314 inline bool HybridMatrix<Type,M,N,true>::isAliased( const Other* alias ) const noexcept
5315 {
5316  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
5317 }
5319 //*************************************************************************************************
5320 
5321 
5322 //*************************************************************************************************
5332 template< typename Type // Data type of the matrix
5333  , size_t M // Number of rows
5334  , size_t N > // Number of columns
5335 inline bool HybridMatrix<Type,M,N,true>::isAligned() const noexcept
5336 {
5337  return ( usePadding || rows() % SIMDSIZE == 0UL );
5338 }
5340 //*************************************************************************************************
5341 
5342 
5343 //*************************************************************************************************
5358 template< typename Type // Data type of the matrix
5359  , size_t M // Number of rows
5360  , size_t N > // Number of columns
5361 BLAZE_ALWAYS_INLINE typename HybridMatrix<Type,M,N,true>::SIMDType
5362  HybridMatrix<Type,M,N,true>::load( size_t i, size_t j ) const noexcept
5363 {
5364  if( usePadding )
5365  return loada( i, j );
5366  else
5367  return loadu( i, j );
5368 }
5370 //*************************************************************************************************
5371 
5372 
5373 //*************************************************************************************************
5388 template< typename Type // Data type of the matrix
5389  , size_t M // Number of rows
5390  , size_t N > // Number of columns
5391 BLAZE_ALWAYS_INLINE typename HybridMatrix<Type,M,N,true>::SIMDType
5392  HybridMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const noexcept
5393 {
5394  using blaze::loada;
5395 
5397 
5398  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5399  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5400  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5401  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5402  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5403 
5404  return loada( &v_[i+j*MM] );
5405 }
5407 //*************************************************************************************************
5408 
5409 
5410 //*************************************************************************************************
5425 template< typename Type // Data type of the matrix
5426  , size_t M // Number of rows
5427  , size_t N > // Number of columns
5428 BLAZE_ALWAYS_INLINE typename HybridMatrix<Type,M,N,true>::SIMDType
5429  HybridMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const noexcept
5430 {
5431  using blaze::loadu;
5432 
5434 
5435  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5436  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5437  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5438 
5439  return loadu( &v_[i+j*MM] );
5440 }
5442 //*************************************************************************************************
5443 
5444 
5445 //*************************************************************************************************
5461 template< typename Type // Data type of the matrix
5462  , size_t M // Number of rows
5463  , size_t N > // Number of columns
5465  HybridMatrix<Type,M,N,true>::store( size_t i, size_t j, const SIMDType& value ) noexcept
5466 {
5467  if( usePadding )
5468  storea( i, j, value );
5469  else
5470  storeu( i, j, value );
5471 }
5473 //*************************************************************************************************
5474 
5475 
5476 //*************************************************************************************************
5492 template< typename Type // Data type of the matrix
5493  , size_t M // Number of rows
5494  , size_t N > // Number of columns
5496  HybridMatrix<Type,M,N,true>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
5497 {
5498  using blaze::storea;
5499 
5501 
5502  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5503  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5504  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5505  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5506  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5507 
5508  storea( &v_[i+j*MM], value );
5509 }
5511 //*************************************************************************************************
5512 
5513 
5514 //*************************************************************************************************
5530 template< typename Type // Data type of the matrix
5531  , size_t M // Number of rows
5532  , size_t N > // Number of columns
5534  HybridMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
5535 {
5536  using blaze::storeu;
5537 
5539 
5540  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5541  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5542  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5543 
5544  storeu( &v_[i+j*MM], value );
5545 }
5547 //*************************************************************************************************
5548 
5549 
5550 //*************************************************************************************************
5567 template< typename Type // Data type of the matrix
5568  , size_t M // Number of rows
5569  , size_t N > // Number of columns
5571  HybridMatrix<Type,M,N,true>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
5572 {
5573  using blaze::stream;
5574 
5576 
5577  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5578  BLAZE_INTERNAL_ASSERT( i + SIMDSIZE <= MM, "Invalid row access index" );
5579  BLAZE_INTERNAL_ASSERT( !usePadding || i % SIMDSIZE == 0UL, "Invalid row access index" );
5580  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5581  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5582 
5583  stream( &v_[i+j*MM], value );
5584 }
5586 //*************************************************************************************************
5587 
5588 
5589 //*************************************************************************************************
5601 template< typename Type // Data type of the matrix
5602  , size_t M // Number of rows
5603  , size_t N > // Number of columns
5604 template< typename MT // Type of the right-hand side dense matrix
5605  , bool SO > // Storage order of the right-hand side dense matrix
5606 inline DisableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >
5607  HybridMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5608 {
5609  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5610 
5611  for( size_t j=0UL; j<n_; ++j ) {
5612  for( size_t i=0UL; i<m_; ++i ) {
5613  v_[i+j*MM] = (~rhs)(i,j);
5614  }
5615  }
5616 }
5618 //*************************************************************************************************
5619 
5620 
5621 //*************************************************************************************************
5633 template< typename Type // Data type of the matrix
5634  , size_t M // Number of rows
5635  , size_t N > // Number of columns
5636 template< typename MT // Type of the right-hand side dense matrix
5637  , bool SO > // Storage order of the right-hand side dense matrix
5638 inline EnableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >
5639  HybridMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5640 {
5642 
5643  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5644 
5645  const bool remainder( !usePadding || !IsPadded<MT>::value );
5646 
5647  const size_t ipos( ( remainder )?( m_ & size_t(-SIMDSIZE) ):( m_ ) );
5648  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5649 
5650  for( size_t j=0UL; j<n_; ++j )
5651  {
5652  size_t i( 0UL );
5653 
5654  for( ; i<ipos; i+=SIMDSIZE ) {
5655  store( i, j, (~rhs).load(i,j) );
5656  }
5657  for( ; remainder && i<m_; ++i ) {
5658  v_[i+j*MM] = (~rhs)(i,j);
5659  }
5660  }
5661 }
5663 //*************************************************************************************************
5664 
5665 
5666 //*************************************************************************************************
5678 template< typename Type // Data type of the matrix
5679  , size_t M // Number of rows
5680  , size_t N > // Number of columns
5681 template< typename MT > // Type of the right-hand side sparse matrix
5682 inline void HybridMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,true>& rhs )
5683 {
5684  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5685 
5686  for( size_t j=0UL; j<n_; ++j )
5687  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5688  v_[element->index()+j*MM] = element->value();
5689 }
5691 //*************************************************************************************************
5692 
5693 
5694 //*************************************************************************************************
5706 template< typename Type // Data type of the matrix
5707  , size_t M // Number of rows
5708  , size_t N > // Number of columns
5709 template< typename MT > // Type of the right-hand side sparse matrix
5710 inline void HybridMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,false>& rhs )
5711 {
5713 
5714  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5715 
5716  for( size_t i=0UL; i<m_; ++i )
5717  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5718  v_[i+element->index()*MM] = element->value();
5719 }
5721 //*************************************************************************************************
5722 
5723 
5724 //*************************************************************************************************
5736 template< typename Type // Data type of the matrix
5737  , size_t M // Number of rows
5738  , size_t N > // Number of columns
5739 template< typename MT // Type of the right-hand side dense matrix
5740  , bool SO > // Storage order of the right-hand side dense matrix
5741 inline DisableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5742  HybridMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5743 {
5744  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5745 
5746  for( size_t j=0UL; j<n_; ++j )
5747  {
5748  if( IsDiagonal<MT>::value )
5749  {
5750  v_[j+j*MM] += (~rhs)(j,j);
5751  }
5752  else
5753  {
5754  const size_t ibegin( ( IsLower<MT>::value )
5755  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5756  :( 0UL ) );
5757  const size_t iend ( ( IsUpper<MT>::value )
5758  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5759  :( m_ ) );
5760  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5761 
5762  for( size_t i=ibegin; i<iend; ++i ) {
5763  v_[i+j*MM] += (~rhs)(i,j);
5764  }
5765  }
5766  }
5767 }
5769 //*************************************************************************************************
5770 
5771 
5772 //*************************************************************************************************
5784 template< typename Type // Data type of the matrix
5785  , size_t M // Number of rows
5786  , size_t N > // Number of columns
5787 template< typename MT // Type of the right-hand side dense matrix
5788  , bool SO > // Storage order of the right-hand side dense matrix
5789 inline EnableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >
5790  HybridMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5791 {
5794 
5795  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5796 
5797  const bool remainder( !usePadding || !IsPadded<MT>::value );
5798 
5799  for( size_t j=0UL; j<n_; ++j )
5800  {
5801  const size_t ibegin( ( IsLower<MT>::value )
5802  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5803  :( 0UL ) );
5804  const size_t iend ( ( IsUpper<MT>::value )
5805  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5806  :( m_ ) );
5807  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5808 
5809  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5810  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5811 
5812  size_t i( ibegin );
5813 
5814  for( ; i<ipos; i+=SIMDSIZE ) {
5815  store( i, j, load(i,j) + (~rhs).load(i,j) );
5816  }
5817  for( ; remainder && i<iend; ++i ) {
5818  v_[i+j*MM] += (~rhs)(i,j);
5819  }
5820  }
5821 }
5823 //*************************************************************************************************
5824 
5825 
5826 //*************************************************************************************************
5838 template< typename Type // Data type of the matrix
5839  , size_t M // Number of rows
5840  , size_t N > // Number of columns
5841 template< typename MT > // Type of the right-hand side sparse matrix
5842 inline void HybridMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,true>& rhs )
5843 {
5844  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5845 
5846  for( size_t j=0UL; j<n_; ++j )
5847  for( ConstIterator_<MT> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5848  v_[element->index()+j*MM] += element->value();
5849 }
5851 //*************************************************************************************************
5852 
5853 
5854 //*************************************************************************************************
5866 template< typename Type // Data type of the matrix
5867  , size_t M // Number of rows
5868  , size_t N > // Number of columns
5869 template< typename MT > // Type of the right-hand side sparse matrix
5870 inline void HybridMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,false>& rhs )
5871 {
5873 
5874  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5875 
5876  for( size_t i=0UL; i<m_; ++i )
5877  for( ConstIterator_<MT> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5878  v_[i+element->index()*MM] += element->value();
5879 }
5881 //*************************************************************************************************
5882 
5883 
5884 //*************************************************************************************************
5896 template< typename Type // Data type of the matrix
5897  , size_t M // Number of rows
5898  , size_t N > // Number of columns
5899 template< typename MT // Type of the right-hand side dense matrix
5900  , bool SO > // Storage order of the right-hand side dense matrix
5901 inline DisableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5902  HybridMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5903 {
5904  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5905 
5906  for( size_t j=0UL; j<n_; ++j )
5907  {
5908  if( IsDiagonal<MT>::value )
5909  {
5910  v_[j+j*MM] -= (~rhs)(j,j);
5911  }
5912  else
5913  {
5914  const size_t ibegin( ( IsLower<MT>::value )
5915  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5916  :( 0UL ) );
5917  const size_t iend ( ( IsUpper<MT>::value )
5918  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5919  :( m_ ) );
5920  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5921 
5922  for( size_t i=ibegin; i<iend; ++i ) {
5923  v_[i+j*MM] -= (~rhs)(i,j);
5924  }
5925  }
5926  }
5927 }
5929 //*************************************************************************************************
5930 
5931 
5932 //*************************************************************************************************
5944 template< typename Type // Data type of the matrix
5945  , size_t M // Number of rows
5946  , size_t N > // Number of columns
5947 template< typename MT // Type of the right-hand side dense matrix
5948  , bool SO > // Storage order of the right-hand side dense matrix
5949 inline EnableIf_<typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >
5950  HybridMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5951 {
5954 
5955  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5956 
5957  const bool remainder( !usePadding || !IsPadded<MT>::value );
5958 
5959  for( size_t j=0UL; j<n_; ++j )
5960  {
5961  const size_t ibegin( ( IsLower<MT>::value )
5962  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
5963  :( 0UL ) );
5964  const size_t iend ( ( IsUpper<MT>::value )
5965  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5966  :( m_ ) );
5967  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5968 
5969  const size_t ipos( ( remainder )?( iend & size_t(-SIMDSIZE) ):( iend ) );
5970  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
5971 
5972  size_t i( ibegin );
5973 
5974  for( ; i<ipos; i+=SIMDSIZE ) {
5975  store( i, j, load(i,j) - (~rhs).load(i,j) );
5976  }
5977  for( ; remainder && i<iend; ++i ) {
5978  v_[i+j*MM] -= (~rhs)(i,j);
5979  }
5980  }
5981 }
5983 //*************************************************************************************************
5984 
5985 
5986 //*************************************************************************************************
5998 template< typename Type // Data type of the matrix
5999  , size_t M // Number of rows
6000  , size_t N > // Number of columns
6001 template< typename MT > // Type of the right-hand side sparse matrix
6002 inline void HybridMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,true>& rhs )
6003 {
6004  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6005 
6006  typedef ConstIterator_<MT> RhsConstIterator;
6007 
6008  for( size_t j=0UL; j<n_; ++j )
6009  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
6010  v_[element->index()+j*MM] -= element->value();
6011 }
6013 //*************************************************************************************************
6014 
6015 
6016 //*************************************************************************************************
6028 template< typename Type // Data type of the matrix
6029  , size_t M // Number of rows
6030  , size_t N > // Number of columns
6031 template< typename MT > // Type of the right-hand side sparse matrix
6032 inline void HybridMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,false>& rhs )
6033 {
6035 
6036  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
6037 
6038  typedef ConstIterator_<MT> RhsConstIterator;
6039 
6040  for( size_t i=0UL; i<m_; ++i )
6041  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
6042  v_[i+element->index()*MM] -= element->value();
6043 }
6045 //*************************************************************************************************
6046 
6047 
6048 
6049 
6050 
6051 
6052 
6053 
6054 //=================================================================================================
6055 //
6056 // UNDEFINED CLASS TEMPLATE SPECIALIZATIONS
6057 //
6058 //=================================================================================================
6059 
6060 //*************************************************************************************************
6068 template< typename Type // Data type of the matrix
6069  , size_t M // Number of rows
6070  , bool SO > // Storage order
6071 class HybridMatrix<Type,M,0UL,SO>;
6073 //*************************************************************************************************
6074 
6075 
6076 //*************************************************************************************************
6084 template< typename Type // Data type of the matrix
6085  , size_t N // Number of columns
6086  , bool SO > // Storage order
6087 class HybridMatrix<Type,0UL,N,SO>;
6089 //*************************************************************************************************
6090 
6091 
6092 //*************************************************************************************************
6100 template< typename Type // Data type of the matrix
6101  , bool SO > // Storage order
6102 class HybridMatrix<Type,0UL,0UL,SO>;
6104 //*************************************************************************************************
6105 
6106 
6107 
6108 
6109 
6110 
6111 
6112 
6113 //=================================================================================================
6114 //
6115 // STATICMATRIX OPERATORS
6116 //
6117 //=================================================================================================
6118 
6119 //*************************************************************************************************
6122 template< typename Type, size_t M, size_t N, bool SO >
6123 inline void reset( HybridMatrix<Type,M,N,SO>& m );
6124 
6125 template< typename Type, size_t M, size_t N, bool SO >
6126 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i );
6127 
6128 template< typename Type, size_t M, size_t N, bool SO >
6129 inline void clear( HybridMatrix<Type,M,N,SO>& m );
6130 
6131 template< typename Type, size_t M, size_t N, bool SO >
6132 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m );
6133 
6134 template< typename Type, size_t M, size_t N, bool SO >
6135 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m ) noexcept;
6136 
6137 template< typename Type, size_t M, size_t N, bool SO >
6138 inline void swap( HybridMatrix<Type,M,N,SO>& a, HybridMatrix<Type,M,N,SO>& b ) noexcept;
6140 //*************************************************************************************************
6141 
6142 
6143 //*************************************************************************************************
6150 template< typename Type // Data type of the matrix
6151  , size_t M // Number of rows
6152  , size_t N // Number of columns
6153  , bool SO > // Storage order
6155 {
6156  m.reset();
6157 }
6158 //*************************************************************************************************
6159 
6160 
6161 //*************************************************************************************************
6174 template< typename Type // Data type of the matrix
6175  , size_t M // Number of rows
6176  , size_t N // Number of columns
6177  , bool SO > // Storage order
6178 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i )
6179 {
6180  m.reset( i );
6181 }
6182 //*************************************************************************************************
6183 
6184 
6185 //*************************************************************************************************
6192 template< typename Type // Data type of the matrix
6193  , size_t M // Number of rows
6194  , size_t N // Number of columns
6195  , bool SO > // Storage order
6197 {
6198  m.clear();
6199 }
6200 //*************************************************************************************************
6201 
6202 
6203 //*************************************************************************************************
6221 template< typename Type // Data type of the matrix
6222  , size_t M // Number of rows
6223  , size_t N // Number of columns
6224  , bool SO > // Storage order
6225 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m )
6226 {
6227  return ( m.rows() == 0UL && m.columns() == 0UL );
6228 }
6229 //*************************************************************************************************
6230 
6231 
6232 //*************************************************************************************************
6250 template< typename Type // Data type of the matrix
6251  , size_t M // Number of rows
6252  , size_t N // Number of columns
6253  , bool SO > // Storage order
6254 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m ) noexcept
6255 {
6256  return m.isIntact();
6257 }
6258 //*************************************************************************************************
6259 
6260 
6261 //*************************************************************************************************
6269 template< typename Type // Data type of the matrix
6270  , size_t M // Number of rows
6271  , size_t N // Number of columns
6272  , bool SO > // Storage order
6274 {
6275  a.swap( b );
6276 }
6277 //*************************************************************************************************
6278 
6279 
6280 
6281 
6282 //=================================================================================================
6283 //
6284 // HASCONSTDATAACCESS SPECIALIZATIONS
6285 //
6286 //=================================================================================================
6287 
6288 //*************************************************************************************************
6290 template< typename T, size_t M, size_t N, bool SO >
6291 struct HasConstDataAccess< HybridMatrix<T,M,N,SO> > : public TrueType
6292 {};
6294 //*************************************************************************************************
6295 
6296 
6297 
6298 
6299 //=================================================================================================
6300 //
6301 // HASMUTABLEDATAACCESS SPECIALIZATIONS
6302 //
6303 //=================================================================================================
6304 
6305 //*************************************************************************************************
6307 template< typename T, size_t M, size_t N, bool SO >
6308 struct HasMutableDataAccess< HybridMatrix<T,M,N,SO> > : public TrueType
6309 {};
6311 //*************************************************************************************************
6312 
6313 
6314 
6315 
6316 //=================================================================================================
6317 //
6318 // ISALIGNED SPECIALIZATIONS
6319 //
6320 //=================================================================================================
6321 
6322 //*************************************************************************************************
6324 template< typename T, size_t M, size_t N, bool SO >
6325 struct IsAligned< HybridMatrix<T,M,N,SO> > : public BoolConstant<usePadding>
6326 {};
6328 //*************************************************************************************************
6329 
6330 
6331 
6332 
6333 //=================================================================================================
6334 //
6335 // ISPADDED SPECIALIZATIONS
6336 //
6337 //=================================================================================================
6338 
6339 //*************************************************************************************************
6341 template< typename T, size_t M, size_t N, bool SO >
6342 struct IsPadded< HybridMatrix<T,M,N,SO> > : public BoolConstant<usePadding>
6343 {};
6345 //*************************************************************************************************
6346 
6347 
6348 
6349 
6350 //=================================================================================================
6351 //
6352 // ISRESIZABLE SPECIALIZATIONS
6353 //
6354 //=================================================================================================
6355 
6356 //*************************************************************************************************
6358 template< typename T, size_t M, size_t N, bool SO >
6359 struct IsResizable< HybridMatrix<T,M,N,SO> > : public TrueType
6360 {};
6362 //*************************************************************************************************
6363 
6364 
6365 
6366 
6367 //=================================================================================================
6368 //
6369 // ADDTRAIT SPECIALIZATIONS
6370 //
6371 //=================================================================================================
6372 
6373 //*************************************************************************************************
6375 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6376 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6377 {
6378  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, SO >;
6379 };
6380 
6381 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6382 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6383 {
6384  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, false >;
6385 };
6386 
6387 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6388 struct AddTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6389 {
6390  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, SO >;
6391 };
6392 
6393 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6394 struct AddTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6395 {
6396  using Type = StaticMatrix< AddTrait_<T1,T2>, M2, N2, false >;
6397 };
6398 
6399 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6400 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6401 {
6402  using Type = HybridMatrix< AddTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6403 };
6404 
6405 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6406 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6407 {
6408  using Type = HybridMatrix< AddTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6409 };
6411 //*************************************************************************************************
6412 
6413 
6414 
6415 
6416 //=================================================================================================
6417 //
6418 // SUBTRAIT SPECIALIZATIONS
6419 //
6420 //=================================================================================================
6421 
6422 //*************************************************************************************************
6424 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6425 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6426 {
6427  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, SO >;
6428 };
6429 
6430 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6431 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6432 {
6433  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, false >;
6434 };
6435 
6436 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6437 struct SubTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6438 {
6439  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, SO >;
6440 };
6441 
6442 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6443 struct SubTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6444 {
6445  using Type = StaticMatrix< SubTrait_<T1,T2>, M2, N2, false >;
6446 };
6447 
6448 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6449 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6450 {
6451  using Type = HybridMatrix< SubTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO >;
6452 };
6453 
6454 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6455 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6456 {
6457  using Type = HybridMatrix< SubTrait_<T1,T2>, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false >;
6458 };
6460 //*************************************************************************************************
6461 
6462 
6463 
6464 
6465 //=================================================================================================
6466 //
6467 // MULTTRAIT SPECIALIZATIONS
6468 //
6469 //=================================================================================================
6470 
6471 //*************************************************************************************************
6473 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6474 struct MultTrait< HybridMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6475 {
6476  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6477 };
6478 
6479 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6480 struct MultTrait< T1, HybridMatrix<T2,M,N,SO>, EnableIf_<IsNumeric<T1> > >
6481 {
6482  using Type = HybridMatrix< MultTrait_<T1,T2>, M, N, SO >;
6483 };
6484 
6485 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6486 struct MultTrait< HybridMatrix<T1,M,N,SO>, StaticVector<T2,K,false> >
6487 {
6488  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6489 };
6490 
6491 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6492 struct MultTrait< StaticVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6493 {
6494  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6495 };
6496 
6497 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6498 struct MultTrait< HybridMatrix<T1,M,N,SO>, HybridVector<T2,K,false> >
6499 {
6500  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6501 };
6502 
6503 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6504 struct MultTrait< HybridVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6505 {
6506  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6507 };
6508 
6509 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6510 struct MultTrait< HybridMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
6511 {
6512  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6513 };
6514 
6515 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6516 struct MultTrait< DynamicVector<T1,true>, HybridMatrix<T2,M,N,SO> >
6517 {
6518  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6519 };
6520 
6521 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6522 struct MultTrait< HybridMatrix<T1,M,N,SO>, CustomVector<T2,AF,PF,false> >
6523 {
6524  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6525 };
6526 
6527 template< typename T1, bool AF, bool PF, typename T2, size_t M, size_t N, bool SO >
6528 struct MultTrait< CustomVector<T1,AF,PF,true>, HybridMatrix<T2,M,N,SO> >
6529 {
6530  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6531 };
6532 
6533 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6534 struct MultTrait< HybridMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
6535 {
6536  using Type = HybridVector< MultTrait_<T1,T2>, M, false >;
6537 };
6538 
6539 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6540 struct MultTrait< CompressedVector<T1,true>, HybridMatrix<T2,M,N,SO> >
6541 {
6542  using Type = HybridVector< MultTrait_<T1,T2>, N, true >;
6543 };
6544 
6545 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6546 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6547 {
6548  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
6549 };
6550 
6551 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6552 struct MultTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6553 {
6554  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
6555 };
6556 
6557 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6558 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6559 {
6560  using Type = HybridMatrix< MultTrait_<T1,T2>, M1, N2, SO1 >;
6561 };
6563 //*************************************************************************************************
6564 
6565 
6566 
6567 
6568 //=================================================================================================
6569 //
6570 // DIVTRAIT SPECIALIZATIONS
6571 //
6572 //=================================================================================================
6573 
6574 //*************************************************************************************************
6576 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6577 struct DivTrait< HybridMatrix<T1,M,N,SO>, T2, EnableIf_<IsNumeric<T2> > >
6578 {
6579  using Type = HybridMatrix< DivTrait_<T1,T2>, M, N, SO >;
6580 };
6582 //*************************************************************************************************
6583 
6584 
6585 
6586 
6587 //=================================================================================================
6588 //
6589 // MATHTRAIT SPECIALIZATIONS
6590 //
6591 //=================================================================================================
6592 
6593 //*************************************************************************************************
6595 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6596 struct MathTrait< HybridMatrix<T1,M,N,SO>, HybridMatrix<T2,M,N,SO> >
6597 {
6598  using HighType = HybridMatrix< typename MathTrait<T1,T2>::HighType, M, N, SO >;
6599  using LowType = HybridMatrix< typename MathTrait<T1,T2>::LowType , M, N, SO >;
6600 };
6602 //*************************************************************************************************
6603 
6604 
6605 
6606 
6607 //=================================================================================================
6608 //
6609 // SUBMATRIXTRAIT SPECIALIZATIONS
6610 //
6611 //=================================================================================================
6612 
6613 //*************************************************************************************************
6615 template< typename T1, size_t M, size_t N, bool SO >
6616 struct SubmatrixTrait< HybridMatrix<T1,M,N,SO> >
6617 {
6618  using Type = HybridMatrix<T1,M,N,SO>;
6619 };
6621 //*************************************************************************************************
6622 
6623 
6624 
6625 
6626 //=================================================================================================
6627 //
6628 // ROWTRAIT SPECIALIZATIONS
6629 //
6630 //=================================================================================================
6631 
6632 //*************************************************************************************************
6634 template< typename T1, size_t M, size_t N, bool SO >
6635 struct RowTrait< HybridMatrix<T1,M,N,SO> >
6636 {
6637  using Type = HybridVector<T1,N,true>;
6638 };
6640 //*************************************************************************************************
6641 
6642 
6643 
6644 
6645 //=================================================================================================
6646 //
6647 // COLUMNTRAIT SPECIALIZATIONS
6648 //
6649 //=================================================================================================
6650 
6651 //*************************************************************************************************
6653 template< typename T1, size_t M, size_t N, bool SO >
6654 struct ColumnTrait< HybridMatrix<T1,M,N,SO> >
6655 {
6656  using Type = HybridVector<T1,M,false>;
6657 };
6659 //*************************************************************************************************
6660 
6661 } // namespace blaze
6662 
6663 #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
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
Header file for the NextMultiple class template.
#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.
Header file for the subtraction trait.
Type ElementType
Type of the matrix elements.
Definition: HybridMatrix.h:222
Header file for basic type definitions.
constexpr size_t spacing() const noexcept
Returns the spacing between the beginning of two rows.
Definition: HybridMatrix.h:1689
constexpr size_t capacity() const noexcept
Returns the maximum capacity of the matrix.
Definition: HybridMatrix.h:1705
Header file for the row trait.
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:258
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1339
Header file for the IsSame and IsStrictlySame type traits.
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:188
typename SIMDTrait< T >::Type SIMDTrait_
Auxiliary alias declaration for the SIMDTrait class template.The SIMDTrait_ alias declaration provide...
Definition: SIMDTrait.h:315
Iterator begin(size_t i) noexcept
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1127
Header file for the IsColumnMajorMatrix type trait.
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: HybridMatrix.h:979
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:533
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2805
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:223
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: HybridMatrix.h:230
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:88
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:590
Iterator end(size_t i) noexcept
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1199
#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:228
Header file for the SizeT class template.
SIMDTrait_< ElementType > SIMDType
SIMD type of the matrix elements.
Definition: HybridMatrix.h:223
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
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:88
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
Header file for memory allocation and deallocation functionality.
System settings for performance optimizations.
HybridMatrix< Type, N, M,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: HybridMatrix.h:221
Type & Reference
Reference to a non-constant matrix value.
Definition: HybridMatrix.h:227
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
STL namespace.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
typename T::ResultType ResultType_
Alias declaration for nested ResultType type definitions.The ResultType_ alias declaration provides a...
Definition: Aliases.h:323
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1716
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:70
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:109
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
Constraint on the data type.
Header file for the std::initializer_list aliases.
Header file for the SparseMatrix base class.
const This & CompositeType
Data type for composite expression templates.
Definition: HybridMatrix.h:225
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: HybridMatrix.h:1896
size_t rows() const noexcept
Returns the current number of rows of the matrix.
Definition: HybridMatrix.h:1654
ConstIterator cend(size_t i) const noexcept
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1247
typename TransExprTrait< T >::Type TransExprTrait_
Auxiliary alias declaration for the TransExprTrait class template.The TransExprTrait_ alias declarati...
Definition: TransExprTrait.h:143
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
typename CTransExprTrait< T >::Type CTransExprTrait_
Auxiliary alias declaration for the CTransExprTrait class template.The CTransExprTrait_ alias declara...
Definition: CTransExprTrait.h:143
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b) noexcept
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:5148
HybridMatrix & operator=(const Type &set)
Homogenous assignment to all matrix elements.
Definition: HybridMatrix.h:1273
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:2601
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:2496
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:2532
Header file for all forward declarations of the math module.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2647
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: HybridMatrix.h:1747
#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.
Header file for the DenseMatrix base class.
Header file for the DenseIterator class template.
bool isIntact() const noexcept
Returns whether the invariants of the hybrid matrix are intact.
Definition: HybridMatrix.h:2310
Header file for all SIMD functionality.
HybridMatrix()
The default constructor for HybridMatrix.
Definition: HybridMatrix.h:521
Type * Pointer
Pointer to a non-constant matrix value.
Definition: HybridMatrix.h:229
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:930
const Type & ReturnType
Return type for expression template evaluations.
Definition: HybridMatrix.h:224
Header file for the IsLower type trait.
size_t m_
The current number of rows of the matrix.
Definition: HybridMatrix.h:485
Header file for the IsAligned type trait.
HybridMatrix< Type, M, N, SO > This
Type of this HybridMatrix instance.
Definition: HybridMatrix.h:217
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:90
BLAZE_ALWAYS_INLINE SIMDType load(size_t i, size_t j) const noexcept
Load of a SIMD element of the matrix.
Definition: HybridMatrix.h:2429
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:330
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:1801
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:2459
Header file for the exception macros of the math module.
HybridMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: HybridMatrix.h:2023
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
BLAZE_ALWAYS_INLINE void resize(Matrix< MT, SO > &matrix, size_t rows, size_t columns, bool preserve=true)
Changing the size of the matrix.
Definition: Matrix.h:538
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:254
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
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.
ConstIterator cbegin(size_t i) const noexcept
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1175
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:220
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:2638
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
Header file for the HasConstDataAccess type trait.
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:2096
AlignedArray< Type, M *NN > v_
The statically allocated matrix elements.
Definition: HybridMatrix.h:475
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:2563
#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
Pointer data() noexcept
Low-level data access to the matrix elements.
Definition: HybridMatrix.h:1038
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:218
Header file for run time assertion macros.
size_t columns() const noexcept
Returns the current number of columns of the matrix.
Definition: HybridMatrix.h:1670
HybridMatrix & transpose()
In-place transpose of the matrix.
Definition: HybridMatrix.h:1968
Header file for the addition trait.
Header file for the division trait.
Header file for the InvExprTrait class template.
Header file for the submatrix trait.
bool isAligned() const noexcept
Returns whether the matrix is properly aligned in memory.
Definition: HybridMatrix.h:2402
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: HybridMatrix.h:219
Constraint on the data type.
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: HybridMatrix.h:232
Header file for the AlignedArray implementation.
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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2646
bool isAliased(const Other *alias) const noexcept
Returns whether the matrix is aliased with the given address alias.
Definition: HybridMatrix.h:2382
Header file for the column trait.
Header file for the isDefault shim.
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b) noexcept
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:258
Header file for the TransExprTrait class template.
Constraint on the data type.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:89
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
BLAZE_ALWAYS_INLINE void conjugate(T &a) noexcept(IsNumeric< T >::value)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
Header file for the HasMutableDataAccess type trait.
IntegralConstant< bool, B > BoolConstant
Generic wrapper for a compile time constant boolean value.The BoolConstant class template represents ...
Definition: IntegralConstant.h:100
EnableIf_< IsBuiltin< T > > deallocate(T *address) noexcept
Deallocation of memory for built-in data types.
Definition: Memory.h:225
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:223
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
Header file for the mathematical trait.
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b) noexcept(IsNumeric< T >::value)
Swapping two conjugated values/objects.
Definition: Conjugate.h:195
BLAZE_ALWAYS_INLINE bool checkAlignment(const T *address)
Checks the alignment of the given address.
Definition: AlignmentCheck.h:68
Rebind mechanism to obtain a HybridMatrix with different data/element type.
Definition: HybridMatrix.h:240
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:233
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:314
HybridMatrix< ET, M, N, SO > Other
The type of the other HybridMatrix.
Definition: HybridMatrix.h:241
typename T::ConstIterator ConstIterator_
Alias declaration for nested ConstIterator type definitions.The ConstIterator_ alias declaration prov...
Definition: Aliases.h:103
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2806
Header file for the AreSIMDCombinable type trait.
constexpr bool usePadding
Configuration of the padding of dense vectors and matrices.This configuration switch enables/disables...
Definition: Optimizations.h:52
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
size_t n_
The current number of columns of the matrix.
Definition: HybridMatrix.h:486
Header file for the IntegralConstant class template.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
void clear()
Clearing the hybrid matrix.
Definition: HybridMatrix.h:1849
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:78
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
#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
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2654
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1303
Header file for the IsUpper type trait.
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:1945
#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
bool canAlias(const Other *alias) const noexcept
Returns whether the matrix can alias with the given address alias.
Definition: HybridMatrix.h:2360
Header file for the IsResizable type trait.
System settings for the inline keywords.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the TrueType type/value trait base class.
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:564
constexpr bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56