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 <cmath>
51 #include <blaze/math/Forward.h>
52 #include <blaze/math/Functions.h>
53 #include <blaze/math/Intrinsics.h>
54 #include <blaze/math/shims/Clear.h>
80 #include <blaze/system/Inline.h>
85 #include <blaze/util/Assert.h>
92 #include <blaze/util/DisableIf.h>
93 #include <blaze/util/EnableIf.h>
94 #include <blaze/util/Exception.h>
95 #include <blaze/util/Memory.h>
97 #include <blaze/util/mpl/SizeT.h>
99 #include <blaze/util/Template.h>
100 #include <blaze/util/Types.h>
104 #include <blaze/util/Unused.h>
106 
107 
108 namespace blaze {
109 
110 //=================================================================================================
111 //
112 // CLASS DEFINITION
113 //
114 //=================================================================================================
115 
116 //*************************************************************************************************
202 template< typename Type // Data type of the matrix
203  , size_t M // Number of rows
204  , size_t N // Number of columns
205  , bool SO = defaultStorageOrder > // Storage order
206 class HybridMatrix : public DenseMatrix< HybridMatrix<Type,M,N,SO>, SO >
207 {
208  private:
209  //**Type definitions****************************************************************************
211  //**********************************************************************************************
212 
213  //**********************************************************************************************
215  static const size_t NN = ( usePadding )?( NextMultiple< SizeT<N>, SizeT<IT::size> >::value ):( N );
216  //**********************************************************************************************
217 
218  public:
219  //**Type definitions****************************************************************************
221  typedef This ResultType;
224  typedef Type ElementType;
225  typedef typename IT::Type IntrinsicType;
226  typedef const Type& ReturnType;
227  typedef const This& CompositeType;
228 
229  typedef Type& Reference;
230  typedef const Type& ConstReference;
231  typedef Type* Pointer;
232  typedef const Type* ConstPointer;
233 
236  //**********************************************************************************************
237 
238  //**Rebind struct definition********************************************************************
241  template< typename ET > // Data type of the other matrix
242  struct Rebind {
244  };
245  //**********************************************************************************************
246 
247  //**Compilation flags***************************************************************************
249 
253  enum { vectorizable = IsVectorizable<Type>::value };
254 
256 
259  enum { smpAssignable = 0 };
260  //**********************************************************************************************
261 
262  //**Constructors********************************************************************************
265  explicit inline HybridMatrix();
266  explicit inline HybridMatrix( size_t m, size_t n );
267  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
268  template< typename Other > explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
269 
270  template< typename Other, size_t M2, size_t N2 >
271  explicit inline HybridMatrix( const Other (&array)[M2][N2] );
272 
273  inline HybridMatrix( const HybridMatrix& m );
274  template< typename MT, bool SO2 > inline HybridMatrix( const Matrix<MT,SO2>& m );
276  //**********************************************************************************************
277 
278  //**Destructor**********************************************************************************
279  // No explicitly declared destructor.
280  //**********************************************************************************************
281 
282  //**Data access functions***********************************************************************
285  inline Reference operator()( size_t i, size_t j );
286  inline ConstReference operator()( size_t i, size_t j ) const;
287  inline Reference at( size_t i, size_t j );
288  inline ConstReference at( size_t i, size_t j ) const;
289  inline Pointer data ();
290  inline ConstPointer data () const;
291  inline Pointer data ( size_t i );
292  inline ConstPointer data ( size_t i ) const;
293  inline Iterator begin ( size_t i );
294  inline ConstIterator begin ( size_t i ) const;
295  inline ConstIterator cbegin( size_t i ) const;
296  inline Iterator end ( size_t i );
297  inline ConstIterator end ( size_t i ) const;
298  inline ConstIterator cend ( size_t i ) const;
300  //**********************************************************************************************
301 
302  //**Assignment operators************************************************************************
305  template< typename Other, size_t M2, size_t N2 >
306  inline HybridMatrix& operator=( const Other (&array)[M2][N2] );
307 
308  inline HybridMatrix& operator= ( const Type& set );
309  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
310  template< typename MT, bool SO2 > inline HybridMatrix& operator= ( const Matrix<MT,SO2>& rhs );
311  template< typename MT, bool SO2 > inline HybridMatrix& operator+=( const Matrix<MT,SO2>& rhs );
312  template< typename MT, bool SO2 > inline HybridMatrix& operator-=( const Matrix<MT,SO2>& rhs );
313  template< typename MT, bool SO2 > inline HybridMatrix& operator*=( const Matrix<MT,SO2>& rhs );
314 
315  template< typename Other >
316  inline typename EnableIf< IsNumeric<Other>, HybridMatrix >::Type&
317  operator*=( Other rhs );
318 
319  template< typename Other >
320  inline typename EnableIf< IsNumeric<Other>, HybridMatrix >::Type&
321  operator/=( Other rhs );
323  //**********************************************************************************************
324 
325  //**Utility functions***************************************************************************
328  inline size_t rows() const;
329  inline size_t columns() const;
330  inline size_t spacing() const;
331  inline size_t capacity() const;
332  inline size_t capacity( size_t i ) const;
333  inline size_t nonZeros() const;
334  inline size_t nonZeros( size_t i ) const;
335  inline void reset();
336  inline void reset( size_t i );
337  inline void clear();
338  void resize ( size_t m, size_t n, bool preserve=true );
339  inline void extend ( size_t m, size_t n, bool preserve=true );
340  inline HybridMatrix& transpose();
341  inline HybridMatrix& ctranspose();
342  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
343  inline void swap( HybridMatrix& m ) /* throw() */;
345  //**********************************************************************************************
346 
347  //**Memory functions****************************************************************************
350  static inline void* operator new ( std::size_t size );
351  static inline void* operator new[]( std::size_t size );
352  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
353  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
354 
355  static inline void operator delete ( void* ptr );
356  static inline void operator delete[]( void* ptr );
357  static inline void operator delete ( void* ptr, const std::nothrow_t& );
358  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
360  //**********************************************************************************************
361 
362  private:
363  //**********************************************************************************************
365  template< typename MT >
367  struct VectorizedAssign {
368  enum { value = useOptimizedKernels &&
369  vectorizable && MT::vectorizable &&
370  IsSame<Type,typename MT::ElementType>::value &&
371  IsRowMajorMatrix<MT>::value };
372  };
374  //**********************************************************************************************
375 
376  //**********************************************************************************************
378  template< typename MT >
380  struct VectorizedAddAssign {
381  enum { value = useOptimizedKernels &&
382  vectorizable && MT::vectorizable &&
383  IsSame<Type,typename MT::ElementType>::value &&
384  IntrinsicTrait<Type>::addition &&
385  IsRowMajorMatrix<MT>::value &&
386  !IsDiagonal<MT>::value };
387  };
389  //**********************************************************************************************
390 
391  //**********************************************************************************************
393  template< typename MT >
395  struct VectorizedSubAssign {
396  enum { value = useOptimizedKernels &&
397  vectorizable && MT::vectorizable &&
398  IsSame<Type,typename MT::ElementType>::value &&
399  IntrinsicTrait<Type>::subtraction &&
400  IsRowMajorMatrix<MT>::value &&
401  !IsDiagonal<MT>::value };
402  };
404  //**********************************************************************************************
405 
406  public:
407  //**Expression template evaluation functions****************************************************
410  template< typename Other > inline bool canAlias ( const Other* alias ) const;
411  template< typename Other > inline bool isAliased( const Other* alias ) const;
412 
413  inline bool isAligned() const;
414 
415  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
416  BLAZE_ALWAYS_INLINE IntrinsicType loada( size_t i, size_t j ) const;
417  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
418 
419  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
420  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const IntrinsicType& value );
421  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
422  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
423 
424  template< typename MT, bool SO2 >
425  inline typename DisableIf< VectorizedAssign<MT> >::Type
426  assign( const DenseMatrix<MT,SO2>& rhs );
427 
428  template< typename MT, bool SO2 >
429  inline typename EnableIf< VectorizedAssign<MT> >::Type
430  assign( const DenseMatrix<MT,SO2>& rhs );
431 
432  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
433  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
434 
435  template< typename MT, bool SO2 >
436  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
437  addAssign( const DenseMatrix<MT,SO2>& rhs );
438 
439  template< typename MT, bool SO2 >
440  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
441  addAssign( const DenseMatrix<MT,SO2>& rhs );
442 
443  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
444  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
445 
446  template< typename MT, bool SO2 >
447  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
448  subAssign( const DenseMatrix<MT,SO2>& rhs );
449 
450  template< typename MT, bool SO2 >
451  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
452  subAssign( const DenseMatrix<MT,SO2>& rhs );
453 
454  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
455  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
457  //**********************************************************************************************
458 
459  private:
460  //**Member variables****************************************************************************
464 
473  size_t m_;
474  size_t n_;
475 
476  //**********************************************************************************************
477 
478  //**Compile time checks*************************************************************************
484  BLAZE_STATIC_ASSERT( !usePadding || NN % IT::size == 0UL );
485  BLAZE_STATIC_ASSERT( NN >= N );
487  //**********************************************************************************************
488 };
489 //*************************************************************************************************
490 
491 
492 
493 
494 //=================================================================================================
495 //
496 // CONSTRUCTORS
497 //
498 //=================================================================================================
499 
500 //*************************************************************************************************
505 template< typename Type // Data type of the matrix
506  , size_t M // Number of rows
507  , size_t N // Number of columns
508  , bool SO > // Storage order
510  : v_() // The statically allocated matrix elements
511  , m_( 0UL ) // The current number of rows of the matrix
512  , n_( 0UL ) // The current number of columns of the matrix
513 {
515 
516  if( IsNumeric<Type>::value ) {
517  for( size_t i=0UL; i<M*NN; ++i )
518  v_[i] = Type();
519  }
520 }
521 //*************************************************************************************************
522 
523 
524 //*************************************************************************************************
537 template< typename Type // Data type of the matrix
538  , size_t M // Number of rows
539  , size_t N // Number of columns
540  , bool SO > // Storage order
541 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n )
542  : v_() // The statically allocated matrix elements
543  , m_( m ) // The current number of rows of the matrix
544  , n_( n ) // The current number of columns of the matrix
545 {
547 
548  if( m > M ) {
549  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
550  }
551 
552  if( n > N ) {
553  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
554  }
555 
556  if( IsNumeric<Type>::value ) {
557  for( size_t i=0UL; i<M*NN; ++i )
558  v_[i] = Type();
559  }
560 }
561 //*************************************************************************************************
562 
563 
564 //*************************************************************************************************
578 template< typename Type // Data type of the matrix
579  , size_t M // Number of rows
580  , size_t N // Number of columns
581  , bool SO > // Storage order
582 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Type& init )
583  : v_() // The statically allocated matrix elements
584  , m_( m ) // The current number of rows of the matrix
585  , n_( n ) // The current number of columns of the matrix
586 {
588 
589  if( m > M ) {
590  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
591  }
592 
593  if( n > N ) {
594  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
595  }
596 
597  for( size_t i=0UL; i<m; ++i ) {
598  for( size_t j=0UL; j<n; ++j )
599  v_[i*NN+j] = init;
600 
601  if( IsNumeric<Type>::value ) {
602  for( size_t j=n; j<NN; ++j )
603  v_[i*NN+j] = Type();
604  }
605  }
606 
607  if( IsNumeric<Type>::value ) {
608  for( size_t i=m; i<M; ++i )
609  for( size_t j=0UL; j<NN; ++j )
610  v_[i*NN+j] = Type();
611  }
612 }
613 //*************************************************************************************************
614 
615 
616 //*************************************************************************************************
643 template< typename Type // Data type of the matrix
644  , size_t M // Number of rows
645  , size_t N // Number of columns
646  , bool SO > // Storage order
647 template< typename Other > // Data type of the initialization array
648 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Other* array )
649  : v_() // The statically allocated matrix elements
650  , m_( m ) // The current number of rows of the matrix
651  , n_( n ) // The current number of columns of the matrix
652 {
654 
655  if( m > M ) {
656  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
657  }
658 
659  if( n > N ) {
660  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
661  }
662 
663  for( size_t i=0UL; i<m; ++i ) {
664  for( size_t j=0UL; j<n; ++j )
665  v_[i*NN+j] = array[i*n+j];
666 
667  if( IsNumeric<Type>::value ) {
668  for( size_t j=n; j<NN; ++j )
669  v_[i*NN+j] = Type();
670  }
671  }
672 
673  if( IsNumeric<Type>::value ) {
674  for( size_t i=m; i<M; ++i )
675  for( size_t j=0UL; j<NN; ++j )
676  v_[i*NN+j] = Type();
677  }
678 }
679 //*************************************************************************************************
680 
681 
682 //*************************************************************************************************
703 template< typename Type // Data type of the matrix
704  , size_t M // Number of rows
705  , size_t N // Number of columns
706  , bool SO > // Storage order
707 template< typename Other // Data type of the initialization array
708  , size_t M2 // Number of rows of the initialization array
709  , size_t N2 > // Number of columns of the initialization array
710 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( const Other (&array)[M2][N2] )
711  : v_() // The statically allocated matrix elements
712  , m_( M2 ) // The current number of rows of the matrix
713  , n_( N2 ) // The current number of columns of the matrix
714 {
715  BLAZE_STATIC_ASSERT( M2 <= M );
716  BLAZE_STATIC_ASSERT( N2 <= N );
718 
719  for( size_t i=0UL; i<M2; ++i ) {
720  for( size_t j=0UL; j<N2; ++j )
721  v_[i*NN+j] = array[i][j];
722 
723  if( IsNumeric<Type>::value ) {
724  for( size_t j=N2; j<NN; ++j )
725  v_[i*NN+j] = Type();
726  }
727  }
728 
729  if( IsNumeric<Type>::value ) {
730  for( size_t i=M2; i<M; ++i )
731  for( size_t j=0UL; j<NN; ++j )
732  v_[i*NN+j] = Type();
733  }
734 }
735 //*************************************************************************************************
736 
737 
738 //*************************************************************************************************
746 template< typename Type // Data type of the matrix
747  , size_t M // Number of rows
748  , size_t N // Number of columns
749  , bool SO > // Storage order
751  : v_() // The statically allocated matrix elements
752  , m_( m.m_ ) // The current number of rows of the matrix
753  , n_( m.n_ ) // The current number of columns of the matrix
754 {
756 
757  for( size_t i=0UL; i<m_; ++i ) {
758  for( size_t j=0UL; j<n_; ++j )
759  v_[i*NN+j] = m.v_[i*NN+j];
760 
761  if( IsNumeric<Type>::value ) {
762  for( size_t j=n_; j<NN; ++j )
763  v_[i*NN+j] = Type();
764  }
765  }
766 
767  if( IsNumeric<Type>::value ) {
768  for( size_t i=m_; i<M; ++i )
769  for( size_t j=0UL; j<NN; ++j )
770  v_[i*NN+j] = Type();
771  }
772 }
773 //*************************************************************************************************
774 
775 
776 //*************************************************************************************************
782 template< typename Type // Data type of the matrix
783  , size_t M // Number of rows
784  , size_t N // Number of columns
785  , bool SO > // Storage order
786 template< typename MT // Type of the foreign matrix
787  , bool SO2 > // Storage order of the foreign matrix
789  : v_() // The statically allocated matrix elements
790  , m_( (~m).rows() ) // The current number of rows of the matrix
791  , n_( (~m).columns() ) // The current number of columns of the matrix
792 {
793  using blaze::assign;
794 
796 
797  if( (~m).rows() > M || (~m).columns() > N ) {
798  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
799  }
800 
801  for( size_t i=0UL; i<m_; ++i ) {
802  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : n_ );
803  j<( IsNumeric<Type>::value ? NN : n_ );
804  ++j ) {
805  v_[i*NN+j] = Type();
806  }
807  }
808 
809  if( IsNumeric<Type>::value ) {
810  for( size_t i=m_; i<M; ++i )
811  for( size_t j=0UL; j<NN; ++j )
812  v_[i*NN+j] = Type();
813  }
814 
815  assign( *this, ~m );
816 }
817 //*************************************************************************************************
818 
819 
820 
821 
822 //=================================================================================================
823 //
824 // DATA ACCESS FUNCTIONS
825 //
826 //=================================================================================================
827 
828 //*************************************************************************************************
838 template< typename Type // Data type of the matrix
839  , size_t M // Number of rows
840  , size_t N // Number of columns
841  , bool SO > // Storage order
844 {
845  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
846  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
847  return v_[i*NN+j];
848 }
849 //*************************************************************************************************
850 
851 
852 //*************************************************************************************************
862 template< typename Type // Data type of the matrix
863  , size_t M // Number of rows
864  , size_t N // Number of columns
865  , bool SO > // Storage order
867  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const
868 {
869  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
870  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
871  return v_[i*NN+j];
872 }
873 //*************************************************************************************************
874 
875 
876 //*************************************************************************************************
887 template< typename Type // Data type of the matrix
888  , size_t M // Number of rows
889  , size_t N // Number of columns
890  , bool SO > // Storage order
892  HybridMatrix<Type,M,N,SO>::at( size_t i, size_t j )
893 {
894  if( i >= m_ ) {
895  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
896  }
897  if( j >= n_ ) {
898  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
899  }
900  return (*this)(i,j);
901 }
902 //*************************************************************************************************
903 
904 
905 //*************************************************************************************************
916 template< typename Type // Data type of the matrix
917  , size_t M // Number of rows
918  , size_t N // Number of columns
919  , bool SO > // Storage order
921  HybridMatrix<Type,M,N,SO>::at( size_t i, size_t j ) const
922 {
923  if( i >= m_ ) {
924  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
925  }
926  if( j >= n_ ) {
927  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
928  }
929  return (*this)(i,j);
930 }
931 //*************************************************************************************************
932 
933 
934 //*************************************************************************************************
946 template< typename Type // Data type of the matrix
947  , size_t M // Number of rows
948  , size_t N // Number of columns
949  , bool SO > // Storage order
952 {
953  return v_;
954 }
955 //*************************************************************************************************
956 
957 
958 //*************************************************************************************************
970 template< typename Type // Data type of the matrix
971  , size_t M // Number of rows
972  , size_t N // Number of columns
973  , bool SO > // Storage order
976 {
977  return v_;
978 }
979 //*************************************************************************************************
980 
981 
982 //*************************************************************************************************
990 template< typename Type // Data type of the matrix
991  , size_t M // Number of rows
992  , size_t N // Number of columns
993  , bool SO > // Storage order
996 {
997  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
998  return v_ + i*NN;
999 }
1000 //*************************************************************************************************
1001 
1002 
1003 //*************************************************************************************************
1011 template< typename Type // Data type of the matrix
1012  , size_t M // Number of rows
1013  , size_t N // Number of columns
1014  , bool SO > // Storage order
1017 {
1018  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1019  return v_ + i*NN;
1020 }
1021 //*************************************************************************************************
1022 
1023 
1024 //*************************************************************************************************
1035 template< typename Type // Data type of the matrix
1036  , size_t M // Number of rows
1037  , size_t N // Number of columns
1038  , bool SO > // Storage order
1041 {
1042  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1043  return Iterator( v_ + i*NN );
1044 }
1045 //*************************************************************************************************
1046 
1047 
1048 //*************************************************************************************************
1059 template< typename Type // Data type of the matrix
1060  , size_t M // Number of rows
1061  , size_t N // Number of columns
1062  , bool SO > // Storage order
1065 {
1066  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1067  return ConstIterator( v_ + i*NN );
1068 }
1069 //*************************************************************************************************
1070 
1071 
1072 //*************************************************************************************************
1083 template< typename Type // Data type of the matrix
1084  , size_t M // Number of rows
1085  , size_t N // Number of columns
1086  , bool SO > // Storage order
1089 {
1090  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1091  return ConstIterator( v_ + i*NN );
1092 }
1093 //*************************************************************************************************
1094 
1095 
1096 //*************************************************************************************************
1107 template< typename Type // Data type of the matrix
1108  , size_t M // Number of rows
1109  , size_t N // Number of columns
1110  , bool SO > // Storage order
1113 {
1114  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1115  return Iterator( v_ + i*NN + N );
1116 }
1117 //*************************************************************************************************
1118 
1119 
1120 //*************************************************************************************************
1131 template< typename Type // Data type of the matrix
1132  , size_t M // Number of rows
1133  , size_t N // Number of columns
1134  , bool SO > // Storage order
1137 {
1138  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1139  return ConstIterator( v_ + i*NN + N );
1140 }
1141 //*************************************************************************************************
1142 
1143 
1144 //*************************************************************************************************
1155 template< typename Type // Data type of the matrix
1156  , size_t M // Number of rows
1157  , size_t N // Number of columns
1158  , bool SO > // Storage order
1161 {
1162  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1163  return ConstIterator( v_ + i*NN + N );
1164 }
1165 //*************************************************************************************************
1166 
1167 
1168 
1169 
1170 //=================================================================================================
1171 //
1172 // ASSIGNMENT OPERATORS
1173 //
1174 //=================================================================================================
1175 
1176 //*************************************************************************************************
1197 template< typename Type // Data type of the matrix
1198  , size_t M // Number of rows
1199  , size_t N // Number of columns
1200  , bool SO > // Storage order
1201 template< typename Other // Data type of the initialization array
1202  , size_t M2 // Number of rows of the initialization array
1203  , size_t N2 > // Number of columns of the initialization array
1205 {
1206  BLAZE_STATIC_ASSERT( M2 <= M );
1207  BLAZE_STATIC_ASSERT( N2 <= N );
1208 
1209  resize( M2, N2 );
1210 
1211  for( size_t i=0UL; i<M2; ++i )
1212  for( size_t j=0UL; j<N2; ++j )
1213  v_[i*NN+j] = array[i][j];
1214 
1215  return *this;
1216 }
1217 //*************************************************************************************************
1218 
1219 
1220 //*************************************************************************************************
1226 template< typename Type // Data type of the matrix
1227  , size_t M // Number of rows
1228  , size_t N // Number of columns
1229  , bool SO > // Storage order
1231 {
1232  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1233  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1234 
1235  for( size_t i=0UL; i<m_; ++i )
1236  for( size_t j=0UL; j<n_; ++j )
1237  v_[i*NN+j] = set;
1238 
1239  return *this;
1240 }
1241 //*************************************************************************************************
1242 
1243 
1244 //*************************************************************************************************
1252 template< typename Type // Data type of the matrix
1253  , size_t M // Number of rows
1254  , size_t N // Number of columns
1255  , bool SO > // Storage order
1257 {
1258  using blaze::assign;
1259 
1260  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1261  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1262 
1263  resize( rhs.rows(), rhs.columns() );
1264  assign( *this, ~rhs );
1265 
1266  return *this;
1267 }
1268 //*************************************************************************************************
1269 
1270 
1271 //*************************************************************************************************
1282 template< typename Type // Data type of the matrix
1283  , size_t M // Number of rows
1284  , size_t N // Number of columns
1285  , bool SO > // Storage order
1286 template< typename MT // Type of the right-hand side matrix
1287  , bool SO2 > // Storage order of the right-hand side matrix
1289 {
1290  using blaze::assign;
1291 
1292  typedef typename TransExprTrait<This>::Type TT;
1293  typedef typename CTransExprTrait<This>::Type CT;
1294 
1295  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
1296  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
1297  }
1298 
1299  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
1300  transpose();
1301  }
1302  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
1303  ctranspose();
1304  }
1305  else if( (~rhs).canAlias( this ) ) {
1306  HybridMatrix tmp( ~rhs );
1307  resize( tmp.rows(), tmp.columns() );
1308  assign( *this, tmp );
1309  }
1310  else {
1311  resize( (~rhs).rows(), (~rhs).columns() );
1313  reset();
1314  assign( *this, ~rhs );
1315  }
1316 
1317  return *this;
1318 }
1319 //*************************************************************************************************
1320 
1321 
1322 //*************************************************************************************************
1332 template< typename Type // Data type of the matrix
1333  , size_t M // Number of rows
1334  , size_t N // Number of columns
1335  , bool SO > // Storage order
1336 template< typename MT // Type of the right-hand side matrix
1337  , bool SO2 > // Storage order of the right-hand side matrix
1339 {
1340  using blaze::addAssign;
1341 
1342  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1343  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1344  }
1345 
1346  if( (~rhs).canAlias( this ) ) {
1347  const typename MT::ResultType tmp( ~rhs );
1348  addAssign( *this, tmp );
1349  }
1350  else {
1351  addAssign( *this, ~rhs );
1352  }
1353 
1354  return *this;
1355 }
1356 //*************************************************************************************************
1357 
1358 
1359 //*************************************************************************************************
1369 template< typename Type // Data type of the matrix
1370  , size_t M // Number of rows
1371  , size_t N // Number of columns
1372  , bool SO > // Storage order
1373 template< typename MT // Type of the right-hand side matrix
1374  , bool SO2 > // Storage order of the right-hand side matrix
1376 {
1377  using blaze::subAssign;
1378 
1379  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
1380  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1381  }
1382 
1383  if( (~rhs).canAlias( this ) ) {
1384  const typename MT::ResultType tmp( ~rhs );
1385  subAssign( *this, tmp );
1386  }
1387  else {
1388  subAssign( *this, ~rhs );
1389  }
1390 
1391  return *this;
1392 }
1393 //*************************************************************************************************
1394 
1395 
1396 //*************************************************************************************************
1406 template< typename Type // Data type of the matrix
1407  , size_t M // Number of rows
1408  , size_t N // Number of columns
1409  , bool SO > // Storage order
1410 template< typename MT // Type of the right-hand side matrix
1411  , bool SO2 > // Storage order of the right-hand side matrix
1413 {
1414  if( n_ != (~rhs).rows() || (~rhs).columns() > N ) {
1415  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1416  }
1417 
1418  const HybridMatrix tmp( *this * (~rhs) );
1419  return this->operator=( tmp );
1420 }
1421 //*************************************************************************************************
1422 
1423 
1424 //*************************************************************************************************
1431 template< typename Type // Data type of the matrix
1432  , size_t M // Number of rows
1433  , size_t N // Number of columns
1434  , bool SO > // Storage order
1435 template< typename Other > // Data type of the right-hand side scalar
1436 inline typename EnableIf< IsNumeric<Other>, HybridMatrix<Type,M,N,SO> >::Type&
1438 {
1439  using blaze::assign;
1440 
1441  assign( *this, (*this) * rhs );
1442  return *this;
1443 }
1444 //*************************************************************************************************
1445 
1446 
1447 //*************************************************************************************************
1456 template< typename Type // Data type of the matrix
1457  , size_t M // Number of rows
1458  , size_t N // Number of columns
1459  , bool SO > // Storage order
1460 template< typename Other > // Data type of the right-hand side scalar
1461 inline typename EnableIf< IsNumeric<Other>, HybridMatrix<Type,M,N,SO> >::Type&
1463 {
1464  using blaze::assign;
1465 
1466  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1467 
1468  assign( *this, (*this) / rhs );
1469  return *this;
1470 }
1471 //*************************************************************************************************
1472 
1473 
1474 
1475 
1476 //=================================================================================================
1477 //
1478 // UTILITY FUNCTIONS
1479 //
1480 //=================================================================================================
1481 
1482 //*************************************************************************************************
1487 template< typename Type // Data type of the matrix
1488  , size_t M // Number of rows
1489  , size_t N // Number of columns
1490  , bool SO > // Storage order
1491 inline size_t HybridMatrix<Type,M,N,SO>::rows() const
1492 {
1493  return m_;
1494 }
1495 //*************************************************************************************************
1496 
1497 
1498 //*************************************************************************************************
1503 template< typename Type // Data type of the matrix
1504  , size_t M // Number of rows
1505  , size_t N // Number of columns
1506  , bool SO > // Storage order
1508 {
1509  return n_;
1510 }
1511 //*************************************************************************************************
1512 
1513 
1514 //*************************************************************************************************
1522 template< typename Type // Data type of the matrix
1523  , size_t M // Number of rows
1524  , size_t N // Number of columns
1525  , bool SO > // Storage order
1527 {
1528  return NN;
1529 }
1530 //*************************************************************************************************
1531 
1532 
1533 //*************************************************************************************************
1538 template< typename Type // Data type of the matrix
1539  , size_t M // Number of rows
1540  , size_t N // Number of columns
1541  , bool SO > // Storage order
1543 {
1544  return M*NN;
1545 }
1546 //*************************************************************************************************
1547 
1548 
1549 //*************************************************************************************************
1560 template< typename Type // Data type of the matrix
1561  , size_t M // Number of rows
1562  , size_t N // Number of columns
1563  , bool SO > // Storage order
1564 inline size_t HybridMatrix<Type,M,N,SO>::capacity( size_t i ) const
1565 {
1566  UNUSED_PARAMETER( i );
1567 
1568  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1569 
1570  return NN;
1571 }
1572 //*************************************************************************************************
1573 
1574 
1575 //*************************************************************************************************
1580 template< typename Type // Data type of the matrix
1581  , size_t M // Number of rows
1582  , size_t N // Number of columns
1583  , bool SO > // Storage order
1585 {
1586  size_t nonzeros( 0UL );
1587 
1588  for( size_t i=0UL; i<m_; ++i )
1589  for( size_t j=0UL; j<n_; ++j )
1590  if( !isDefault( v_[i*NN+j] ) )
1591  ++nonzeros;
1592 
1593  return nonzeros;
1594 }
1595 //*************************************************************************************************
1596 
1597 
1598 //*************************************************************************************************
1609 template< typename Type // Data type of the matrix
1610  , size_t M // Number of rows
1611  , size_t N // Number of columns
1612  , bool SO > // Storage order
1613 inline size_t HybridMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1614 {
1615  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1616 
1617  const size_t jend( i*NN + n_ );
1618  size_t nonzeros( 0UL );
1619 
1620  for( size_t j=i*NN; j<jend; ++j )
1621  if( !isDefault( v_[j] ) )
1622  ++nonzeros;
1623 
1624  return nonzeros;
1625 }
1626 //*************************************************************************************************
1627 
1628 
1629 //*************************************************************************************************
1634 template< typename Type // Data type of the matrix
1635  , size_t M // Number of rows
1636  , size_t N // Number of columns
1637  , bool SO > // Storage order
1639 {
1640  using blaze::clear;
1641 
1642  for( size_t i=0UL; i<m_; ++i )
1643  for( size_t j=0UL; j<n_; ++j )
1644  clear( v_[i*NN+j] );
1645 }
1646 //*************************************************************************************************
1647 
1648 
1649 //*************************************************************************************************
1660 template< typename Type // Data type of the matrix
1661  , size_t M // Number of rows
1662  , size_t N // Number of columns
1663  , bool SO > // Storage order
1664 inline void HybridMatrix<Type,M,N,SO>::reset( size_t i )
1665 {
1666  using blaze::clear;
1667 
1668  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1669  for( size_t j=0UL; j<n_; ++j )
1670  clear( v_[i*NN+j] );
1671 }
1672 //*************************************************************************************************
1673 
1674 
1675 //*************************************************************************************************
1682 template< typename Type // Data type of the matrix
1683  , size_t M // Number of rows
1684  , size_t N // Number of columns
1685  , bool SO > // Storage order
1687 {
1688  resize( 0UL, 0UL );
1689 }
1690 //*************************************************************************************************
1691 
1692 
1693 //*************************************************************************************************
1729 template< typename Type // Data type of the matrix
1730  , size_t M // Number of rows
1731  , size_t N // Number of columns
1732  , bool SO > // Storage order
1733 void HybridMatrix<Type,M,N,SO>::resize( size_t m, size_t n, bool preserve )
1734 {
1735  UNUSED_PARAMETER( preserve );
1736 
1737  if( m > M ) {
1738  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
1739  }
1740 
1741  if( n > N ) {
1742  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
1743  }
1744 
1745  if( IsVectorizable<Type>::value && n < n_ ) {
1746  for( size_t i=0UL; i<m; ++i )
1747  for( size_t j=n; j<n_; ++j )
1748  v_[i*NN+j] = Type();
1749  }
1750 
1751  if( IsVectorizable<Type>::value && m < m_ ) {
1752  for( size_t i=m; i<m_; ++i )
1753  for( size_t j=0UL; j<n_; ++j )
1754  v_[i*NN+j] = Type();
1755  }
1756 
1757  m_ = m;
1758  n_ = n;
1759 }
1760 //*************************************************************************************************
1761 
1762 
1763 //*************************************************************************************************
1778 template< typename Type // Data type of the matrix
1779  , size_t M // Number of rows
1780  , size_t N // Number of columns
1781  , bool SO > // Storage order
1782 inline void HybridMatrix<Type,M,N,SO>::extend( size_t m, size_t n, bool preserve )
1783 {
1784  UNUSED_PARAMETER( preserve );
1785  resize( m_+m, n_+n );
1786 }
1787 //*************************************************************************************************
1788 
1789 
1790 //*************************************************************************************************
1801 template< typename Type // Data type of the matrix
1802  , size_t M // Number of rows
1803  , size_t N // Number of columns
1804  , bool SO > // Storage order
1806 {
1807  using std::swap;
1808 
1809  if( m_ > N || n_ > M ) {
1810  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1811  }
1812 
1813  const size_t maxsize( max( m_, n_ ) );
1814  for( size_t i=1UL; i<maxsize; ++i )
1815  for( size_t j=0UL; j<i; ++j )
1816  swap( v_[i*NN+j], v_[j*NN+i] );
1817 
1818  if( IsVectorizable<Type>::value && m_ < n_ ) {
1819  for( size_t i=0UL; i<m_; ++i ) {
1820  for( size_t j=m_; j<n_; ++j ) {
1821  v_[i*NN+j] = Type();
1822  }
1823  }
1824  }
1825 
1826  if( IsVectorizable<Type>::value && m_ > n_ ) {
1827  for( size_t i=n_; i<m_; ++i ) {
1828  for( size_t j=0UL; j<n_; ++j ) {
1829  v_[i*NN+j] = Type();
1830  }
1831  }
1832  }
1833 
1834  swap( m_, n_ );
1835 
1836  return *this;
1837 }
1838 //*************************************************************************************************
1839 
1840 
1841 //*************************************************************************************************
1852 template< typename Type // Data type of the matrix
1853  , size_t M // Number of rows
1854  , size_t N // Number of columns
1855  , bool SO > // Storage order
1857 {
1858  using std::swap;
1859 
1860  if( m_ > N || n_ > M ) {
1861  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
1862  }
1863 
1864  const size_t maxsize( max( m_, n_ ) );
1865  for( size_t i=0UL; i<maxsize; ++i ) {
1866  for( size_t j=0UL; j<i; ++j ) {
1867  cswap( v_[i*NN+j], v_[j*NN+i] );
1868  }
1869  conjugate( v_[i*NN+i] );
1870  }
1871 
1872  if( IsVectorizable<Type>::value && m_ < n_ ) {
1873  for( size_t i=0UL; i<m_; ++i ) {
1874  for( size_t j=m_; j<n_; ++j ) {
1875  v_[i*NN+j] = Type();
1876  }
1877  }
1878  }
1879 
1880  if( IsVectorizable<Type>::value && m_ > n_ ) {
1881  for( size_t i=n_; i<m_; ++i ) {
1882  for( size_t j=0UL; j<n_; ++j ) {
1883  v_[i*NN+j] = Type();
1884  }
1885  }
1886  }
1887 
1888  swap( m_, n_ );
1889 
1890  return *this;
1891 }
1892 //*************************************************************************************************
1893 
1894 
1895 //*************************************************************************************************
1901 template< typename Type // Data type of the matrix
1902  , size_t M // Number of rows
1903  , size_t N // Number of columns
1904  , bool SO > // Storage order
1905 template< typename Other > // Data type of the scalar value
1907 {
1908  for( size_t i=0UL; i<m_; ++i )
1909  for( size_t j=0UL; j<n_; ++j )
1910  v_[i*NN+j] *= scalar;
1911 
1912  return *this;
1913 }
1914 //*************************************************************************************************
1915 
1916 
1917 //*************************************************************************************************
1924 template< typename Type // Data type of the matrix
1925  , size_t M // Number of rows
1926  , size_t N // Number of columns
1927  , bool SO > // Storage order
1928 inline void HybridMatrix<Type,M,N,SO>::swap( HybridMatrix& m ) /* throw() */
1929 {
1930  using std::swap;
1931 
1932  const size_t maxrows( max( m_, m.m_ ) );
1933  const size_t maxcols( max( n_, m.n_ ) );
1934 
1935  for( size_t i=0UL; i<maxrows; ++i ) {
1936  for( size_t j=0UL; j<maxcols; ++j ) {
1937  swap( v_[i*NN+j], m(i,j) );
1938  }
1939  }
1940 
1941  swap( m_, m.m_ );
1942  swap( n_, m.n_ );
1943 }
1944 //*************************************************************************************************
1945 
1946 
1947 
1948 
1949 //=================================================================================================
1950 //
1951 // MEMORY FUNCTIONS
1952 //
1953 //=================================================================================================
1954 
1955 //*************************************************************************************************
1965 template< typename Type // Data type of the matrix
1966  , size_t M // Number of rows
1967  , size_t N // Number of columns
1968  , bool SO > // Storage order
1969 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size )
1970 {
1972 
1973  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
1974 
1975  return allocate<HybridMatrix>( 1UL );
1976 }
1977 //*************************************************************************************************
1978 
1979 
1980 //*************************************************************************************************
1990 template< typename Type // Data type of the matrix
1991  , size_t M // Number of rows
1992  , size_t N // Number of columns
1993  , bool SO > // Storage order
1994 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
1995 {
1996  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
1997  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
1998 
1999  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2000 }
2001 //*************************************************************************************************
2002 
2003 
2004 //*************************************************************************************************
2014 template< typename Type // Data type of the matrix
2015  , size_t M // Number of rows
2016  , size_t N // Number of columns
2017  , bool SO > // Storage order
2018 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
2019 {
2020  UNUSED_PARAMETER( size );
2021 
2022  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
2023 
2024  return allocate<HybridMatrix>( 1UL );
2025 }
2026 //*************************************************************************************************
2027 
2028 
2029 //*************************************************************************************************
2039 template< typename Type // Data type of the matrix
2040  , size_t M // Number of rows
2041  , size_t N // Number of columns
2042  , bool SO > // Storage order
2043 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
2044 {
2045  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
2046  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
2047 
2048  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
2049 }
2050 //*************************************************************************************************
2051 
2052 
2053 //*************************************************************************************************
2059 template< typename Type // Data type of the matrix
2060  , size_t M // Number of rows
2061  , size_t N // Number of columns
2062  , bool SO > // Storage order
2063 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr )
2064 {
2065  deallocate( static_cast<HybridMatrix*>( ptr ) );
2066 }
2067 //*************************************************************************************************
2068 
2069 
2070 //*************************************************************************************************
2076 template< typename Type // Data type of the matrix
2077  , size_t M // Number of rows
2078  , size_t N // Number of columns
2079  , bool SO > // Storage order
2080 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
2081 {
2082  deallocate( static_cast<HybridMatrix*>( ptr ) );
2083 }
2084 //*************************************************************************************************
2085 
2086 
2087 //*************************************************************************************************
2093 template< typename Type // Data type of the matrix
2094  , size_t M // Number of rows
2095  , size_t N // Number of columns
2096  , bool SO > // Storage order
2097 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
2098 {
2099  deallocate( static_cast<HybridMatrix*>( ptr ) );
2100 }
2101 //*************************************************************************************************
2102 
2103 
2104 //*************************************************************************************************
2110 template< typename Type // Data type of the matrix
2111  , size_t M // Number of rows
2112  , size_t N // Number of columns
2113  , bool SO > // Storage order
2114 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
2115 {
2116  deallocate( static_cast<HybridMatrix*>( ptr ) );
2117 }
2118 //*************************************************************************************************
2119 
2120 
2121 
2122 
2123 //=================================================================================================
2124 //
2125 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2126 //
2127 //=================================================================================================
2128 
2129 //*************************************************************************************************
2139 template< typename Type // Data type of the matrix
2140  , size_t M // Number of rows
2141  , size_t N // Number of columns
2142  , bool SO > // Storage order
2143 template< typename Other > // Data type of the foreign expression
2144 inline bool HybridMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const
2145 {
2146  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2147 }
2148 //*************************************************************************************************
2149 
2150 
2151 //*************************************************************************************************
2161 template< typename Type // Data type of the matrix
2162  , size_t M // Number of rows
2163  , size_t N // Number of columns
2164  , bool SO > // Storage order
2165 template< typename Other > // Data type of the foreign expression
2166 inline bool HybridMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const
2167 {
2168  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2169 }
2170 //*************************************************************************************************
2171 
2172 
2173 //*************************************************************************************************
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
2187 {
2188  return ( usePadding || columns() % IT::size == 0UL );
2189 }
2190 //*************************************************************************************************
2191 
2192 
2193 //*************************************************************************************************
2208 template< typename Type // Data type of the matrix
2209  , size_t M // Number of rows
2210  , size_t N // Number of columns
2211  , bool SO > // Storage order
2213  HybridMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const
2214 {
2215  if( usePadding )
2216  return loada( i, j );
2217  else
2218  return loadu( i, j );
2219 }
2220 //*************************************************************************************************
2221 
2222 
2223 //*************************************************************************************************
2238 template< typename Type // Data type of the matrix
2239  , size_t M // Number of rows
2240  , size_t N // Number of columns
2241  , bool SO > // Storage order
2243  HybridMatrix<Type,M,N,SO>::loada( size_t i, size_t j ) const
2244 {
2245  using blaze::loada;
2246 
2248 
2249  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2250  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2251  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN, "Invalid column access index" );
2252  BLAZE_INTERNAL_ASSERT( !usePadding || j % IT::size == 0UL, "Invalid column access index" );
2253  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2254 
2255  return loada( &v_[i*NN+j] );
2256 }
2257 //*************************************************************************************************
2258 
2259 
2260 //*************************************************************************************************
2275 template< typename Type // Data type of the matrix
2276  , size_t M // Number of rows
2277  , size_t N // Number of columns
2278  , bool SO > // Storage order
2280  HybridMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const
2281 {
2282  using blaze::loadu;
2283 
2285 
2286  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2287  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2288  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN, "Invalid column access index" );
2289 
2290  return loadu( &v_[i*NN+j] );
2291 }
2292 //*************************************************************************************************
2293 
2294 
2295 //*************************************************************************************************
2311 template< typename Type // Data type of the matrix
2312  , size_t M // Number of rows
2313  , size_t N // Number of columns
2314  , bool SO > // Storage order
2316  HybridMatrix<Type,M,N,SO>::store( size_t i, size_t j, const IntrinsicType& value )
2317 {
2318  if( usePadding )
2319  storea( i, j, value );
2320  else
2321  storeu( i, j, value );
2322 }
2323 //*************************************************************************************************
2324 
2325 
2326 //*************************************************************************************************
2342 template< typename Type // Data type of the matrix
2343  , size_t M // Number of rows
2344  , size_t N // Number of columns
2345  , bool SO > // Storage order
2347  HybridMatrix<Type,M,N,SO>::storea( size_t i, size_t j, const IntrinsicType& value )
2348 {
2349  using blaze::storea;
2350 
2352 
2353  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2354  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2355  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN, "Invalid column access index" );
2356  BLAZE_INTERNAL_ASSERT( !usePadding || j % IT::size == 0UL, "Invalid column access index" );
2357  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2358 
2359  storea( &v_[i*NN+j], value );
2360 }
2361 //*************************************************************************************************
2362 
2363 
2364 //*************************************************************************************************
2380 template< typename Type // Data type of the matrix
2381  , size_t M // Number of rows
2382  , size_t N // Number of columns
2383  , bool SO > // Storage order
2385  HybridMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const IntrinsicType& value )
2386 {
2387  using blaze::storeu;
2388 
2390 
2391  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2392  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2393  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN, "Invalid column access index" );
2394 
2395  storeu( &v_[i*NN+j], value );
2396 }
2397 //*************************************************************************************************
2398 
2399 
2400 //*************************************************************************************************
2416 template< typename Type // Data type of the matrix
2417  , size_t M // Number of rows
2418  , size_t N // Number of columns
2419  , bool SO > // Storage order
2421  HybridMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const IntrinsicType& value )
2422 {
2423  using blaze::stream;
2424 
2426 
2427  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2428  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2429  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN, "Invalid column access index" );
2430  BLAZE_INTERNAL_ASSERT( !usePadding || j % IT::size == 0UL, "Invalid column access index" );
2431  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i*NN+j] ), "Invalid alignment detected" );
2432 
2433  stream( &v_[i*NN+j], value );
2434 }
2435 //*************************************************************************************************
2436 
2437 
2438 //*************************************************************************************************
2449 template< typename Type // Data type of the matrix
2450  , size_t M // Number of rows
2451  , size_t N // Number of columns
2452  , bool SO > // Storage order
2453 template< typename MT // Type of the right-hand side dense matrix
2454  , bool SO2 > // Storage order of the right-hand side dense matrix
2455 inline typename DisableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2457 {
2458  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2459 
2460  for( size_t i=0UL; i<m_; ++i ) {
2461  for( size_t j=0UL; j<n_; ++j ) {
2462  v_[i*NN+j] = (~rhs)(i,j);
2463  }
2464  }
2465 }
2466 //*************************************************************************************************
2467 
2468 
2469 //*************************************************************************************************
2480 template< typename Type // Data type of the matrix
2481  , size_t M // Number of rows
2482  , size_t N // Number of columns
2483  , bool SO > // Storage order
2484 template< typename MT // Type of the right-hand side dense matrix
2485  , bool SO2 > // Storage order of the right-hand side dense matrix
2486 inline typename EnableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2488 {
2490 
2491  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2492 
2493  const bool remainder( !usePadding || !IsPadded<MT>::value );
2494 
2495  const size_t jpos( ( remainder )?( n_ & size_t(-IT::size) ):( n_ ) );
2496  BLAZE_INTERNAL_ASSERT( !remainder || ( n_ - ( n_ % (IT::size) ) ) == jpos, "Invalid end calculation" );
2497 
2498  for( size_t i=0UL; i<m_; ++i )
2499  {
2500  size_t j( 0UL );
2501 
2502  for( ; j<jpos; j+=IT::size ) {
2503  store( i, j, (~rhs).load(i,j) );
2504  }
2505  for( ; remainder && j<n_; ++j ) {
2506  v_[i*NN+j] = (~rhs)(i,j);
2507  }
2508  }
2509 }
2510 //*************************************************************************************************
2511 
2512 
2513 //*************************************************************************************************
2524 template< typename Type // Data type of the matrix
2525  , size_t M // Number of rows
2526  , size_t N // Number of columns
2527  , bool SO > // Storage order
2528 template< typename MT > // Type of the right-hand side sparse matrix
2530 {
2531  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2532 
2533  typedef typename MT::ConstIterator RhsConstIterator;
2534 
2535  for( size_t i=0UL; i<m_; ++i )
2536  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2537  v_[i*NN+element->index()] = element->value();
2538 }
2539 //*************************************************************************************************
2540 
2541 
2542 //*************************************************************************************************
2553 template< typename Type // Data type of the matrix
2554  , size_t M // Number of rows
2555  , size_t N // Number of columns
2556  , bool SO > // Storage order
2557 template< typename MT > // Type of the right-hand side sparse matrix
2559 {
2561 
2562  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2563 
2564  typedef typename MT::ConstIterator RhsConstIterator;
2565 
2566  for( size_t j=0UL; j<n_; ++j )
2567  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2568  v_[element->index()*NN+j] = element->value();
2569 }
2570 //*************************************************************************************************
2571 
2572 
2573 //*************************************************************************************************
2584 template< typename Type // Data type of the matrix
2585  , size_t M // Number of rows
2586  , size_t N // Number of columns
2587  , bool SO > // Storage order
2588 template< typename MT // Type of the right-hand side dense matrix
2589  , bool SO2 > // Storage order of the right-hand side dense matrix
2590 inline typename DisableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2592 {
2593  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2594 
2595  for( size_t i=0UL; i<m_; ++i )
2596  {
2597  if( IsDiagonal<MT>::value )
2598  {
2599  v_[i*NN+i] += (~rhs)(i,i);
2600  }
2601  else
2602  {
2603  const size_t jbegin( ( IsUpper<MT>::value )
2604  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2605  :( 0UL ) );
2606  const size_t jend ( ( IsLower<MT>::value )
2607  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2608  :( n_ ) );
2609  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2610 
2611  for( size_t j=jbegin; j<jend; ++j ) {
2612  v_[i*NN+j] += (~rhs)(i,j);
2613  }
2614  }
2615  }
2616 }
2617 //*************************************************************************************************
2618 
2619 
2620 //*************************************************************************************************
2631 template< typename Type // Data type of the matrix
2632  , size_t M // Number of rows
2633  , size_t N // Number of columns
2634  , bool SO > // Storage order
2635 template< typename MT // Type of the right-hand side dense matrix
2636  , bool SO2 > // Storage order of the right-hand side dense matrix
2637 inline typename EnableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2639 {
2642 
2643  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2644 
2645  const bool remainder( !usePadding || !IsPadded<MT>::value );
2646 
2647  for( size_t i=0UL; i<m_; ++i )
2648  {
2649  const size_t jbegin( ( IsUpper<MT>::value )
2650  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-IT::size) )
2651  :( 0UL ) );
2652  const size_t jend ( ( IsLower<MT>::value )
2653  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2654  :( n_ ) );
2655  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2656 
2657  const size_t jpos( ( remainder )?( jend & size_t(-IT::size) ):( jend ) );
2658  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (IT::size) ) ) == jpos, "Invalid end calculation" );
2659 
2660  size_t j( jbegin );
2661 
2662  for( ; j<jpos; j+=IT::size ) {
2663  store( i, j, load(i,j) + (~rhs).load(i,j) );
2664  }
2665  for( ; remainder && j<jend; ++j ) {
2666  v_[i*NN+j] += (~rhs)(i,j);
2667  }
2668  }
2669 }
2670 //*************************************************************************************************
2671 
2672 
2673 //*************************************************************************************************
2684 template< typename Type // Data type of the matrix
2685  , size_t M // Number of rows
2686  , size_t N // Number of columns
2687  , bool SO > // Storage order
2688 template< typename MT > // Type of the right-hand side sparse matrix
2690 {
2691  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2692 
2693  typedef typename MT::ConstIterator RhsConstIterator;
2694 
2695  for( size_t i=0UL; i<m_; ++i )
2696  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2697  v_[i*NN+element->index()] += element->value();
2698 }
2699 //*************************************************************************************************
2700 
2701 
2702 //*************************************************************************************************
2713 template< typename Type // Data type of the matrix
2714  , size_t M // Number of rows
2715  , size_t N // Number of columns
2716  , bool SO > // Storage order
2717 template< typename MT > // Type of the right-hand side sparse matrix
2719 {
2721 
2722  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2723 
2724  typedef typename MT::ConstIterator RhsConstIterator;
2725 
2726  for( size_t j=0UL; j<n_; ++j )
2727  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2728  v_[element->index()*NN+j] += element->value();
2729 }
2730 //*************************************************************************************************
2731 
2732 
2733 //*************************************************************************************************
2744 template< typename Type // Data type of the matrix
2745  , size_t M // Number of rows
2746  , size_t N // Number of columns
2747  , bool SO > // Storage order
2748 template< typename MT // Type of the right-hand side dense matrix
2749  , bool SO2 > // Storage order of the right-hand side dense matrix
2750 inline typename DisableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2752 {
2753  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2754 
2755  for( size_t i=0UL; i<m_; ++i )
2756  {
2757  if( IsDiagonal<MT>::value )
2758  {
2759  v_[i*NN+i] -= (~rhs)(i,i);
2760  }
2761  else
2762  {
2763  const size_t jbegin( ( IsUpper<MT>::value )
2764  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2765  :( 0UL ) );
2766  const size_t jend ( ( IsLower<MT>::value )
2767  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2768  :( n_ ) );
2769  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2770 
2771  for( size_t j=jbegin; j<jend; ++j ) {
2772  v_[i*NN+j] -= (~rhs)(i,j);
2773  }
2774  }
2775  }
2776 }
2777 //*************************************************************************************************
2778 
2779 
2780 //*************************************************************************************************
2791 template< typename Type // Data type of the matrix
2792  , size_t M // Number of rows
2793  , size_t N // Number of columns
2794  , bool SO > // Storage order
2795 template< typename MT // Type of the right-hand side dense matrix
2796  , bool SO2 > // Storage order of the right-hand side dense matrix
2797 inline typename EnableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2799 {
2802 
2803  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2804 
2805  const bool remainder( !usePadding || !IsPadded<MT>::value );
2806 
2807  for( size_t i=0UL; i<m_; ++i )
2808  {
2809  const size_t jbegin( ( IsUpper<MT>::value )
2810  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-IT::size) )
2811  :( 0UL ) );
2812  const size_t jend ( ( IsLower<MT>::value )
2813  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2814  :( n_ ) );
2815  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2816 
2817  const size_t jpos( ( remainder )?( jend & size_t(-IT::size) ):( jend ) );
2818  BLAZE_INTERNAL_ASSERT( !remainder || ( jend - ( jend % (IT::size) ) ) == jpos, "Invalid end calculation" );
2819 
2820  size_t j( jbegin );
2821 
2822  for( ; j<jpos; j+=IT::size ) {
2823  store( i, j, load(i,j) - (~rhs).load(i,j) );
2824  }
2825  for( ; remainder && j<jend; ++j ) {
2826  v_[i*NN+j] -= (~rhs)(i,j);
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 sparse matrix
2850 {
2851  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2852 
2853  typedef typename MT::ConstIterator RhsConstIterator;
2854 
2855  for( size_t i=0UL; i<m_; ++i )
2856  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2857  v_[i*NN+element->index()] -= element->value();
2858 }
2859 //*************************************************************************************************
2860 
2861 
2862 //*************************************************************************************************
2873 template< typename Type // Data type of the matrix
2874  , size_t M // Number of rows
2875  , size_t N // Number of columns
2876  , bool SO > // Storage order
2877 template< typename MT > // Type of the right-hand side sparse matrix
2879 {
2881 
2882  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2883 
2884  typedef typename MT::ConstIterator RhsConstIterator;
2885 
2886  for( size_t j=0UL; j<n_; ++j )
2887  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2888  v_[element->index()*NN+j] -= element->value();
2889 }
2890 //*************************************************************************************************
2891 
2892 
2893 
2894 
2895 
2896 
2897 
2898 
2899 //=================================================================================================
2900 //
2901 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2902 //
2903 //=================================================================================================
2904 
2905 //*************************************************************************************************
2913 template< typename Type // Data type of the matrix
2914  , size_t M // Number of rows
2915  , size_t N > // Number of columns
2916 class HybridMatrix<Type,M,N,true> : public DenseMatrix< HybridMatrix<Type,M,N,true>, true >
2917 {
2918  private:
2919  //**Type definitions****************************************************************************
2920  typedef IntrinsicTrait<Type> IT;
2921  //**********************************************************************************************
2922 
2923  //**********************************************************************************************
2925  static const size_t MM = ( usePadding )?( NextMultiple< SizeT<M>, SizeT<IT::size> >::value ):( M );
2926  //**********************************************************************************************
2927 
2928  public:
2929  //**Type definitions****************************************************************************
2931  typedef This ResultType;
2934  typedef Type ElementType;
2935  typedef typename IT::Type IntrinsicType;
2936  typedef const Type& ReturnType;
2937  typedef const This& CompositeType;
2938 
2939  typedef Type& Reference;
2940  typedef const Type& ConstReference;
2941  typedef Type* Pointer;
2942  typedef const Type* ConstPointer;
2943 
2946  //**********************************************************************************************
2947 
2948  //**Rebind struct definition********************************************************************
2951  template< typename ET > // Data type of the other matrix
2952  struct Rebind {
2954  };
2955  //**********************************************************************************************
2956 
2957  //**Compilation flags***************************************************************************
2959 
2963  enum { vectorizable = IsVectorizable<Type>::value };
2964 
2966 
2969  enum { smpAssignable = 0 };
2970  //**********************************************************************************************
2971 
2972  //**Constructors********************************************************************************
2975  explicit inline HybridMatrix();
2976  explicit inline HybridMatrix( size_t m, size_t n );
2977  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
2978  template< typename Other > explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
2979 
2980  template< typename Other, size_t M2, size_t N2 >
2981  explicit inline HybridMatrix( const Other (&array)[M2][N2] );
2982 
2983  inline HybridMatrix( const HybridMatrix& m );
2984  template< typename MT, bool SO > inline HybridMatrix( const Matrix<MT,SO>& m );
2986  //**********************************************************************************************
2987 
2988  //**Destructor**********************************************************************************
2989  // No explicitly declared destructor.
2990  //**********************************************************************************************
2991 
2992  //**Data access functions***********************************************************************
2995  inline Reference operator()( size_t i, size_t j );
2996  inline ConstReference operator()( size_t i, size_t j ) const;
2997  inline Reference at( size_t i, size_t j );
2998  inline ConstReference at( size_t i, size_t j ) const;
2999  inline Pointer data ();
3000  inline ConstPointer data () const;
3001  inline Pointer data ( size_t j );
3002  inline ConstPointer data ( size_t j ) const;
3003  inline Iterator begin ( size_t j );
3004  inline ConstIterator begin ( size_t j ) const;
3005  inline ConstIterator cbegin( size_t j ) const;
3006  inline Iterator end ( size_t j );
3007  inline ConstIterator end ( size_t j ) const;
3008  inline ConstIterator cend ( size_t j ) const;
3010  //**********************************************************************************************
3011 
3012  //**Assignment operators************************************************************************
3015  template< typename Other, size_t M2, size_t N2 >
3016  inline HybridMatrix& operator=( const Other (&array)[M2][N2] );
3017 
3018  inline HybridMatrix& operator= ( const Type& set );
3019  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
3020  template< typename MT, bool SO > inline HybridMatrix& operator= ( const Matrix<MT,SO>& rhs );
3021  template< typename MT, bool SO > inline HybridMatrix& operator+=( const Matrix<MT,SO>& rhs );
3022  template< typename MT, bool SO > inline HybridMatrix& operator-=( const Matrix<MT,SO>& rhs );
3023  template< typename MT, bool SO > inline HybridMatrix& operator*=( const Matrix<MT,SO>& rhs );
3024 
3025  template< typename Other >
3026  inline typename EnableIf< IsNumeric<Other>, HybridMatrix >::Type&
3027  operator*=( Other rhs );
3028 
3029  template< typename Other >
3030  inline typename EnableIf< IsNumeric<Other>, HybridMatrix >::Type&
3031  operator/=( Other rhs );
3033  //**********************************************************************************************
3034 
3035  //**Utility functions***************************************************************************
3038  inline size_t rows() const;
3039  inline size_t columns() const;
3040  inline size_t spacing() const;
3041  inline size_t capacity() const;
3042  inline size_t capacity( size_t j ) const;
3043  inline size_t nonZeros() const;
3044  inline size_t nonZeros( size_t j ) const;
3045  inline void reset();
3046  inline void reset( size_t i );
3047  inline void clear();
3048  void resize ( size_t m, size_t n, bool preserve=true );
3049  inline void extend ( size_t m, size_t n, bool preserve=true );
3050  inline HybridMatrix& transpose();
3051  inline HybridMatrix& ctranspose();
3052  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
3053  inline void swap( HybridMatrix& m ) /* throw() */;
3055  //**********************************************************************************************
3056 
3057  //**Memory functions****************************************************************************
3060  static inline void* operator new ( std::size_t size );
3061  static inline void* operator new[]( std::size_t size );
3062  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
3063  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
3064 
3065  static inline void operator delete ( void* ptr );
3066  static inline void operator delete[]( void* ptr );
3067  static inline void operator delete ( void* ptr, const std::nothrow_t& );
3068  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
3070  //**********************************************************************************************
3071 
3072  private:
3073  //**********************************************************************************************
3075  template< typename MT >
3076  struct VectorizedAssign {
3077  enum { value = useOptimizedKernels &&
3078  vectorizable && MT::vectorizable &&
3079  IsSame<Type,typename MT::ElementType>::value &&
3080  IsColumnMajorMatrix<MT>::value };
3081  };
3082  //**********************************************************************************************
3083 
3084  //**********************************************************************************************
3086  template< typename MT >
3087  struct VectorizedAddAssign {
3088  enum { value = useOptimizedKernels &&
3089  vectorizable && MT::vectorizable &&
3090  IsSame<Type,typename MT::ElementType>::value &&
3091  IntrinsicTrait<Type>::addition &&
3092  IsColumnMajorMatrix<MT>::value &&
3093  !IsDiagonal<MT>::value };
3094  };
3095  //**********************************************************************************************
3096 
3097  //**********************************************************************************************
3099  template< typename MT >
3100  struct VectorizedSubAssign {
3101  enum { value = useOptimizedKernels &&
3102  vectorizable && MT::vectorizable &&
3103  IsSame<Type,typename MT::ElementType>::value &&
3104  IntrinsicTrait<Type>::subtraction &&
3105  IsColumnMajorMatrix<MT>::value &&
3106  !IsDiagonal<MT>::value };
3107  };
3108  //**********************************************************************************************
3109 
3110  public:
3111  //**Expression template evaluation functions****************************************************
3114  template< typename Other > inline bool canAlias ( const Other* alias ) const;
3115  template< typename Other > inline bool isAliased( const Other* alias ) const;
3116 
3117  inline bool isAligned() const;
3118 
3119  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
3120  BLAZE_ALWAYS_INLINE IntrinsicType loada( size_t i, size_t j ) const;
3121  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
3122 
3123  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
3124  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const IntrinsicType& value );
3125  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
3126  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
3127 
3128  template< typename MT, bool SO >
3129  inline typename DisableIf< VectorizedAssign<MT> >::Type
3130  assign( const DenseMatrix<MT,SO>& rhs );
3131 
3132  template< typename MT, bool SO >
3133  inline typename EnableIf< VectorizedAssign<MT> >::Type
3134  assign( const DenseMatrix<MT,SO>& rhs );
3135 
3136  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
3137  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
3138 
3139  template< typename MT, bool SO >
3140  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
3141  addAssign( const DenseMatrix<MT,SO>& rhs );
3142 
3143  template< typename MT, bool SO >
3144  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
3145  addAssign( const DenseMatrix<MT,SO>& rhs );
3146 
3147  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
3148  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
3149 
3150  template< typename MT, bool SO >
3151  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
3152  subAssign( const DenseMatrix<MT,SO>& rhs );
3153 
3154  template< typename MT, bool SO >
3155  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
3156  subAssign( const DenseMatrix<MT,SO>& rhs );
3157 
3158  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
3159  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
3161  //**********************************************************************************************
3162 
3163  private:
3164  //**Member variables****************************************************************************
3167  AlignedArray<Type,MM*N> v_;
3168 
3170  size_t m_;
3171  size_t n_;
3172 
3173  //**********************************************************************************************
3174 
3175  //**Compile time checks*************************************************************************
3180  BLAZE_STATIC_ASSERT( !usePadding || MM % IT::size == 0UL );
3181  BLAZE_STATIC_ASSERT( MM >= M );
3182  //**********************************************************************************************
3183 };
3185 //*************************************************************************************************
3186 
3187 
3188 
3189 
3190 //=================================================================================================
3191 //
3192 // CONSTRUCTORS
3193 //
3194 //=================================================================================================
3195 
3196 //*************************************************************************************************
3202 template< typename Type // Data type of the matrix
3203  , size_t M // Number of rows
3204  , size_t N > // Number of columns
3206  : v_() // The statically allocated matrix elements
3207  , m_( 0UL ) // The current number of rows of the matrix
3208  , n_( 0UL ) // The current number of columns of the matrix
3209 {
3210  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3211 
3212  if( IsNumeric<Type>::value ) {
3213  for( size_t i=0UL; i<MM*N; ++i )
3214  v_[i] = Type();
3215  }
3216 }
3218 //*************************************************************************************************
3219 
3220 
3221 //*************************************************************************************************
3235 template< typename Type // Data type of the matrix
3236  , size_t M // Number of rows
3237  , size_t N > // Number of columns
3238 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n )
3239  : v_() // The statically allocated matrix elements
3240  , m_( m ) // The current number of rows of the matrix
3241  , n_( n ) // The current number of columns of the matrix
3242 {
3243  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3244 
3245  if( m > M ) {
3246  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3247  }
3248 
3249  if( n > N ) {
3250  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3251  }
3252 
3253  if( IsNumeric<Type>::value ) {
3254  for( size_t i=0UL; i<MM*N; ++i )
3255  v_[i] = Type();
3256  }
3257 }
3259 //*************************************************************************************************
3260 
3261 
3262 //*************************************************************************************************
3277 template< typename Type // Data type of the matrix
3278  , size_t M // Number of rows
3279  , size_t N > // Number of columns
3280 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Type& init )
3281  : v_() // The statically allocated matrix elements
3282  , m_( m ) // The current number of rows of the matrix
3283  , n_( n ) // The current number of columns of the matrix
3284 {
3285  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3286 
3287  if( m > M ) {
3288  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3289  }
3290 
3291  if( n > N ) {
3292  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3293  }
3294 
3295  for( size_t j=0UL; j<n; ++j ) {
3296  for( size_t i=0UL; i<m; ++i )
3297  v_[i+j*MM] = init;
3298 
3299  if( IsNumeric<Type>::value ) {
3300  for( size_t i=m; i<MM; ++i )
3301  v_[i+j*MM] = Type();
3302  }
3303  }
3304 
3305  if( IsNumeric<Type>::value ) {
3306  for( size_t j=n; j<N; ++j )
3307  for( size_t i=0UL; i<MM; ++i )
3308  v_[i+j*MM] = Type();
3309  }
3310 }
3312 //*************************************************************************************************
3313 
3314 
3315 //*************************************************************************************************
3343 template< typename Type // Data type of the matrix
3344  , size_t M // Number of rows
3345  , size_t N > // Number of columns
3346 template< typename Other > // Data type of the initialization array
3347 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Other* array )
3348  : v_() // The statically allocated matrix elements
3349  , m_( m ) // The current number of rows of the matrix
3350  , n_( n ) // The current number of columns of the matrix
3351 {
3352  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3353 
3354  if( m > M ) {
3355  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
3356  }
3357 
3358  if( n > N ) {
3359  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
3360  }
3361 
3362  for( size_t j=0UL; j<n; ++j ) {
3363  for( size_t i=0UL; i<m; ++i )
3364  v_[i+j*MM] = array[i+j*m];
3365 
3366  if( IsNumeric<Type>::value ) {
3367  for( size_t i=m; i<MM; ++i )
3368  v_[i+j*MM] = Type();
3369  }
3370  }
3371 
3372  if( IsNumeric<Type>::value ) {
3373  for( size_t j=n; j<N; ++j )
3374  for( size_t i=0UL; i<MM; ++i )
3375  v_[i+j*MM] = Type();
3376  }
3377 }
3379 //*************************************************************************************************
3380 
3381 
3382 //*************************************************************************************************
3404 template< typename Type // Data type of the matrix
3405  , size_t M // Number of rows
3406  , size_t N > // Number of columns
3407 template< typename Other // Data type of the initialization array
3408  , size_t M2 // Number of rows of the initialization array
3409  , size_t N2 > // Number of columns of the initialization array
3410 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const Other (&array)[M2][N2] )
3411  : v_() // The statically allocated matrix elements
3412  , m_( M2 ) // The current number of rows of the matrix
3413  , n_( N2 ) // The current number of columns of the matrix
3414 {
3415  BLAZE_STATIC_ASSERT( M2 <= M );
3416  BLAZE_STATIC_ASSERT( N2 <= N );
3417  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3418 
3419  for( size_t j=0UL; j<N2; ++j ) {
3420  for( size_t i=0UL; i<M2; ++i )
3421  v_[i+j*MM] = array[i][j];
3422 
3423  if( IsNumeric<Type>::value ) {
3424  for( size_t i=M2; i<MM; ++i )
3425  v_[i+j*MM] = Type();
3426  }
3427  }
3428 
3429  if( IsNumeric<Type>::value ) {
3430  for( size_t j=N2; j<N; ++j )
3431  for( size_t i=0UL; i<MM; ++i )
3432  v_[i+j*MM] = Type();
3433  }
3434 }
3436 //*************************************************************************************************
3437 
3438 
3439 //*************************************************************************************************
3448 template< typename Type // Data type of the matrix
3449  , size_t M // Number of rows
3450  , size_t N > // Number of columns
3451 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const HybridMatrix& m )
3452  : v_() // The statically allocated matrix elements
3453  , m_( m.m_ ) // The current number of rows of the matrix
3454  , n_( m.n_ ) // The current number of columns of the matrix
3455 {
3456  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3457 
3458  for( size_t j=0UL; j<n_; ++j ) {
3459  for( size_t i=0UL; i<m_; ++i )
3460  v_[i+j*MM] = m.v_[i+j*MM];
3461 
3462  if( IsNumeric<Type>::value ) {
3463  for( size_t i=m_; i<MM; ++i )
3464  v_[i+j*MM] = Type();
3465  }
3466  }
3467 
3468  if( IsNumeric<Type>::value ) {
3469  for( size_t j=n_; j<N; ++j )
3470  for( size_t i=0UL; i<MM; ++i )
3471  v_[i+j*MM] = Type();
3472  }
3473 }
3475 //*************************************************************************************************
3476 
3477 
3478 //*************************************************************************************************
3485 template< typename Type // Data type of the matrix
3486  , size_t M // Number of rows
3487  , size_t N > // Number of columns
3488 template< typename MT // Type of the foreign matrix
3489  , bool SO2 > // Storage order of the foreign matrix
3490 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const Matrix<MT,SO2>& m )
3491  : v_() // The statically allocated matrix elements
3492  , m_( (~m).rows() ) // The current number of rows of the matrix
3493  , n_( (~m).columns() ) // The current number of columns of the matrix
3494 {
3495  using blaze::assign;
3496 
3497  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3498 
3499  if( (~m).rows() > M || (~m).columns() > N ) {
3500  BLAZE_THROW_INVALID_ARGUMENT( "Invalid setup of hybrid matrix" );
3501  }
3502 
3503  for( size_t j=0UL; j<n_; ++j ) {
3504  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : m_ );
3505  i<( IsNumeric<Type>::value ? MM : m_ );
3506  ++i ) {
3507  v_[i+j*MM] = Type();
3508  }
3509  }
3510 
3511  if( IsNumeric<Type>::value ) {
3512  for( size_t j=n_; j<N; ++j )
3513  for( size_t i=0UL; i<MM; ++i )
3514  v_[i+j*MM] = Type();
3515  }
3516 
3517  assign( *this, ~m );
3518 }
3520 //*************************************************************************************************
3521 
3522 
3523 
3524 
3525 //=================================================================================================
3526 //
3527 // DATA ACCESS FUNCTIONS
3528 //
3529 //=================================================================================================
3530 
3531 //*************************************************************************************************
3542 template< typename Type // Data type of the matrix
3543  , size_t M // Number of rows
3544  , size_t N > // Number of columns
3546  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j )
3547 {
3548  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3549  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3550  return v_[i+j*MM];
3551 }
3553 //*************************************************************************************************
3554 
3555 
3556 //*************************************************************************************************
3567 template< typename Type // Data type of the matrix
3568  , size_t M // Number of rows
3569  , size_t N > // Number of columns
3571  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const
3572 {
3573  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3574  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3575  return v_[i+j*MM];
3576 }
3578 //*************************************************************************************************
3579 
3580 
3581 //*************************************************************************************************
3593 template< typename Type // Data type of the matrix
3594  , size_t M // Number of rows
3595  , size_t N > // Number of columns
3597  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j )
3598 {
3599  if( i >= m_ ) {
3600  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3601  }
3602  if( j >= n_ ) {
3603  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3604  }
3605  return (*this)(i,j);
3606 }
3608 //*************************************************************************************************
3609 
3610 
3611 //*************************************************************************************************
3623 template< typename Type // Data type of the matrix
3624  , size_t M // Number of rows
3625  , size_t N > // Number of columns
3627  HybridMatrix<Type,M,N,true>::at( size_t i, size_t j ) const
3628 {
3629  if( i >= m_ ) {
3630  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3631  }
3632  if( j >= n_ ) {
3633  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3634  }
3635  return (*this)(i,j);
3636 }
3638 //*************************************************************************************************
3639 
3640 
3641 //*************************************************************************************************
3653 template< typename Type // Data type of the matrix
3654  , size_t M // Number of rows
3655  , size_t N > // Number of columns
3656 inline typename HybridMatrix<Type,M,N,true>::Pointer
3658 {
3659  return v_;
3660 }
3662 //*************************************************************************************************
3663 
3664 
3665 //*************************************************************************************************
3677 template< typename Type // Data type of the matrix
3678  , size_t M // Number of rows
3679  , size_t N > // Number of columns
3680 inline typename HybridMatrix<Type,M,N,true>::ConstPointer
3682 {
3683  return v_;
3684 }
3686 //*************************************************************************************************
3687 
3688 
3689 //*************************************************************************************************
3698 template< typename Type // Data type of the matrix
3699  , size_t M // Number of rows
3700  , size_t N > // Number of columns
3701 inline typename HybridMatrix<Type,M,N,true>::Pointer
3703 {
3704  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3705  return v_ + j*MM;
3706 }
3708 //*************************************************************************************************
3709 
3710 
3711 //*************************************************************************************************
3720 template< typename Type // Data type of the matrix
3721  , size_t M // Number of rows
3722  , size_t N > // Number of columns
3723 inline typename HybridMatrix<Type,M,N,true>::ConstPointer
3724  HybridMatrix<Type,M,N,true>::data( size_t j ) const
3725 {
3726  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3727  return v_ + j*MM;
3728 }
3730 //*************************************************************************************************
3731 
3732 
3733 //*************************************************************************************************
3740 template< typename Type // Data type of the matrix
3741  , size_t M // Number of rows
3742  , size_t N > // Number of columns
3745 {
3746  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3747  return Iterator( v_ + j*MM );
3748 }
3750 //*************************************************************************************************
3751 
3752 
3753 //*************************************************************************************************
3760 template< typename Type // Data type of the matrix
3761  , size_t M // Number of rows
3762  , size_t N > // Number of columns
3764  HybridMatrix<Type,M,N,true>::begin( size_t j ) const
3765 {
3766  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3767  return ConstIterator( v_ + j*MM );
3768 }
3770 //*************************************************************************************************
3771 
3772 
3773 //*************************************************************************************************
3780 template< typename Type // Data type of the matrix
3781  , size_t M // Number of rows
3782  , size_t N > // Number of columns
3784  HybridMatrix<Type,M,N,true>::cbegin( size_t j ) const
3785 {
3786  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3787  return ConstIterator( v_ + j*MM );
3788 }
3790 //*************************************************************************************************
3791 
3792 
3793 //*************************************************************************************************
3800 template< typename Type // Data type of the matrix
3801  , size_t M // Number of rows
3802  , size_t N > // Number of columns
3805 {
3806  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3807  return Iterator( v_ + j*MM + M );
3808 }
3810 //*************************************************************************************************
3811 
3812 
3813 //*************************************************************************************************
3820 template< typename Type // Data type of the matrix
3821  , size_t M // Number of rows
3822  , size_t N > // Number of columns
3824  HybridMatrix<Type,M,N,true>::end( size_t j ) const
3825 {
3826  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3827  return ConstIterator( v_ + j*MM + M );
3828 }
3830 //*************************************************************************************************
3831 
3832 
3833 //*************************************************************************************************
3840 template< typename Type // Data type of the matrix
3841  , size_t M // Number of rows
3842  , size_t N > // Number of columns
3844  HybridMatrix<Type,M,N,true>::cend( size_t j ) const
3845 {
3846  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3847  return ConstIterator( v_ + j*MM + M );
3848 }
3850 //*************************************************************************************************
3851 
3852 
3853 
3854 
3855 //=================================================================================================
3856 //
3857 // ASSIGNMENT OPERATORS
3858 //
3859 //=================================================================================================
3860 
3861 //*************************************************************************************************
3883 template< typename Type // Data type of the matrix
3884  , size_t M // Number of rows
3885  , size_t N > // Number of columns
3886 template< typename Other // Data type of the initialization array
3887  , size_t M2 // Number of rows of the initialization array
3888  , size_t N2 > // Number of columns of the initialization array
3889 inline HybridMatrix<Type,M,N,true>&
3890  HybridMatrix<Type,M,N,true>::operator=( const Other (&array)[M2][N2] )
3891 {
3892  BLAZE_STATIC_ASSERT( M2 <= M );
3893  BLAZE_STATIC_ASSERT( N2 <= N );
3894 
3895  resize( M2, N2 );
3896 
3897  for( size_t j=0UL; j<N2; ++j )
3898  for( size_t i=0UL; i<M2; ++i )
3899  v_[i+j*MM] = array[i][j];
3900 
3901  return *this;
3902 }
3904 //*************************************************************************************************
3905 
3906 
3907 //*************************************************************************************************
3914 template< typename Type // Data type of the matrix
3915  , size_t M // Number of rows
3916  , size_t N > // Number of columns
3917 inline HybridMatrix<Type,M,N,true>&
3918  HybridMatrix<Type,M,N,true>::operator=( const Type& set )
3919 {
3920  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
3921  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
3922 
3923  for( size_t j=0UL; j<n_; ++j )
3924  for( size_t i=0UL; i<m_; ++i )
3925  v_[i+j*MM] = set;
3926 
3927  return *this;
3928 }
3930 //*************************************************************************************************
3931 
3932 
3933 //*************************************************************************************************
3942 template< typename Type // Data type of the matrix
3943  , size_t M // Number of rows
3944  , size_t N > // Number of columns
3945 inline HybridMatrix<Type,M,N,true>&
3946  HybridMatrix<Type,M,N,true>::operator=( const HybridMatrix& rhs )
3947 {
3948  using blaze::assign;
3949 
3950  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
3951  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
3952 
3953  resize( rhs.rows(), rhs.columns() );
3954  assign( *this, ~rhs );
3955 
3956  return *this;
3957 }
3959 //*************************************************************************************************
3960 
3961 
3962 //*************************************************************************************************
3974 template< typename Type // Data type of the matrix
3975  , size_t M // Number of rows
3976  , size_t N > // Number of columns
3977 template< typename MT // Type of the right-hand side matrix
3978  , bool SO > // Storage order of the right-hand side matrix
3979 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator=( const Matrix<MT,SO>& rhs )
3980 {
3981  using blaze::assign;
3982 
3983  typedef typename TransExprTrait<This>::Type TT;
3984  typedef typename CTransExprTrait<This>::Type CT;
3985 
3986  if( (~rhs).rows() > M || (~rhs).columns() > N ) {
3987  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to hybrid matrix" );
3988  }
3989 
3990  if( IsSame<MT,TT>::value && (~rhs).isAliased( this ) ) {
3991  transpose();
3992  }
3993  else if( IsSame<MT,CT>::value && (~rhs).isAliased( this ) ) {
3994  ctranspose();
3995  }
3996  else if( (~rhs).canAlias( this ) ) {
3997  HybridMatrix tmp( ~rhs );
3998  resize( tmp.rows(), tmp.columns() );
3999  assign( *this, tmp );
4000  }
4001  else {
4002  resize( (~rhs).rows(), (~rhs).columns() );
4003  if( IsSparseMatrix<MT>::value )
4004  reset();
4005  assign( *this, ~rhs );
4006  }
4007 
4008  return *this;
4009 }
4011 //*************************************************************************************************
4012 
4013 
4014 //*************************************************************************************************
4025 template< typename Type // Data type of the matrix
4026  , size_t M // Number of rows
4027  , size_t N > // Number of columns
4028 template< typename MT // Type of the right-hand side matrix
4029  , bool SO > // Storage order of the right-hand side matrix
4030 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator+=( const Matrix<MT,SO>& rhs )
4031 {
4032  using blaze::addAssign;
4033 
4034  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4035  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4036  }
4037 
4038  if( (~rhs).canAlias( this ) ) {
4039  const typename MT::ResultType tmp( ~rhs );
4040  addAssign( *this, tmp );
4041  }
4042  else {
4043  addAssign( *this, ~rhs );
4044  }
4045 
4046  return *this;
4047 }
4049 //*************************************************************************************************
4050 
4051 
4052 //*************************************************************************************************
4063 template< typename Type // Data type of the matrix
4064  , size_t M // Number of rows
4065  , size_t N > // Number of columns
4066 template< typename MT // Type of the right-hand side matrix
4067  , bool SO > // Storage order of the right-hand side matrix
4068 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator-=( const Matrix<MT,SO>& rhs )
4069 {
4070  using blaze::subAssign;
4071 
4072  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ ) {
4073  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4074  }
4075 
4076  if( (~rhs).canAlias( this ) ) {
4077  const typename MT::ResultType tmp( ~rhs );
4078  subAssign( *this, tmp );
4079  }
4080  else {
4081  subAssign( *this, ~rhs );
4082  }
4083 
4084  return *this;
4085 }
4087 //*************************************************************************************************
4088 
4089 
4090 //*************************************************************************************************
4101 template< typename Type // Data type of the matrix
4102  , size_t M // Number of rows
4103  , size_t N > // Number of columns
4104 template< typename MT // Type of the right-hand side matrix
4105  , bool SO > // Storage order of the right-hand side matrix
4106 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator*=( const Matrix<MT,SO>& rhs )
4107 {
4108  if( n_ != (~rhs).rows() || (~rhs).columns() > N ) {
4109  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4110  }
4111 
4112  const HybridMatrix tmp( *this * (~rhs) );
4113  return this->operator=( tmp );
4114 }
4116 //*************************************************************************************************
4117 
4118 
4119 //*************************************************************************************************
4127 template< typename Type // Data type of the matrix
4128  , size_t M // Number of rows
4129  , size_t N > // Number of columns
4130 template< typename Other > // Data type of the right-hand side scalar
4131 inline typename EnableIf< IsNumeric<Other>, HybridMatrix<Type,M,N,true> >::Type&
4132  HybridMatrix<Type,M,N,true>::operator*=( Other rhs )
4133 {
4134  using blaze::assign;
4135 
4136  assign( *this, (*this) * rhs );
4137  return *this;
4138 }
4140 //*************************************************************************************************
4141 
4142 
4143 //*************************************************************************************************
4153 template< typename Type // Data type of the matrix
4154  , size_t M // Number of rows
4155  , size_t N > // Number of columns
4156 template< typename Other > // Data type of the right-hand side scalar
4157 inline typename EnableIf< IsNumeric<Other>, HybridMatrix<Type,M,N,true> >::Type&
4158  HybridMatrix<Type,M,N,true>::operator/=( Other rhs )
4159 {
4160  using blaze::assign;
4161 
4162  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4163 
4164  assign( *this, (*this) / rhs );
4165  return *this;
4166 }
4168 //*************************************************************************************************
4169 
4170 
4171 
4172 
4173 //=================================================================================================
4174 //
4175 // UTILITY FUNCTIONS
4176 //
4177 //=================================================================================================
4178 
4179 //*************************************************************************************************
4185 template< typename Type // Data type of the matrix
4186  , size_t M // Number of rows
4187  , size_t N > // Number of columns
4188 inline size_t HybridMatrix<Type,M,N,true>::rows() const
4189 {
4190  return m_;
4191 }
4193 //*************************************************************************************************
4194 
4195 
4196 //*************************************************************************************************
4202 template< typename Type // Data type of the matrix
4203  , size_t M // Number of rows
4204  , size_t N > // Number of columns
4205 inline size_t HybridMatrix<Type,M,N,true>::columns() const
4206 {
4207  return n_;
4208 }
4210 //*************************************************************************************************
4211 
4212 
4213 //*************************************************************************************************
4222 template< typename Type // Data type of the matrix
4223  , size_t M // Number of rows
4224  , size_t N > // Number of columns
4225 inline size_t HybridMatrix<Type,M,N,true>::spacing() const
4226 {
4227  return MM;
4228 }
4230 //*************************************************************************************************
4231 
4232 
4233 //*************************************************************************************************
4239 template< typename Type // Data type of the matrix
4240  , size_t M // Number of rows
4241  , size_t N > // Number of columns
4242 inline size_t HybridMatrix<Type,M,N,true>::capacity() const
4243 {
4244  return MM*N;
4245 }
4247 //*************************************************************************************************
4248 
4249 
4250 //*************************************************************************************************
4257 template< typename Type // Data type of the matrix
4258  , size_t M // Number of rows
4259  , size_t N > // Number of columns
4260 inline size_t HybridMatrix<Type,M,N,true>::capacity( size_t j ) const
4261 {
4262  UNUSED_PARAMETER( j );
4263 
4264  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4265 
4266  return MM;
4267 }
4269 //*************************************************************************************************
4270 
4271 
4272 //*************************************************************************************************
4278 template< typename Type // Data type of the matrix
4279  , size_t M // Number of rows
4280  , size_t N > // Number of columns
4281 inline size_t HybridMatrix<Type,M,N,true>::nonZeros() const
4282 {
4283  size_t nonzeros( 0UL );
4284 
4285  for( size_t j=0UL; j<n_; ++j )
4286  for( size_t i=0UL; i<m_; ++i )
4287  if( !isDefault( v_[i+j*MM] ) )
4288  ++nonzeros;
4289 
4290  return nonzeros;
4291 }
4293 //*************************************************************************************************
4294 
4295 
4296 //*************************************************************************************************
4303 template< typename Type // Data type of the matrix
4304  , size_t M // Number of rows
4305  , size_t N > // Number of columns
4306 inline size_t HybridMatrix<Type,M,N,true>::nonZeros( size_t j ) const
4307 {
4308  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4309 
4310  const size_t iend( j*MM + m_ );
4311  size_t nonzeros( 0UL );
4312 
4313  for( size_t i=j*MM; i<iend; ++i )
4314  if( !isDefault( v_[i] ) )
4315  ++nonzeros;
4316 
4317  return nonzeros;
4318 }
4320 //*************************************************************************************************
4321 
4322 
4323 //*************************************************************************************************
4329 template< typename Type // Data type of the matrix
4330  , size_t M // Number of rows
4331  , size_t N > // Number of columns
4333 {
4334  using blaze::clear;
4335 
4336  for( size_t j=0UL; j<n_; ++j )
4337  for( size_t i=0UL; i<m_; ++i )
4338  clear( v_[i+j*MM] );
4339 }
4341 //*************************************************************************************************
4342 
4343 
4344 //*************************************************************************************************
4354 template< typename Type // Data type of the matrix
4355  , size_t M // Number of rows
4356  , size_t N > // Number of columns
4357 inline void HybridMatrix<Type,M,N,true>::reset( size_t j )
4358 {
4359  using blaze::clear;
4360 
4361  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4362  for( size_t i=0UL; i<m_; ++i )
4363  clear( v_[i+j*MM] );
4364 }
4366 //*************************************************************************************************
4367 
4368 
4369 //*************************************************************************************************
4377 template< typename Type // Data type of the matrix
4378  , size_t M // Number of rows
4379  , size_t N > // Number of columns
4381 {
4382  resize( 0UL, 0UL );
4383 }
4385 //*************************************************************************************************
4386 
4387 
4388 //*************************************************************************************************
4425 template< typename Type // Data type of the matrix
4426  , size_t M // Number of rows
4427  , size_t N > // Number of columns
4428 void HybridMatrix<Type,M,N,true>::resize( size_t m, size_t n, bool preserve )
4429 {
4430  UNUSED_PARAMETER( preserve );
4431 
4432  if( m > M ) {
4433  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of rows for hybrid matrix" );
4434  }
4435 
4436  if( n > N ) {
4437  BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of columns for hybrid matrix" );
4438  }
4439 
4440  if( IsVectorizable<Type>::value && m < m_ ) {
4441  for( size_t j=0UL; j<n; ++j )
4442  for( size_t i=m; i<m_; ++i )
4443  v_[i+j*MM] = Type();
4444  }
4445 
4446  if( IsVectorizable<Type>::value && n < n_ ) {
4447  for( size_t j=n; j<n_; ++j )
4448  for( size_t i=0UL; i<m_; ++i )
4449  v_[i+j*MM] = Type();
4450  }
4451 
4452  m_ = m;
4453  n_ = n;
4454 }
4456 //*************************************************************************************************
4457 
4458 
4459 //*************************************************************************************************
4475 template< typename Type // Data type of the matrix
4476  , size_t M // Number of rows
4477  , size_t N > // Number of columns
4478 inline void HybridMatrix<Type,M,N,true>::extend( size_t m, size_t n, bool preserve )
4479 {
4480  UNUSED_PARAMETER( preserve );
4481  resize( m_+m, n_+n );
4482 }
4484 //*************************************************************************************************
4485 
4486 
4487 //*************************************************************************************************
4499 template< typename Type // Data type of the matrix
4500  , size_t M // Number of rows
4501  , size_t N > // Number of columns
4502 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::transpose()
4503 {
4504  using std::swap;
4505 
4506  if( m_ > N || n_ > M ) {
4507  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4508  }
4509 
4510  const size_t maxsize( max( m_, n_ ) );
4511  for( size_t j=1UL; j<maxsize; ++j )
4512  for( size_t i=0UL; i<j; ++i )
4513  swap( v_[i+j*MM], v_[j+i*MM] );
4514 
4515  if( IsVectorizable<Type>::value && n_ < m_ ) {
4516  for( size_t j=0UL; j<n_; ++j ) {
4517  for( size_t i=n_; i<m_; ++i ) {
4518  v_[i+j*MM] = Type();
4519  }
4520  }
4521  }
4522 
4523  if( IsVectorizable<Type>::value && n_ > m_ ) {
4524  for( size_t j=m_; j<n_; ++j )
4525  for( size_t i=0UL; i<m_; ++i )
4526  v_[i+j*MM] = Type();
4527  }
4528 
4529  swap( m_, n_ );
4530 
4531  return *this;
4532 }
4534 //*************************************************************************************************
4535 
4536 
4537 //*************************************************************************************************
4549 template< typename Type // Data type of the matrix
4550  , size_t M // Number of rows
4551  , size_t N > // Number of columns
4552 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::ctranspose()
4553 {
4554  using std::swap;
4555 
4556  if( m_ > N || n_ > M ) {
4557  BLAZE_THROW_LOGIC_ERROR( "Impossible transpose operation" );
4558  }
4559 
4560  const size_t maxsize( max( m_, n_ ) );
4561  for( size_t j=0UL; j<maxsize; ++j ) {
4562  for( size_t i=0UL; i<j; ++i ) {
4563  cswap( v_[i+j*MM], v_[j+i*MM] );
4564  }
4565  conjugate( v_[j+j*MM] );
4566  }
4567 
4568  if( IsVectorizable<Type>::value && n_ < m_ ) {
4569  for( size_t j=0UL; j<n_; ++j ) {
4570  for( size_t i=n_; i<m_; ++i ) {
4571  v_[i+j*MM] = Type();
4572  }
4573  }
4574  }
4575 
4576  if( IsVectorizable<Type>::value && n_ > m_ ) {
4577  for( size_t j=m_; j<n_; ++j )
4578  for( size_t i=0UL; i<m_; ++i )
4579  v_[i+j*MM] = Type();
4580  }
4581 
4582  swap( m_, n_ );
4583 
4584  return *this;
4585 }
4587 //*************************************************************************************************
4588 
4589 
4590 //*************************************************************************************************
4597 template< typename Type // Data type of the matrix
4598  , size_t M // Number of rows
4599  , size_t N > // Number of columns
4600 template< typename Other > // Data type of the scalar value
4601 inline HybridMatrix<Type,M,N,true>&
4602  HybridMatrix<Type,M,N,true>::scale( const Other& scalar )
4603 {
4604  for( size_t j=0UL; j<n_; ++j )
4605  for( size_t i=0UL; i<m_; ++i )
4606  v_[i+j*MM] *= scalar;
4607 
4608  return *this;
4609 }
4611 //*************************************************************************************************
4612 
4613 
4614 //*************************************************************************************************
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 void HybridMatrix<Type,M,N,true>::swap( HybridMatrix& m ) /* throw() */
4626 {
4627  using std::swap;
4628 
4629  const size_t maxrows( max( m_, m.m_ ) );
4630  const size_t maxcols( max( n_, m.n_ ) );
4631 
4632  for( size_t j=0UL; j<maxcols; ++j ) {
4633  for( size_t i=0UL; i<maxrows; ++i ) {
4634  swap( v_[i+j*MM], m(i,j) );
4635  }
4636  }
4637 
4638  swap( m_, m.m_ );
4639  swap( n_, m.n_ );
4640 }
4642 //*************************************************************************************************
4643 
4644 
4645 
4646 
4647 //=================================================================================================
4648 //
4649 // MEMORY FUNCTIONS
4650 //
4651 //=================================================================================================
4652 
4653 //*************************************************************************************************
4664 template< typename Type // Data type of the matrix
4665  , size_t M // Number of rows
4666  , size_t N > // Number of columns
4667 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size )
4668 {
4669  UNUSED_PARAMETER( size );
4670 
4671  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
4672 
4673  return allocate<HybridMatrix>( 1UL );
4674 }
4676 //*************************************************************************************************
4677 
4678 
4679 //*************************************************************************************************
4690 template< typename Type // Data type of the matrix
4691  , size_t M // Number of rows
4692  , size_t N > // Number of columns
4693 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size )
4694 {
4695  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
4696  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
4697 
4698  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
4699 }
4701 //*************************************************************************************************
4702 
4703 
4704 //*************************************************************************************************
4715 template< typename Type // Data type of the matrix
4716  , size_t M // Number of rows
4717  , size_t N > // Number of columns
4718 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
4719 {
4720  UNUSED_PARAMETER( size );
4721 
4722  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
4723 
4724  return allocate<HybridMatrix>( 1UL );
4725 }
4727 //*************************************************************************************************
4728 
4729 
4730 //*************************************************************************************************
4741 template< typename Type // Data type of the matrix
4742  , size_t M // Number of rows
4743  , size_t N > // Number of columns
4744 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
4745 {
4746  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
4747  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
4748 
4749  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
4750 }
4752 //*************************************************************************************************
4753 
4754 
4755 //*************************************************************************************************
4762 template< typename Type // Data type of the matrix
4763  , size_t M // Number of rows
4764  , size_t N > // Number of columns
4765 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr )
4766 {
4767  deallocate( static_cast<HybridMatrix*>( ptr ) );
4768 }
4770 //*************************************************************************************************
4771 
4772 
4773 //*************************************************************************************************
4780 template< typename Type // Data type of the matrix
4781  , size_t M // Number of rows
4782  , size_t N > // Number of columns
4783 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr )
4784 {
4785  deallocate( static_cast<HybridMatrix*>( ptr ) );
4786 }
4788 //*************************************************************************************************
4789 
4790 
4791 //*************************************************************************************************
4798 template< typename Type // Data type of the matrix
4799  , size_t M // Number of rows
4800  , size_t N > // Number of columns
4801 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
4802 {
4803  deallocate( static_cast<HybridMatrix*>( ptr ) );
4804 }
4806 //*************************************************************************************************
4807 
4808 
4809 //*************************************************************************************************
4816 template< typename Type // Data type of the matrix
4817  , size_t M // Number of rows
4818  , size_t N > // Number of columns
4819 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
4820 {
4821  deallocate( static_cast<HybridMatrix*>( ptr ) );
4822 }
4824 //*************************************************************************************************
4825 
4826 
4827 
4828 
4829 //=================================================================================================
4830 //
4831 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4832 //
4833 //=================================================================================================
4834 
4835 //*************************************************************************************************
4846 template< typename Type // Data type of the matrix
4847  , size_t M // Number of rows
4848  , size_t N > // Number of columns
4849 template< typename Other > // Data type of the foreign expression
4850 inline bool HybridMatrix<Type,M,N,true>::canAlias( const Other* alias ) const
4851 {
4852  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4853 }
4855 //*************************************************************************************************
4856 
4857 
4858 //*************************************************************************************************
4869 template< typename Type // Data type of the matrix
4870  , size_t M // Number of rows
4871  , size_t N > // Number of columns
4872 template< typename Other > // Data type of the foreign expression
4873 inline bool HybridMatrix<Type,M,N,true>::isAliased( const Other* alias ) const
4874 {
4875  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4876 }
4878 //*************************************************************************************************
4879 
4880 
4881 //*************************************************************************************************
4891 template< typename Type // Data type of the matrix
4892  , size_t M // Number of rows
4893  , size_t N > // Number of columns
4894 inline bool HybridMatrix<Type,M,N,true>::isAligned() const
4895 {
4896  return ( usePadding || rows() % IT::size == 0UL );
4897 }
4899 //*************************************************************************************************
4900 
4901 
4902 //*************************************************************************************************
4917 template< typename Type // Data type of the matrix
4918  , size_t M // Number of rows
4919  , size_t N > // Number of columns
4920 BLAZE_ALWAYS_INLINE typename HybridMatrix<Type,M,N,true>::IntrinsicType
4921  HybridMatrix<Type,M,N,true>::load( size_t i, size_t j ) const
4922 {
4923  if( usePadding )
4924  return loada( i, j );
4925  else
4926  return loadu( i, j );
4927 }
4929 //*************************************************************************************************
4930 
4931 
4932 //*************************************************************************************************
4947 template< typename Type // Data type of the matrix
4948  , size_t M // Number of rows
4949  , size_t N > // Number of columns
4950 BLAZE_ALWAYS_INLINE typename HybridMatrix<Type,M,N,true>::IntrinsicType
4951  HybridMatrix<Type,M,N,true>::loada( size_t i, size_t j ) const
4952 {
4953  using blaze::loada;
4954 
4956 
4957  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4958  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM, "Invalid row access index" );
4959  BLAZE_INTERNAL_ASSERT( !usePadding || i % IT::size == 0UL, "Invalid row access index" );
4960  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4961  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
4962 
4963  return loada( &v_[i+j*MM] );
4964 }
4966 //*************************************************************************************************
4967 
4968 
4969 //*************************************************************************************************
4984 template< typename Type // Data type of the matrix
4985  , size_t M // Number of rows
4986  , size_t N > // Number of columns
4987 BLAZE_ALWAYS_INLINE typename HybridMatrix<Type,M,N,true>::IntrinsicType
4988  HybridMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const
4989 {
4990  using blaze::loadu;
4991 
4993 
4994  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4995  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM, "Invalid row access index" );
4996  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4997 
4998  return loadu( &v_[i+j*MM] );
4999 }
5001 //*************************************************************************************************
5002 
5003 
5004 //*************************************************************************************************
5020 template< typename Type // Data type of the matrix
5021  , size_t M // Number of rows
5022  , size_t N > // Number of columns
5024  HybridMatrix<Type,M,N,true>::store( size_t i, size_t j, const IntrinsicType& value )
5025 {
5026  if( usePadding )
5027  storea( i, j, value );
5028  else
5029  storeu( i, j, value );
5030 }
5032 //*************************************************************************************************
5033 
5034 
5035 //*************************************************************************************************
5051 template< typename Type // Data type of the matrix
5052  , size_t M // Number of rows
5053  , size_t N > // Number of columns
5055  HybridMatrix<Type,M,N,true>::storea( size_t i, size_t j, const IntrinsicType& value )
5056 {
5057  using blaze::storea;
5058 
5060 
5061  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5062  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM, "Invalid row access index" );
5063  BLAZE_INTERNAL_ASSERT( !usePadding || i % IT::size == 0UL, "Invalid row access index" );
5064  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5065  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5066 
5067  storea( &v_[i+j*MM], value );
5068 }
5070 //*************************************************************************************************
5071 
5072 
5073 //*************************************************************************************************
5089 template< typename Type // Data type of the matrix
5090  , size_t M // Number of rows
5091  , size_t N > // Number of columns
5093  HybridMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
5094 {
5095  using blaze::storeu;
5096 
5098 
5099  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5100  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM, "Invalid row access index" );
5101  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5102 
5103  storeu( &v_[i+j*MM], value );
5104 }
5106 //*************************************************************************************************
5107 
5108 
5109 //*************************************************************************************************
5125 template< typename Type // Data type of the matrix
5126  , size_t M // Number of rows
5127  , size_t N > // Number of columns
5129  HybridMatrix<Type,M,N,true>::stream( size_t i, size_t j, const IntrinsicType& value )
5130 {
5131  using blaze::stream;
5132 
5134 
5135  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
5136  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM, "Invalid row access index" );
5137  BLAZE_INTERNAL_ASSERT( !usePadding || i % IT::size == 0UL, "Invalid row access index" );
5138  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
5139  BLAZE_INTERNAL_ASSERT( checkAlignment( &v_[i+j*MM] ), "Invalid alignment detected" );
5140 
5141  stream( &v_[i+j*MM], value );
5142 }
5144 //*************************************************************************************************
5145 
5146 
5147 //*************************************************************************************************
5159 template< typename Type // Data type of the matrix
5160  , size_t M // Number of rows
5161  , size_t N > // Number of columns
5162 template< typename MT // Type of the right-hand side dense matrix
5163  , bool SO > // Storage order of the right-hand side dense matrix
5164 inline typename DisableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
5165  HybridMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5166 {
5167  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5168 
5169  for( size_t j=0UL; j<n_; ++j ) {
5170  for( size_t i=0UL; i<m_; ++i ) {
5171  v_[i+j*MM] = (~rhs)(i,j);
5172  }
5173  }
5174 }
5176 //*************************************************************************************************
5177 
5178 
5179 //*************************************************************************************************
5191 template< typename Type // Data type of the matrix
5192  , size_t M // Number of rows
5193  , size_t N > // Number of columns
5194 template< typename MT // Type of the right-hand side dense matrix
5195  , bool SO > // Storage order of the right-hand side dense matrix
5196 inline typename EnableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
5197  HybridMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
5198 {
5200 
5201  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5202 
5203  const bool remainder( !usePadding || !IsPadded<MT>::value );
5204 
5205  const size_t ipos( ( remainder )?( m_ & size_t(-IT::size) ):( m_ ) );
5206  BLAZE_INTERNAL_ASSERT( !remainder || ( m_ - ( m_ % (IT::size) ) ) == ipos, "Invalid end calculation" );
5207 
5208  for( size_t j=0UL; j<n_; ++j )
5209  {
5210  size_t i( 0UL );
5211 
5212  for( ; i<ipos; i+=IT::size ) {
5213  store( i, j, (~rhs).load(i,j) );
5214  }
5215  for( ; remainder && i<m_; ++i ) {
5216  v_[i+j*MM] = (~rhs)(i,j);
5217  }
5218  }
5219 }
5221 //*************************************************************************************************
5222 
5223 
5224 //*************************************************************************************************
5236 template< typename Type // Data type of the matrix
5237  , size_t M // Number of rows
5238  , size_t N > // Number of columns
5239 template< typename MT > // Type of the right-hand side sparse matrix
5240 inline void HybridMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,true>& rhs )
5241 {
5242  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5243 
5244  typedef typename MT::ConstIterator RhsConstIterator;
5245 
5246  for( size_t j=0UL; j<n_; ++j )
5247  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5248  v_[element->index()+j*MM] = element->value();
5249 }
5251 //*************************************************************************************************
5252 
5253 
5254 //*************************************************************************************************
5266 template< typename Type // Data type of the matrix
5267  , size_t M // Number of rows
5268  , size_t N > // Number of columns
5269 template< typename MT > // Type of the right-hand side sparse matrix
5270 inline void HybridMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,false>& rhs )
5271 {
5273 
5274  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5275 
5276  typedef typename MT::ConstIterator RhsConstIterator;
5277 
5278  for( size_t i=0UL; i<m_; ++i )
5279  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5280  v_[i+element->index()*MM] = element->value();
5281 }
5283 //*************************************************************************************************
5284 
5285 
5286 //*************************************************************************************************
5298 template< typename Type // Data type of the matrix
5299  , size_t M // Number of rows
5300  , size_t N > // Number of columns
5301 template< typename MT // Type of the right-hand side dense matrix
5302  , bool SO > // Storage order of the right-hand side dense matrix
5303 inline typename DisableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
5304  HybridMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5305 {
5306  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5307 
5308  for( size_t j=0UL; j<n_; ++j )
5309  {
5310  if( IsDiagonal<MT>::value )
5311  {
5312  v_[j+j*MM] += (~rhs)(j,j);
5313  }
5314  else
5315  {
5316  const size_t ibegin( ( IsLower<MT>::value )
5317  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5318  :( 0UL ) );
5319  const size_t iend ( ( IsUpper<MT>::value )
5320  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5321  :( m_ ) );
5322  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5323 
5324  for( size_t i=ibegin; i<iend; ++i ) {
5325  v_[i+j*MM] += (~rhs)(i,j);
5326  }
5327  }
5328  }
5329 }
5331 //*************************************************************************************************
5332 
5333 
5334 //*************************************************************************************************
5346 template< typename Type // Data type of the matrix
5347  , size_t M // Number of rows
5348  , size_t N > // Number of columns
5349 template< typename MT // Type of the right-hand side dense matrix
5350  , bool SO > // Storage order of the right-hand side dense matrix
5351 inline typename EnableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
5352  HybridMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
5353 {
5356 
5357  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5358 
5359  const bool remainder( !usePadding || !IsPadded<MT>::value );
5360 
5361  for( size_t j=0UL; j<n_; ++j )
5362  {
5363  const size_t ibegin( ( IsLower<MT>::value )
5364  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
5365  :( 0UL ) );
5366  const size_t iend ( ( IsUpper<MT>::value )
5367  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5368  :( m_ ) );
5369  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5370 
5371  const size_t ipos( ( remainder )?( iend & size_t(-IT::size) ):( iend ) );
5372  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (IT::size) ) ) == ipos, "Invalid end calculation" );
5373 
5374  size_t i( ibegin );
5375 
5376  for( ; i<ipos; i+=IT::size ) {
5377  store( i, j, load(i,j) + (~rhs).load(i,j) );
5378  }
5379  for( ; remainder && i<iend; ++i ) {
5380  v_[i+j*MM] += (~rhs)(i,j);
5381  }
5382  }
5383 }
5385 //*************************************************************************************************
5386 
5387 
5388 //*************************************************************************************************
5400 template< typename Type // Data type of the matrix
5401  , size_t M // Number of rows
5402  , size_t N > // Number of columns
5403 template< typename MT > // Type of the right-hand side sparse matrix
5404 inline void HybridMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,true>& rhs )
5405 {
5406  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5407 
5408  typedef typename MT::ConstIterator RhsConstIterator;
5409 
5410  for( size_t j=0UL; j<n_; ++j )
5411  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5412  v_[element->index()+j*MM] += element->value();
5413 }
5415 //*************************************************************************************************
5416 
5417 
5418 //*************************************************************************************************
5430 template< typename Type // Data type of the matrix
5431  , size_t M // Number of rows
5432  , size_t N > // Number of columns
5433 template< typename MT > // Type of the right-hand side sparse matrix
5434 inline void HybridMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,false>& rhs )
5435 {
5437 
5438  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5439 
5440  typedef typename MT::ConstIterator RhsConstIterator;
5441 
5442  for( size_t i=0UL; i<m_; ++i )
5443  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5444  v_[i+element->index()*MM] += element->value();
5445 }
5447 //*************************************************************************************************
5448 
5449 
5450 //*************************************************************************************************
5462 template< typename Type // Data type of the matrix
5463  , size_t M // Number of rows
5464  , size_t N > // Number of columns
5465 template< typename MT // Type of the right-hand side dense matrix
5466  , bool SO > // Storage order of the right-hand side dense matrix
5467 inline typename DisableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
5468  HybridMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5469 {
5470  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5471 
5472  for( size_t j=0UL; j<n_; ++j )
5473  {
5474  if( IsDiagonal<MT>::value )
5475  {
5476  v_[j+j*MM] -= (~rhs)(j,j);
5477  }
5478  else
5479  {
5480  const size_t ibegin( ( IsLower<MT>::value )
5481  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5482  :( 0UL ) );
5483  const size_t iend ( ( IsUpper<MT>::value )
5484  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5485  :( m_ ) );
5486  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5487 
5488  for( size_t i=ibegin; i<iend; ++i ) {
5489  v_[i+j*MM] -= (~rhs)(i,j);
5490  }
5491  }
5492  }
5493 }
5495 //*************************************************************************************************
5496 
5497 
5498 //*************************************************************************************************
5510 template< typename Type // Data type of the matrix
5511  , size_t M // Number of rows
5512  , size_t N > // Number of columns
5513 template< typename MT // Type of the right-hand side dense matrix
5514  , bool SO > // Storage order of the right-hand side dense matrix
5515 inline typename EnableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
5516  HybridMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5517 {
5520 
5521  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5522 
5523  const bool remainder( !usePadding || !IsPadded<MT>::value );
5524 
5525  for( size_t j=0UL; j<n_; ++j )
5526  {
5527  const size_t ibegin( ( IsLower<MT>::value )
5528  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
5529  :( 0UL ) );
5530  const size_t iend ( ( IsUpper<MT>::value )
5531  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5532  :( m_ ) );
5533  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5534 
5535  const size_t ipos( ( remainder )?( iend & size_t(-IT::size) ):( iend ) );
5536  BLAZE_INTERNAL_ASSERT( !remainder || ( iend - ( iend % (IT::size) ) ) == ipos, "Invalid end calculation" );
5537 
5538  size_t i( ibegin );
5539 
5540  for( ; i<ipos; i+=IT::size ) {
5541  store( i, j, load(i,j) - (~rhs).load(i,j) );
5542  }
5543  for( ; remainder && i<iend; ++i ) {
5544  v_[i+j*MM] -= (~rhs)(i,j);
5545  }
5546  }
5547 }
5549 //*************************************************************************************************
5550 
5551 
5552 //*************************************************************************************************
5564 template< typename Type // Data type of the matrix
5565  , size_t M // Number of rows
5566  , size_t N > // Number of columns
5567 template< typename MT > // Type of the right-hand side sparse matrix
5568 inline void HybridMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,true>& rhs )
5569 {
5570  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5571 
5572  typedef typename MT::ConstIterator RhsConstIterator;
5573 
5574  for( size_t j=0UL; j<n_; ++j )
5575  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5576  v_[element->index()+j*MM] -= element->value();
5577 }
5579 //*************************************************************************************************
5580 
5581 
5582 //*************************************************************************************************
5594 template< typename Type // Data type of the matrix
5595  , size_t M // Number of rows
5596  , size_t N > // Number of columns
5597 template< typename MT > // Type of the right-hand side sparse matrix
5598 inline void HybridMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,false>& rhs )
5599 {
5601 
5602  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5603 
5604  typedef typename MT::ConstIterator RhsConstIterator;
5605 
5606  for( size_t i=0UL; i<m_; ++i )
5607  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5608  v_[i+element->index()*MM] -= element->value();
5609 }
5611 //*************************************************************************************************
5612 
5613 
5614 
5615 
5616 
5617 
5618 
5619 
5620 //=================================================================================================
5621 //
5622 // UNDEFINED CLASS TEMPLATE SPECIALIZATIONS
5623 //
5624 //=================================================================================================
5625 
5626 //*************************************************************************************************
5634 template< typename Type // Data type of the matrix
5635  , size_t M // Number of rows
5636  , bool SO > // Storage order
5637 class HybridMatrix<Type,M,0UL,SO>;
5639 //*************************************************************************************************
5640 
5641 
5642 //*************************************************************************************************
5650 template< typename Type // Data type of the matrix
5651  , size_t N // Number of columns
5652  , bool SO > // Storage order
5653 class HybridMatrix<Type,0UL,N,SO>;
5655 //*************************************************************************************************
5656 
5657 
5658 //*************************************************************************************************
5666 template< typename Type // Data type of the matrix
5667  , bool SO > // Storage order
5668 class HybridMatrix<Type,0UL,0UL,SO>;
5670 //*************************************************************************************************
5671 
5672 
5673 
5674 
5675 
5676 
5677 
5678 
5679 //=================================================================================================
5680 //
5681 // STATICMATRIX OPERATORS
5682 //
5683 //=================================================================================================
5684 
5685 //*************************************************************************************************
5688 template< typename Type, size_t M, size_t N, bool SO >
5689 inline void reset( HybridMatrix<Type,M,N,SO>& m );
5690 
5691 template< typename Type, size_t M, size_t N, bool SO >
5692 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i );
5693 
5694 template< typename Type, size_t M, size_t N, bool SO >
5695 inline void clear( HybridMatrix<Type,M,N,SO>& m );
5696 
5697 template< typename Type, size_t M, size_t N, bool SO >
5698 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m );
5699 
5700 template< typename Type, size_t M, size_t N, bool SO >
5701 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m );
5702 
5703 template< typename Type, size_t M, size_t N, bool SO >
5704 inline void swap( HybridMatrix<Type,M,N,SO>& a, HybridMatrix<Type,M,N,SO>& b ) /* throw() */;
5705 
5706 template< typename Type, size_t M, size_t N, bool SO >
5707 inline void move( HybridMatrix<Type,M,N,SO>& dst, HybridMatrix<Type,M,N,SO>& src ) /* throw() */;
5709 //*************************************************************************************************
5710 
5711 
5712 //*************************************************************************************************
5719 template< typename Type // Data type of the matrix
5720  , size_t M // Number of rows
5721  , size_t N // Number of columns
5722  , bool SO > // Storage order
5724 {
5725  m.reset();
5726 }
5727 //*************************************************************************************************
5728 
5729 
5730 //*************************************************************************************************
5743 template< typename Type // Data type of the matrix
5744  , size_t M // Number of rows
5745  , size_t N // Number of columns
5746  , bool SO > // Storage order
5747 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i )
5748 {
5749  m.reset( i );
5750 }
5751 //*************************************************************************************************
5752 
5753 
5754 //*************************************************************************************************
5761 template< typename Type // Data type of the matrix
5762  , size_t M // Number of rows
5763  , size_t N // Number of columns
5764  , bool SO > // Storage order
5766 {
5767  m.clear();
5768 }
5769 //*************************************************************************************************
5770 
5771 
5772 //*************************************************************************************************
5790 template< typename Type // Data type of the matrix
5791  , size_t M // Number of rows
5792  , size_t N // Number of columns
5793  , bool SO > // Storage order
5794 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m )
5795 {
5796  return ( m.rows() == 0UL && m.columns() == 0UL );
5797 }
5798 //*************************************************************************************************
5799 
5800 
5801 //*************************************************************************************************
5819 template< typename Type // Data type of the matrix
5820  , size_t M // Number of rows
5821  , size_t N // Number of columns
5822  , bool SO > // Storage order
5823 inline bool isIntact( const HybridMatrix<Type,M,N,SO>& m )
5824 {
5825  return ( m.rows() <= M && m.columns() <= N );
5826 }
5827 //*************************************************************************************************
5828 
5829 
5830 //*************************************************************************************************
5839 template< typename Type // Data type of the matrix
5840  , size_t M // Number of rows
5841  , size_t N // Number of columns
5842  , bool SO > // Storage order
5843 inline void swap( HybridMatrix<Type,M,N,SO>& a, HybridMatrix<Type,M,N,SO>& b ) /* throw() */
5844 {
5845  a.swap( b );
5846 }
5847 //*************************************************************************************************
5848 
5849 
5850 //*************************************************************************************************
5859 template< typename Type // Data type of the matrix
5860  , size_t M // Number of rows
5861  , size_t N // Number of columns
5862  , bool SO > // Storage order
5863 inline void move( HybridMatrix<Type,M,N,SO>& dst, HybridMatrix<Type,M,N,SO>& src ) /* throw() */
5864 {
5865  dst = src;
5866 }
5867 //*************************************************************************************************
5868 
5869 
5870 
5871 
5872 //=================================================================================================
5873 //
5874 // HASCONSTDATAACCESS SPECIALIZATIONS
5875 //
5876 //=================================================================================================
5877 
5878 //*************************************************************************************************
5880 template< typename T, size_t M, size_t N, bool SO >
5881 struct HasConstDataAccess< HybridMatrix<T,M,N,SO> > : public IsTrue<true>
5882 {};
5884 //*************************************************************************************************
5885 
5886 
5887 
5888 
5889 //=================================================================================================
5890 //
5891 // HASMUTABLEDATAACCESS SPECIALIZATIONS
5892 //
5893 //=================================================================================================
5894 
5895 //*************************************************************************************************
5897 template< typename T, size_t M, size_t N, bool SO >
5898 struct HasMutableDataAccess< HybridMatrix<T,M,N,SO> > : public IsTrue<true>
5899 {};
5901 //*************************************************************************************************
5902 
5903 
5904 
5905 
5906 //=================================================================================================
5907 //
5908 // ISALIGNED SPECIALIZATIONS
5909 //
5910 //=================================================================================================
5911 
5912 //*************************************************************************************************
5914 template< typename T, size_t M, size_t N, bool SO >
5915 struct IsAligned< HybridMatrix<T,M,N,SO> > : public IsTrue<usePadding>
5916 {};
5918 //*************************************************************************************************
5919 
5920 
5921 
5922 
5923 //=================================================================================================
5924 //
5925 // ISPADDED SPECIALIZATIONS
5926 //
5927 //=================================================================================================
5928 
5929 //*************************************************************************************************
5931 template< typename T, size_t M, size_t N, bool SO >
5932 struct IsPadded< HybridMatrix<T,M,N,SO> > : public IsTrue<usePadding>
5933 {};
5935 //*************************************************************************************************
5936 
5937 
5938 
5939 
5940 //=================================================================================================
5941 //
5942 // ISRESIZABLE SPECIALIZATIONS
5943 //
5944 //=================================================================================================
5945 
5946 //*************************************************************************************************
5948 template< typename T, size_t M, size_t N, bool SO >
5949 struct IsResizable< HybridMatrix<T,M,N,SO> > : public IsTrue<true>
5950 {};
5952 //*************************************************************************************************
5953 
5954 
5955 
5956 
5957 //=================================================================================================
5958 //
5959 // ADDTRAIT SPECIALIZATIONS
5960 //
5961 //=================================================================================================
5962 
5963 //*************************************************************************************************
5965 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
5966 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
5967 {
5968  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M2, N2, SO > Type;
5969 };
5970 
5971 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5972 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
5973 {
5974  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M2, N2, false > Type;
5975 };
5976 
5977 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
5978 struct AddTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
5979 {
5980  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M2, N2, SO > Type;
5981 };
5982 
5983 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5984 struct AddTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
5985 {
5986  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M2, N2, false > Type;
5987 };
5988 
5989 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
5990 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
5991 {
5992  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO > Type;
5993 };
5994 
5995 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5996 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
5997 {
5998  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false > Type;
5999 };
6001 //*************************************************************************************************
6002 
6003 
6004 
6005 
6006 //=================================================================================================
6007 //
6008 // SUBTRAIT SPECIALIZATIONS
6009 //
6010 //=================================================================================================
6011 
6012 //*************************************************************************************************
6014 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6015 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
6016 {
6017  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M2, N2, SO > Type;
6018 };
6019 
6020 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6021 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6022 {
6023  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M2, N2, false > Type;
6024 };
6025 
6026 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6027 struct SubTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6028 {
6029  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M2, N2, SO > Type;
6030 };
6031 
6032 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6033 struct SubTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6034 {
6035  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M2, N2, false > Type;
6036 };
6037 
6038 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
6039 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
6040 {
6041  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO > Type;
6042 };
6043 
6044 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6045 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6046 {
6047  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false > Type;
6048 };
6050 //*************************************************************************************************
6051 
6052 
6053 
6054 
6055 //=================================================================================================
6056 //
6057 // MULTTRAIT SPECIALIZATIONS
6058 //
6059 //=================================================================================================
6060 
6061 //*************************************************************************************************
6063 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6064 struct MultTrait< HybridMatrix<T1,M,N,SO>, T2, typename EnableIf< IsNumeric<T2> >::Type >
6065 {
6066  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M, N, SO > Type;
6067 };
6068 
6069 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6070 struct MultTrait< T1, HybridMatrix<T2,M,N,SO>, typename EnableIf< IsNumeric<T1> >::Type >
6071 {
6072  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M, N, SO > Type;
6073 };
6074 
6075 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6076 struct MultTrait< HybridMatrix<T1,M,N,SO>, StaticVector<T2,K,false> >
6077 {
6078  typedef HybridVector< typename MultTrait<T1,T2>::Type, M, false > Type;
6079 };
6080 
6081 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6082 struct MultTrait< StaticVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6083 {
6084  typedef HybridVector< typename MultTrait<T1,T2>::Type, N, true > Type;
6085 };
6086 
6087 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
6088 struct MultTrait< HybridMatrix<T1,M,N,SO>, HybridVector<T2,K,false> >
6089 {
6090  typedef HybridVector< typename MultTrait<T1,T2>::Type, M, false > Type;
6091 };
6092 
6093 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
6094 struct MultTrait< HybridVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
6095 {
6096  typedef HybridVector< typename MultTrait<T1,T2>::Type, N, true > Type;
6097 };
6098 
6099 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6100 struct MultTrait< HybridMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
6101 {
6102  typedef HybridVector< typename MultTrait<T1,T2>::Type, M, false > Type;
6103 };
6104 
6105 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6106 struct MultTrait< DynamicVector<T1,true>, HybridMatrix<T2,M,N,SO> >
6107 {
6108  typedef HybridVector< typename MultTrait<T1,T2>::Type, N, true > Type;
6109 };
6110 
6111 template< typename T1, size_t M, size_t N, bool SO, typename T2, bool AF, bool PF >
6112 struct MultTrait< HybridMatrix<T1,M,N,SO>, CustomVector<T2,AF,PF,false> >
6113 {
6114  typedef HybridVector< typename MultTrait<T1,T2>::Type, M, false > Type;
6115 };
6116 
6117 template< typename T1, bool AF, bool PF, typename T2, size_t M, size_t N, bool SO >
6118 struct MultTrait< CustomVector<T1,AF,PF,true>, HybridMatrix<T2,M,N,SO> >
6119 {
6120  typedef HybridVector< typename MultTrait<T1,T2>::Type, N, true > Type;
6121 };
6122 
6123 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6124 struct MultTrait< HybridMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
6125 {
6126  typedef HybridVector< typename MultTrait<T1,T2>::Type, M, false > Type;
6127 };
6128 
6129 template< typename T1, typename T2, size_t M, size_t N, bool SO >
6130 struct MultTrait< CompressedVector<T1,true>, HybridMatrix<T2,M,N,SO> >
6131 {
6132  typedef HybridVector< typename MultTrait<T1,T2>::Type, N, true > Type;
6133 };
6134 
6135 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6136 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
6137 {
6138  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M1, N2, SO1 > Type;
6139 };
6140 
6141 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6142 struct MultTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6143 {
6144  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M1, N2, SO1 > Type;
6145 };
6146 
6147 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
6148 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
6149 {
6150  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M1, N2, SO1 > Type;
6151 };
6153 //*************************************************************************************************
6154 
6155 
6156 
6157 
6158 //=================================================================================================
6159 //
6160 // DIVTRAIT SPECIALIZATIONS
6161 //
6162 //=================================================================================================
6163 
6164 //*************************************************************************************************
6166 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6167 struct DivTrait< HybridMatrix<T1,M,N,SO>, T2, typename EnableIf< IsNumeric<T2> >::Type >
6168 {
6169  typedef HybridMatrix< typename DivTrait<T1,T2>::Type, M, N, SO > Type;
6170 };
6172 //*************************************************************************************************
6173 
6174 
6175 
6176 
6177 //=================================================================================================
6178 //
6179 // MATHTRAIT SPECIALIZATIONS
6180 //
6181 //=================================================================================================
6182 
6183 //*************************************************************************************************
6185 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
6186 struct MathTrait< HybridMatrix<T1,M,N,SO>, HybridMatrix<T2,M,N,SO> >
6187 {
6188  typedef HybridMatrix< typename MathTrait<T1,T2>::HighType, M, N, SO > HighType;
6189  typedef HybridMatrix< typename MathTrait<T1,T2>::LowType , M, N, SO > LowType;
6190 };
6192 //*************************************************************************************************
6193 
6194 
6195 
6196 
6197 //=================================================================================================
6198 //
6199 // SUBMATRIXTRAIT SPECIALIZATIONS
6200 //
6201 //=================================================================================================
6202 
6203 //*************************************************************************************************
6205 template< typename T1, size_t M, size_t N, bool SO >
6206 struct SubmatrixTrait< HybridMatrix<T1,M,N,SO> >
6207 {
6208  typedef HybridMatrix<T1,M,N,SO> Type;
6209 };
6211 //*************************************************************************************************
6212 
6213 
6214 
6215 
6216 //=================================================================================================
6217 //
6218 // ROWTRAIT SPECIALIZATIONS
6219 //
6220 //=================================================================================================
6221 
6222 //*************************************************************************************************
6224 template< typename T1, size_t M, size_t N, bool SO >
6225 struct RowTrait< HybridMatrix<T1,M,N,SO> >
6226 {
6227  typedef HybridVector<T1,N,true> Type;
6228 };
6230 //*************************************************************************************************
6231 
6232 
6233 
6234 
6235 //=================================================================================================
6236 //
6237 // COLUMNTRAIT SPECIALIZATIONS
6238 //
6239 //=================================================================================================
6240 
6241 //*************************************************************************************************
6243 template< typename T1, size_t M, size_t N, bool SO >
6244 struct ColumnTrait< HybridMatrix<T1,M,N,SO> >
6245 {
6246  typedef HybridVector<T1,M,false> Type;
6247 };
6249 //*************************************************************************************************
6250 
6251 } // namespace blaze
6252 
6253 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:118
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:116
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exceptionThis macro encapsulates the default way of...
Definition: Exception.h:187
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1729
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
ConstIterator cbegin(size_t i) const
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1088
ConstIterator cend(size_t i) const
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1160
BLAZE_ALWAYS_INLINE IntrinsicType loada(size_t i, size_t j) const
Aligned load of an intrinsic element of the matrix.
Definition: HybridMatrix.h:2243
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Header file for mathematical functions.
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:224
Header file for basic type definitions.
size_t spacing() const
Returns the spacing between the beginning of two rows.
Definition: HybridMatrix.h:1526
const bool defaultStorageOrder
The default storage order for all matrices of the Blaze library.This value specifies the default stor...
Definition: StorageOrder.h:56
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:252
Header file for the row trait.
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:250
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE void store(size_t i, size_t j, const IntrinsicType &value)
Store of an intrinsic element of the matrix.
Definition: HybridMatrix.h:2316
Header file for the IsSame and IsStrictlySame type traits.
BLAZE_ALWAYS_INLINE void storea(size_t i, size_t j, const IntrinsicType &value)
Aligned store of an intrinsic element of the matrix.
Definition: HybridMatrix.h:2347
Header file for the IsColumnMajorMatrix type trait.
Reference at(size_t i, size_t j)
Checked access to the matrix elements.
Definition: HybridMatrix.h:892
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:507
IT::Type IntrinsicType
Intrinsic type of the matrix elements.
Definition: HybridMatrix.h:225
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2749
Reference operator()(size_t i, size_t j)
2D-access to the matrix elements.
Definition: HybridMatrix.h:843
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:308
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: HybridMatrix.h:232
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:584
#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:116
const Type & ConstReference
Reference to a constant matrix value.
Definition: HybridMatrix.h:230
Header file for the SizeT class template.
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 enumeration is set to 1, the nested type definition Type is TrueType, and the class derives from TrueType. Otherwise value is set to 0, Type is FalseType, and the class derives from FalseType.
Definition: IsSame.h:158
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
Header file for memory allocation and deallocation functionality.
void move(CustomMatrix< Type, AF, PF, SO > &dst, CustomMatrix< Type, AF, PF, SO > &src)
Moving the contents of one custom matrix to another.
Definition: CustomMatrix.h:6085
System settings for performance optimizations.
HybridMatrix< Type, N, M,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: HybridMatrix.h:223
Type & Reference
Reference to a non-constant matrix value.
Definition: HybridMatrix.h:229
bool isAliased(const Other *alias) const
Returns whether the matrix is aliased with the given address alias.
Definition: HybridMatrix.h:2166
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:117
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:547
Constraint on the data type.
Header file for the SparseMatrix base class.
const This & CompositeType
Data type for composite expression templates.
Definition: HybridMatrix.h:227
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: HybridMatrix.h:1733
Header file for the DisableIf class template.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type loadu(const T *address)
Loads a vector of 2-byte integral values.
Definition: Loadu.h:74
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
size_t rows() const
Returns the current number of rows of the matrix.
Definition: HybridMatrix.h:1491
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.
Compile time assertion.
Iterator end(size_t i)
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1112
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b)
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:4998
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type storeu(T *address, const simd_int16_t &value)
Unaligned store of a vector of 2-byte integral values.
Definition: Storeu.h:75
Header file for all forward declarations of the math module.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2592
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: HybridMatrix.h:1584
#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:116
Compile time check for data types with padding.This type trait tests whether the given data type empl...
Definition: IsPadded.h:75
bool isAligned() const
Returns whether the matrix is properly aligned in memory.
Definition: HybridMatrix.h:2186
bool canAlias(const Other *alias) const
Returns whether the matrix can alias with the given address alias.
Definition: HybridMatrix.h:2144
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exceptionThis macro encapsulates the default way of Bla...
Definition: Exception.h:331
Header file for the DenseMatrix base class.
Pointer data()
Low-level data access to the matrix elements.
Definition: HybridMatrix.h:951
EnableIf< IsBuiltin< T > >::Type deallocate(T *address)
Deallocation of memory for built-in data types.
Definition: Memory.h:227
Header file for the DenseIterator class template.
BLAZE_ALWAYS_INLINE void conjugate(T &a)
In-place conjugation of the given value/object.
Definition: Conjugate.h:120
HybridMatrix()
The default constructor for HybridMatrix.
Definition: HybridMatrix.h:509
Type * Pointer
Pointer to a non-constant matrix value.
Definition: HybridMatrix.h:231
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:116
const Type & ReturnType
Return type for expression template evaluations.
Definition: HybridMatrix.h:226
Header file for the IsLower type trait.
IntrinsicTrait< Type > IT
Intrinsic trait for the matrix element type.
Definition: HybridMatrix.h:210
size_t m_
The current number of rows of the matrix.
Definition: HybridMatrix.h:473
Header file for the IsAligned type trait.
HybridMatrix< Type, M, N, SO > This
Type of this HybridMatrix instance.
Definition: HybridMatrix.h:220
Compile time check for diagonal matrices.This type trait tests whether or not the given template para...
Definition: IsDiagonal.h:92
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:79
void reset()
Reset to the default initial values.
Definition: HybridMatrix.h:1638
HybridMatrix & ctranspose()
In-place conjugate transpose of the matrix.
Definition: HybridMatrix.h:1856
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:187
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:532
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2590
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:527
Header file for the IsPadded type trait.
Header file for the IsVectorizable type trait.
HybridMatrix< Type, M, N,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: HybridMatrix.h:222
Header file for the conjugate shim.
Header file for the IsNumeric type trait.
Header file for the HasConstDataAccess type trait.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, simd_int16_t >::Type loada(const T *address)
Loads a vector of 2-byte integral values.
Definition: Loada.h:77
Iterator begin(size_t i)
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:1040
AlignedArray< Type, M *NN > v_
The statically allocated matrix elements.
Definition: HybridMatrix.h:463
#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:116
Compile time integral constant wrapper for size_t.The SizeT class template represents an integral wra...
Definition: SizeT.h:72
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:1232
Header file for run time assertion macros.
HybridMatrix & transpose()
In-place transpose of the matrix.
Definition: HybridMatrix.h:1805
Header file for the addition trait.
Header file for the division trait.
size_t capacity() const
Returns the maximum capacity of the matrix.
Definition: HybridMatrix.h:1542
Header file for the submatrix trait.
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: HybridMatrix.h:221
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Constraint on the data type.
DenseIterator< Type, usePadding > Iterator
Iterator over non-constant elements.
Definition: HybridMatrix.h:234
const bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
Header file for the AlignedArray implementation.
const bool usePadding
Configuration of the padding of dense vectors and matrices.This configuration switch enables/disables...
Definition: Optimizations.h:52
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:116
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2591
Header file for the column trait.
Header file for the isDefault shim.
Header file for the TransExprTrait class template.
Constraint on the data type.
Base class for matrices.The Matrix class is a base class for all dense and sparse matrix classes with...
Definition: Forward.h:94
Constraint on the data type.
Constraint on the data type.
Header file for the HasMutableDataAccess type trait.
Evaluation of the return type of a conjugate transpose expression.Via this type trait it is possible ...
Definition: CTransExprTrait.h:87
Substitution Failure Is Not An Error (SFINAE) class.The DisableIf class template is an auxiliary tool...
Definition: DisableIf.h:184
void swap(DiagonalMatrix< MT, SO, DF > &a, DiagonalMatrix< MT, SO, DF > &b)
Swapping the contents of two matrices.
Definition: DiagonalMatrix.h:256
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:59
Header file for all intrinsic functionality.
Header file for the mathematical trait.
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:242
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:235
HybridMatrix< ET, M, N, SO > Other
The type of the other HybridMatrix.
Definition: HybridMatrix.h:243
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2750
Evaluation of the return type of a transpose expression.Via this type trait it is possible to evaluat...
Definition: TransExprTrait.h:87
Header file for the IsRowMajorMatrix type trait.
BLAZE_ALWAYS_INLINE IntrinsicType load(size_t i, size_t j) const
Load of an intrinsic element of the matrix.
Definition: HybridMatrix.h:2213
Header file for the alignment check function.
BLAZE_ALWAYS_INLINE void cswap(T &a, T &b)
Swapping two conjugated values/objects.
Definition: Conjugate.h:197
BLAZE_ALWAYS_INLINE void stream(size_t i, size_t j, const IntrinsicType &value)
Aligned, non-temporal store of an intrinsic element of the matrix.
Definition: HybridMatrix.h:2421
static const size_t NN
Alignment adjustment.
Definition: HybridMatrix.h:215
size_t n_
The current number of columns of the matrix.
Definition: HybridMatrix.h:474
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2583
Header file for the IsTrue value trait.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type stream(T *address, const simd_int16_t &value)
Aligned, non-temporal store of a vector of 2-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:324
void swap(HybridMatrix &m)
Swapping the contents of two hybrid matrices.
Definition: HybridMatrix.h:1928
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:237
void clear()
Clearing the hybrid matrix.
Definition: HybridMatrix.h:1686
Compile time check for sparse matrix types.This type trait tests whether or not the given template pa...
Definition: IsSparseMatrix.h:103
size_t columns() const
Returns the current number of columns of the matrix.
Definition: HybridMatrix.h:1507
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2589
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exceptionThis macro encapsulates the default way of Blaz...
Definition: Exception.h:283
Rebind mechanism to obtain a CompressedMatrix with different data/element type.
Definition: CompressedMatrix.h:2599
Header file for the IsUpper type trait.
Header file for exception macros.
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:1782
#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:143
BLAZE_ALWAYS_INLINE void storeu(size_t i, size_t j, const IntrinsicType &value)
Unaligned store of an intrinsic element of the matrix.
Definition: HybridMatrix.h:2385
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
BLAZE_ALWAYS_INLINE IntrinsicType loadu(size_t i, size_t j) const
Unaligned load of an intrinsic element of the matrix.
Definition: HybridMatrix.h:2280
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type storea(T *address, const simd_int16_t &value)
Aligned store of a vector of 2-byte integral values.
Definition: Storea.h:78
Compile time integral round up operation.The NextMultiple class template rounds up the given template...
Definition: NextMultiple.h:81
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:558