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>
45 #include <stdexcept>
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>
75 #include <blaze/system/Inline.h>
78 #include <blaze/util/Assert.h>
86 #include <blaze/util/DisableIf.h>
87 #include <blaze/util/EnableIf.h>
88 #include <blaze/util/Memory.h>
90 #include <blaze/util/Template.h>
91 #include <blaze/util/Types.h>
95 #include <blaze/util/Unused.h>
96 
97 
98 namespace blaze {
99 
100 //=================================================================================================
101 //
102 // CLASS DEFINITION
103 //
104 //=================================================================================================
105 
106 //*************************************************************************************************
192 template< typename Type // Data type of the matrix
193  , size_t M // Number of rows
194  , size_t N // Number of columns
195  , bool SO = defaultStorageOrder > // Storage order
196 class HybridMatrix : public DenseMatrix< HybridMatrix<Type,M,N,SO>, SO >
197 {
198  private:
199  //**Type definitions****************************************************************************
201  //**********************************************************************************************
202 
203  //**********************************************************************************************
205  enum { NN = N + ( IT::size - ( N % IT::size ) ) % IT::size };
206  //**********************************************************************************************
207 
208  public:
209  //**Type definitions****************************************************************************
211  typedef This ResultType;
214  typedef Type ElementType;
215  typedef typename IT::Type IntrinsicType;
216  typedef const Type& ReturnType;
217  typedef const This& CompositeType;
218  typedef Type& Reference;
219  typedef const Type& ConstReference;
220  typedef Type* Pointer;
221  typedef const Type* ConstPointer;
224  //**********************************************************************************************
225 
226  //**Rebind struct definition********************************************************************
229  template< typename ET > // Data type of the other matrix
230  struct Rebind {
232  };
233  //**********************************************************************************************
234 
235  //**Compilation flags***************************************************************************
237 
241  enum { vectorizable = IsVectorizable<Type>::value };
242 
244 
247  enum { smpAssignable = 0 };
248  //**********************************************************************************************
249 
250  //**Constructors********************************************************************************
253  explicit inline HybridMatrix();
254  explicit inline HybridMatrix( size_t m, size_t n );
255  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
256  template< typename Other > explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
257 
258  template< typename Other, size_t M2, size_t N2 >
259  explicit inline HybridMatrix( const Other (&array)[M2][N2] );
260 
261  inline HybridMatrix( const HybridMatrix& m );
262  template< typename MT, bool SO2 > inline HybridMatrix( const Matrix<MT,SO2>& m );
264  //**********************************************************************************************
265 
266  //**Destructor**********************************************************************************
267  // No explicitly declared destructor.
268  //**********************************************************************************************
269 
270  //**Data access functions***********************************************************************
273  inline Reference operator()( size_t i, size_t j );
274  inline ConstReference operator()( size_t i, size_t j ) const;
275  inline Pointer data ();
276  inline ConstPointer data () const;
277  inline Pointer data ( size_t i );
278  inline ConstPointer data ( size_t i ) const;
279  inline Iterator begin ( size_t i );
280  inline ConstIterator begin ( size_t i ) const;
281  inline ConstIterator cbegin( size_t i ) const;
282  inline Iterator end ( size_t i );
283  inline ConstIterator end ( size_t i ) const;
284  inline ConstIterator cend ( size_t i ) const;
286  //**********************************************************************************************
287 
288  //**Assignment operators************************************************************************
291  template< typename Other, size_t M2, size_t N2 >
292  inline HybridMatrix& operator=( const Other (&array)[M2][N2] );
293 
294  inline HybridMatrix& operator= ( const Type& set );
295  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
296  template< typename MT, bool SO2 > inline HybridMatrix& operator= ( const Matrix<MT,SO2>& rhs );
297  template< typename MT, bool SO2 > inline HybridMatrix& operator+=( const Matrix<MT,SO2>& rhs );
298  template< typename MT, bool SO2 > inline HybridMatrix& operator-=( const Matrix<MT,SO2>& rhs );
299  template< typename MT, bool SO2 > inline HybridMatrix& operator*=( const Matrix<MT,SO2>& rhs );
300 
301  template< typename Other >
302  inline typename EnableIf< IsNumeric<Other>, HybridMatrix >::Type&
303  operator*=( Other rhs );
304 
305  template< typename Other >
306  inline typename EnableIf< IsNumeric<Other>, HybridMatrix >::Type&
307  operator/=( Other rhs );
309  //**********************************************************************************************
310 
311  //**Utility functions***************************************************************************
314  inline size_t rows() const;
315  inline size_t columns() const;
316  inline size_t spacing() const;
317  inline size_t capacity() const;
318  inline size_t capacity( size_t i ) const;
319  inline size_t nonZeros() const;
320  inline size_t nonZeros( size_t i ) const;
321  inline void reset();
322  inline void reset( size_t i );
323  inline void clear();
324  void resize ( size_t m, size_t n, bool preserve=true );
325  inline void extend ( size_t m, size_t n, bool preserve=true );
326  inline HybridMatrix& transpose();
327  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
328  inline void swap( HybridMatrix& m ) /* throw() */;
330  //**********************************************************************************************
331 
332  //**Memory functions****************************************************************************
335  static inline void* operator new ( std::size_t size );
336  static inline void* operator new[]( std::size_t size );
337  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
338  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
339 
340  static inline void operator delete ( void* ptr );
341  static inline void operator delete[]( void* ptr );
342  static inline void operator delete ( void* ptr, const std::nothrow_t& );
343  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
345  //**********************************************************************************************
346 
347  private:
348  //**********************************************************************************************
350  template< typename MT >
352  struct VectorizedAssign {
353  enum { value = vectorizable && MT::vectorizable &&
354  IsSame<Type,typename MT::ElementType>::value &&
355  IsRowMajorMatrix<MT>::value };
356  };
358  //**********************************************************************************************
359 
360  //**********************************************************************************************
362  template< typename MT >
364  struct VectorizedAddAssign {
365  enum { value = vectorizable && MT::vectorizable &&
366  IsSame<Type,typename MT::ElementType>::value &&
367  IntrinsicTrait<Type>::addition &&
368  IsRowMajorMatrix<MT>::value &&
369  !IsDiagonal<MT>::value };
370  };
372  //**********************************************************************************************
373 
374  //**********************************************************************************************
376  template< typename MT >
378  struct VectorizedSubAssign {
379  enum { value = vectorizable && MT::vectorizable &&
380  IsSame<Type,typename MT::ElementType>::value &&
381  IntrinsicTrait<Type>::subtraction &&
382  IsRowMajorMatrix<MT>::value &&
383  !IsDiagonal<MT>::value };
384  };
386  //**********************************************************************************************
387 
388  public:
389  //**Expression template evaluation functions****************************************************
392  template< typename Other > inline bool canAlias ( const Other* alias ) const;
393  template< typename Other > inline bool isAliased( const Other* alias ) const;
394 
395  inline bool isAligned() const;
396 
397  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
398  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
399  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
400  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
401  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
402 
403  template< typename MT, bool SO2 >
404  inline typename DisableIf< VectorizedAssign<MT> >::Type
405  assign( const DenseMatrix<MT,SO2>& rhs );
406 
407  template< typename MT, bool SO2 >
408  inline typename EnableIf< VectorizedAssign<MT> >::Type
409  assign( const DenseMatrix<MT,SO2>& rhs );
410 
411  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
412  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
413 
414  template< typename MT, bool SO2 >
415  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
416  addAssign( const DenseMatrix<MT,SO2>& rhs );
417 
418  template< typename MT, bool SO2 >
419  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
420  addAssign( const DenseMatrix<MT,SO2>& rhs );
421 
422  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
423  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
424 
425  template< typename MT, bool SO2 >
426  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
427  subAssign( const DenseMatrix<MT,SO2>& rhs );
428 
429  template< typename MT, bool SO2 >
430  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
431  subAssign( const DenseMatrix<MT,SO2>& rhs );
432 
433  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
434  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
436  //**********************************************************************************************
437 
438  private:
439  //**Member variables****************************************************************************
443 
452  size_t m_;
453  size_t n_;
454 
455  //**********************************************************************************************
456 
457  //**Compile time checks*************************************************************************
463  BLAZE_STATIC_ASSERT( NN % IT::size == 0UL );
464  BLAZE_STATIC_ASSERT( NN >= N );
466  //**********************************************************************************************
467 };
468 //*************************************************************************************************
469 
470 
471 
472 
473 //=================================================================================================
474 //
475 // CONSTRUCTORS
476 //
477 //=================================================================================================
478 
479 //*************************************************************************************************
484 template< typename Type // Data type of the matrix
485  , size_t M // Number of rows
486  , size_t N // Number of columns
487  , bool SO > // Storage order
489  : v_() // The statically allocated matrix elements
490  , m_( 0UL ) // The current number of rows of the matrix
491  , n_( 0UL ) // The current number of columns of the matrix
492 {
494 
495  if( IsNumeric<Type>::value ) {
496  for( size_t i=0UL; i<M*NN; ++i )
497  v_[i] = Type();
498  }
499 }
500 //*************************************************************************************************
501 
502 
503 //*************************************************************************************************
516 template< typename Type // Data type of the matrix
517  , size_t M // Number of rows
518  , size_t N // Number of columns
519  , bool SO > // Storage order
520 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n )
521  : v_() // The statically allocated matrix elements
522  , m_( m ) // The current number of rows of the matrix
523  , n_( n ) // The current number of columns of the matrix
524 {
526 
527  if( m > M )
528  throw std::invalid_argument( "Invalid number of rows for hybrid matrix" );
529 
530  if( n > N )
531  throw std::invalid_argument( "Invalid number of columns for hybrid matrix" );
532 
533  if( IsNumeric<Type>::value ) {
534  for( size_t i=0UL; i<M*NN; ++i )
535  v_[i] = Type();
536  }
537 }
538 //*************************************************************************************************
539 
540 
541 //*************************************************************************************************
555 template< typename Type // Data type of the matrix
556  , size_t M // Number of rows
557  , size_t N // Number of columns
558  , bool SO > // Storage order
559 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Type& init )
560  : v_() // The statically allocated matrix elements
561  , m_( m ) // The current number of rows of the matrix
562  , n_( n ) // The current number of columns of the matrix
563 {
565 
566  if( m > M )
567  throw std::invalid_argument( "Invalid number of rows for hybrid matrix" );
568 
569  if( n > N )
570  throw std::invalid_argument( "Invalid number of columns for hybrid matrix" );
571 
572  for( size_t i=0UL; i<m; ++i ) {
573  for( size_t j=0UL; j<n; ++j )
574  v_[i*NN+j] = init;
575 
576  if( IsNumeric<Type>::value ) {
577  for( size_t j=n; j<NN; ++j )
578  v_[i*NN+j] = Type();
579  }
580  }
581 
582  if( IsNumeric<Type>::value ) {
583  for( size_t i=m; i<M; ++i )
584  for( size_t j=0UL; j<NN; ++j )
585  v_[i*NN+j] = Type();
586  }
587 }
588 //*************************************************************************************************
589 
590 
591 //*************************************************************************************************
618 template< typename Type // Data type of the matrix
619  , size_t M // Number of rows
620  , size_t N // Number of columns
621  , bool SO > // Storage order
622 template< typename Other > // Data type of the initialization array
623 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( size_t m, size_t n, const Other* array )
624  : v_() // The statically allocated matrix elements
625  , m_( m ) // The current number of rows of the matrix
626  , n_( n ) // The current number of columns of the matrix
627 {
629 
630  if( m > M )
631  throw std::invalid_argument( "Invalid number of rows for hybrid matrix" );
632 
633  if( n > N )
634  throw std::invalid_argument( "Invalid number of columns for hybrid matrix" );
635 
636  for( size_t i=0UL; i<m; ++i ) {
637  for( size_t j=0UL; j<n; ++j )
638  v_[i*NN+j] = array[i*n+j];
639 
640  if( IsNumeric<Type>::value ) {
641  for( size_t j=n; j<NN; ++j )
642  v_[i*NN+j] = Type();
643  }
644  }
645 
646  if( IsNumeric<Type>::value ) {
647  for( size_t i=m; i<M; ++i )
648  for( size_t j=0UL; j<NN; ++j )
649  v_[i*NN+j] = Type();
650  }
651 }
652 //*************************************************************************************************
653 
654 
655 //*************************************************************************************************
676 template< typename Type // Data type of the matrix
677  , size_t M // Number of rows
678  , size_t N // Number of columns
679  , bool SO > // Storage order
680 template< typename Other // Data type of the initialization array
681  , size_t M2 // Number of rows of the initialization array
682  , size_t N2 > // Number of columns of the initialization array
683 inline HybridMatrix<Type,M,N,SO>::HybridMatrix( const Other (&array)[M2][N2] )
684  : v_() // The statically allocated matrix elements
685  , m_( M2 ) // The current number of rows of the matrix
686  , n_( N2 ) // The current number of columns of the matrix
687 {
688  BLAZE_STATIC_ASSERT( M2 <= M );
689  BLAZE_STATIC_ASSERT( N2 <= N );
691 
692  for( size_t i=0UL; i<M2; ++i ) {
693  for( size_t j=0UL; j<N2; ++j )
694  v_[i*NN+j] = array[i][j];
695 
696  if( IsNumeric<Type>::value ) {
697  for( size_t j=N2; j<NN; ++j )
698  v_[i*NN+j] = Type();
699  }
700  }
701 
702  if( IsNumeric<Type>::value ) {
703  for( size_t i=M2; i<M; ++i )
704  for( size_t j=0UL; j<NN; ++j )
705  v_[i*NN+j] = Type();
706  }
707 }
708 //*************************************************************************************************
709 
710 
711 //*************************************************************************************************
719 template< typename Type // Data type of the matrix
720  , size_t M // Number of rows
721  , size_t N // Number of columns
722  , bool SO > // Storage order
724  : v_() // The statically allocated matrix elements
725  , m_( m.m_ ) // The current number of rows of the matrix
726  , n_( m.n_ ) // The current number of columns of the matrix
727 {
729 
730  for( size_t i=0UL; i<m_; ++i ) {
731  for( size_t j=0UL; j<n_; ++j )
732  v_[i*NN+j] = m.v_[i*NN+j];
733 
734  if( IsNumeric<Type>::value ) {
735  for( size_t j=n_; j<NN; ++j )
736  v_[i*NN+j] = Type();
737  }
738  }
739 
740  if( IsNumeric<Type>::value ) {
741  for( size_t i=m_; i<M; ++i )
742  for( size_t j=0UL; j<NN; ++j )
743  v_[i*NN+j] = Type();
744  }
745 }
746 //*************************************************************************************************
747 
748 
749 //*************************************************************************************************
755 template< typename Type // Data type of the matrix
756  , size_t M // Number of rows
757  , size_t N // Number of columns
758  , bool SO > // Storage order
759 template< typename MT // Type of the foreign matrix
760  , bool SO2 > // Storage order of the foreign matrix
762  : v_() // The statically allocated matrix elements
763  , m_( (~m).rows() ) // The current number of rows of the matrix
764  , n_( (~m).columns() ) // The current number of columns of the matrix
765 {
766  using blaze::assign;
767 
769 
770  if( (~m).rows() > M || (~m).columns() > N )
771  throw std::invalid_argument( "Invalid setup of hybrid matrix" );
772 
773  for( size_t i=0UL; i<m_; ++i ) {
774  for( size_t j=( IsSparseMatrix<MT>::value ? 0UL : n_ );
775  j<( IsNumeric<Type>::value ? NN : n_ );
776  ++j ) {
777  v_[i*NN+j] = Type();
778  }
779  }
780 
781  if( IsNumeric<Type>::value ) {
782  for( size_t i=m_; i<M; ++i )
783  for( size_t j=0UL; j<NN; ++j )
784  v_[i*NN+j] = Type();
785  }
786 
787  assign( *this, ~m );
788 }
789 //*************************************************************************************************
790 
791 
792 
793 
794 //=================================================================================================
795 //
796 // DATA ACCESS FUNCTIONS
797 //
798 //=================================================================================================
799 
800 //*************************************************************************************************
807 template< typename Type // Data type of the matrix
808  , size_t M // Number of rows
809  , size_t N // Number of columns
810  , bool SO > // Storage order
813 {
814  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
815  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
816  return v_[i*NN+j];
817 }
818 //*************************************************************************************************
819 
820 
821 //*************************************************************************************************
828 template< typename Type // Data type of the matrix
829  , size_t M // Number of rows
830  , size_t N // Number of columns
831  , bool SO > // Storage order
833  HybridMatrix<Type,M,N,SO>::operator()( size_t i, size_t j ) const
834 {
835  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
836  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
837  return v_[i*NN+j];
838 }
839 //*************************************************************************************************
840 
841 
842 //*************************************************************************************************
854 template< typename Type // Data type of the matrix
855  , size_t M // Number of rows
856  , size_t N // Number of columns
857  , bool SO > // Storage order
860 {
861  return v_;
862 }
863 //*************************************************************************************************
864 
865 
866 //*************************************************************************************************
878 template< typename Type // Data type of the matrix
879  , size_t M // Number of rows
880  , size_t N // Number of columns
881  , bool SO > // Storage order
884 {
885  return v_;
886 }
887 //*************************************************************************************************
888 
889 
890 //*************************************************************************************************
898 template< typename Type // Data type of the matrix
899  , size_t M // Number of rows
900  , size_t N // Number of columns
901  , bool SO > // Storage order
904 {
905  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
906  return v_ + i*NN;
907 }
908 //*************************************************************************************************
909 
910 
911 //*************************************************************************************************
919 template< typename Type // Data type of the matrix
920  , size_t M // Number of rows
921  , size_t N // Number of columns
922  , bool SO > // Storage order
925 {
926  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
927  return v_ + i*NN;
928 }
929 //*************************************************************************************************
930 
931 
932 //*************************************************************************************************
943 template< typename Type // Data type of the matrix
944  , size_t M // Number of rows
945  , size_t N // Number of columns
946  , bool SO > // Storage order
949 {
950  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
951  return Iterator( v_ + i*NN );
952 }
953 //*************************************************************************************************
954 
955 
956 //*************************************************************************************************
967 template< typename Type // Data type of the matrix
968  , size_t M // Number of rows
969  , size_t N // Number of columns
970  , bool SO > // Storage order
973 {
974  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
975  return ConstIterator( v_ + i*NN );
976 }
977 //*************************************************************************************************
978 
979 
980 //*************************************************************************************************
991 template< typename Type // Data type of the matrix
992  , size_t M // Number of rows
993  , size_t N // Number of columns
994  , bool SO > // Storage order
997 {
998  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
999  return ConstIterator( v_ + i*NN );
1000 }
1001 //*************************************************************************************************
1002 
1003 
1004 //*************************************************************************************************
1015 template< typename Type // Data type of the matrix
1016  , size_t M // Number of rows
1017  , size_t N // Number of columns
1018  , bool SO > // Storage order
1021 {
1022  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1023  return Iterator( v_ + i*NN + N );
1024 }
1025 //*************************************************************************************************
1026 
1027 
1028 //*************************************************************************************************
1039 template< typename Type // Data type of the matrix
1040  , size_t M // Number of rows
1041  , size_t N // Number of columns
1042  , bool SO > // Storage order
1045 {
1046  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1047  return ConstIterator( v_ + i*NN + N );
1048 }
1049 //*************************************************************************************************
1050 
1051 
1052 //*************************************************************************************************
1063 template< typename Type // Data type of the matrix
1064  , size_t M // Number of rows
1065  , size_t N // Number of columns
1066  , bool SO > // Storage order
1069 {
1070  BLAZE_USER_ASSERT( i < M, "Invalid dense matrix row access index" );
1071  return ConstIterator( v_ + i*NN + N );
1072 }
1073 //*************************************************************************************************
1074 
1075 
1076 
1077 
1078 //=================================================================================================
1079 //
1080 // ASSIGNMENT OPERATORS
1081 //
1082 //=================================================================================================
1083 
1084 //*************************************************************************************************
1105 template< typename Type // Data type of the matrix
1106  , size_t M // Number of rows
1107  , size_t N // Number of columns
1108  , bool SO > // Storage order
1109 template< typename Other // Data type of the initialization array
1110  , size_t M2 // Number of rows of the initialization array
1111  , size_t N2 > // Number of columns of the initialization array
1113 {
1114  BLAZE_STATIC_ASSERT( M2 <= M );
1115  BLAZE_STATIC_ASSERT( N2 <= N );
1116 
1117  resize( M2, N2 );
1118 
1119  for( size_t i=0UL; i<M2; ++i )
1120  for( size_t j=0UL; j<N2; ++j )
1121  v_[i*NN+j] = array[i][j];
1122 
1123  return *this;
1124 }
1125 //*************************************************************************************************
1126 
1127 
1128 //*************************************************************************************************
1134 template< typename Type // Data type of the matrix
1135  , size_t M // Number of rows
1136  , size_t N // Number of columns
1137  , bool SO > // Storage order
1139 {
1140  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1141  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1142 
1143  for( size_t i=0UL; i<m_; ++i )
1144  for( size_t j=0UL; j<n_; ++j )
1145  v_[i*NN+j] = set;
1146 
1147  return *this;
1148 }
1149 //*************************************************************************************************
1150 
1151 
1152 //*************************************************************************************************
1160 template< typename Type // Data type of the matrix
1161  , size_t M // Number of rows
1162  , size_t N // Number of columns
1163  , bool SO > // Storage order
1165 {
1166  using blaze::assign;
1167 
1168  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
1169  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
1170 
1171  resize( rhs.rows(), rhs.columns() );
1172  assign( *this, ~rhs );
1173 
1174  return *this;
1175 }
1176 //*************************************************************************************************
1177 
1178 
1179 //*************************************************************************************************
1190 template< typename Type // Data type of the matrix
1191  , size_t M // Number of rows
1192  , size_t N // Number of columns
1193  , bool SO > // Storage order
1194 template< typename MT // Type of the right-hand side matrix
1195  , bool SO2 > // Storage order of the right-hand side matrix
1197 {
1198  using blaze::assign;
1199 
1200  if( (~rhs).rows() > M || (~rhs).columns() > N )
1201  throw std::invalid_argument( "Invalid assignment to hybrid matrix" );
1202 
1203  if( (~rhs).canAlias( this ) ) {
1204  HybridMatrix tmp( ~rhs );
1205  swap( tmp );
1206  }
1207  else {
1208  resize( (~rhs).rows(), (~rhs).columns() );
1210  reset();
1211  assign( *this, ~rhs );
1212  }
1213 
1214  return *this;
1215 }
1216 //*************************************************************************************************
1217 
1218 
1219 //*************************************************************************************************
1229 template< typename Type // Data type of the matrix
1230  , size_t M // Number of rows
1231  , size_t N // Number of columns
1232  , bool SO > // Storage order
1233 template< typename MT // Type of the right-hand side matrix
1234  , bool SO2 > // Storage order of the right-hand side matrix
1236 {
1237  using blaze::addAssign;
1238 
1239  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
1240  throw std::invalid_argument( "Matrix sizes do not match" );
1241 
1242  if( (~rhs).canAlias( this ) ) {
1243  typename MT::ResultType tmp( ~rhs );
1244  addAssign( *this, tmp );
1245  }
1246  else {
1247  addAssign( *this, ~rhs );
1248  }
1249 
1250  return *this;
1251 }
1252 //*************************************************************************************************
1253 
1254 
1255 //*************************************************************************************************
1265 template< typename Type // Data type of the matrix
1266  , size_t M // Number of rows
1267  , size_t N // Number of columns
1268  , bool SO > // Storage order
1269 template< typename MT // Type of the right-hand side matrix
1270  , bool SO2 > // Storage order of the right-hand side matrix
1272 {
1273  using blaze::subAssign;
1274 
1275  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
1276  throw std::invalid_argument( "Matrix sizes do not match" );
1277 
1278  if( (~rhs).canAlias( this ) ) {
1279  typename MT::ResultType tmp( ~rhs );
1280  subAssign( *this, tmp );
1281  }
1282  else {
1283  subAssign( *this, ~rhs );
1284  }
1285 
1286  return *this;
1287 }
1288 //*************************************************************************************************
1289 
1290 
1291 //*************************************************************************************************
1301 template< typename Type // Data type of the matrix
1302  , size_t M // Number of rows
1303  , size_t N // Number of columns
1304  , bool SO > // Storage order
1305 template< typename MT // Type of the right-hand side matrix
1306  , bool SO2 > // Storage order of the right-hand side matrix
1308 {
1309  if( n_ != (~rhs).rows() || (~rhs).columns() > N )
1310  throw std::invalid_argument( "Matrix sizes do not match" );
1311 
1312  HybridMatrix tmp( *this * (~rhs) );
1313  return this->operator=( tmp );
1314 }
1315 //*************************************************************************************************
1316 
1317 
1318 //*************************************************************************************************
1325 template< typename Type // Data type of the matrix
1326  , size_t M // Number of rows
1327  , size_t N // Number of columns
1328  , bool SO > // Storage order
1329 template< typename Other > // Data type of the right-hand side scalar
1330 inline typename EnableIf< IsNumeric<Other>, HybridMatrix<Type,M,N,SO> >::Type&
1332 {
1333  using blaze::assign;
1334 
1335  assign( *this, (*this) * rhs );
1336  return *this;
1337 }
1338 //*************************************************************************************************
1339 
1340 
1341 //*************************************************************************************************
1350 template< typename Type // Data type of the matrix
1351  , size_t M // Number of rows
1352  , size_t N // Number of columns
1353  , bool SO > // Storage order
1354 template< typename Other > // Data type of the right-hand side scalar
1355 inline typename EnableIf< IsNumeric<Other>, HybridMatrix<Type,M,N,SO> >::Type&
1357 {
1358  using blaze::assign;
1359 
1360  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1361 
1362  assign( *this, (*this) / rhs );
1363  return *this;
1364 }
1365 //*************************************************************************************************
1366 
1367 
1368 
1369 
1370 //=================================================================================================
1371 //
1372 // UTILITY FUNCTIONS
1373 //
1374 //=================================================================================================
1375 
1376 //*************************************************************************************************
1381 template< typename Type // Data type of the matrix
1382  , size_t M // Number of rows
1383  , size_t N // Number of columns
1384  , bool SO > // Storage order
1385 inline size_t HybridMatrix<Type,M,N,SO>::rows() const
1386 {
1387  return m_;
1388 }
1389 //*************************************************************************************************
1390 
1391 
1392 //*************************************************************************************************
1397 template< typename Type // Data type of the matrix
1398  , size_t M // Number of rows
1399  , size_t N // Number of columns
1400  , bool SO > // Storage order
1402 {
1403  return n_;
1404 }
1405 //*************************************************************************************************
1406 
1407 
1408 //*************************************************************************************************
1416 template< typename Type // Data type of the matrix
1417  , size_t M // Number of rows
1418  , size_t N // Number of columns
1419  , bool SO > // Storage order
1421 {
1422  return NN;
1423 }
1424 //*************************************************************************************************
1425 
1426 
1427 //*************************************************************************************************
1432 template< typename Type // Data type of the matrix
1433  , size_t M // Number of rows
1434  , size_t N // Number of columns
1435  , bool SO > // Storage order
1437 {
1438  return M*NN;
1439 }
1440 //*************************************************************************************************
1441 
1442 
1443 //*************************************************************************************************
1454 template< typename Type // Data type of the matrix
1455  , size_t M // Number of rows
1456  , size_t N // Number of columns
1457  , bool SO > // Storage order
1458 inline size_t HybridMatrix<Type,M,N,SO>::capacity( size_t i ) const
1459 {
1460  UNUSED_PARAMETER( i );
1461 
1462  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1463 
1464  return NN;
1465 }
1466 //*************************************************************************************************
1467 
1468 
1469 //*************************************************************************************************
1474 template< typename Type // Data type of the matrix
1475  , size_t M // Number of rows
1476  , size_t N // Number of columns
1477  , bool SO > // Storage order
1479 {
1480  size_t nonzeros( 0UL );
1481 
1482  for( size_t i=0UL; i<m_; ++i )
1483  for( size_t j=0UL; j<n_; ++j )
1484  if( !isDefault( v_[i*NN+j] ) )
1485  ++nonzeros;
1486 
1487  return nonzeros;
1488 }
1489 //*************************************************************************************************
1490 
1491 
1492 //*************************************************************************************************
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
1507 inline size_t HybridMatrix<Type,M,N,SO>::nonZeros( size_t i ) const
1508 {
1509  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1510 
1511  const size_t jend( i*NN+n_ );
1512  size_t nonzeros( 0UL );
1513 
1514  for( size_t j=i*NN; j<jend; ++j )
1515  if( !isDefault( v_[j] ) )
1516  ++nonzeros;
1517 
1518  return nonzeros;
1519 }
1520 //*************************************************************************************************
1521 
1522 
1523 //*************************************************************************************************
1528 template< typename Type // Data type of the matrix
1529  , size_t M // Number of rows
1530  , size_t N // Number of columns
1531  , bool SO > // Storage order
1533 {
1534  using blaze::clear;
1535 
1536  for( size_t i=0UL; i<m_; ++i )
1537  for( size_t j=0UL; j<n_; ++j )
1538  clear( v_[i*NN+j] );
1539 }
1540 //*************************************************************************************************
1541 
1542 
1543 //*************************************************************************************************
1554 template< typename Type // Data type of the matrix
1555  , size_t M // Number of rows
1556  , size_t N // Number of columns
1557  , bool SO > // Storage order
1558 inline void HybridMatrix<Type,M,N,SO>::reset( size_t i )
1559 {
1560  using blaze::clear;
1561 
1562  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1563  for( size_t j=0UL; j<n_; ++j )
1564  clear( v_[i*NN+j] );
1565 }
1566 //*************************************************************************************************
1567 
1568 
1569 //*************************************************************************************************
1576 template< typename Type // Data type of the matrix
1577  , size_t M // Number of rows
1578  , size_t N // Number of columns
1579  , bool SO > // Storage order
1581 {
1582  resize( 0UL, 0UL );
1583 }
1584 //*************************************************************************************************
1585 
1586 
1587 //*************************************************************************************************
1623 template< typename Type // Data type of the matrix
1624  , size_t M // Number of rows
1625  , size_t N // Number of columns
1626  , bool SO > // Storage order
1627 void HybridMatrix<Type,M,N,SO>::resize( size_t m, size_t n, bool preserve )
1628 {
1629  UNUSED_PARAMETER( preserve );
1630 
1631  if( m > M )
1632  throw std::invalid_argument( "Invalid number of rows for hybrid matrix" );
1633 
1634  if( n > N )
1635  throw std::invalid_argument( "Invalid number of columns for hybrid matrix" );
1636 
1637  if( IsVectorizable<Type>::value && n < n_ ) {
1638  for( size_t i=0UL; i<m; ++i )
1639  for( size_t j=n; j<n_; ++j )
1640  v_[i*NN+j] = Type();
1641  }
1642 
1643  if( IsVectorizable<Type>::value && m < m_ ) {
1644  for( size_t i=m; i<m_; ++i )
1645  for( size_t j=0UL; j<n_; ++j )
1646  v_[i*NN+j] = Type();
1647  }
1648 
1649  m_ = m;
1650  n_ = n;
1651 }
1652 //*************************************************************************************************
1653 
1654 
1655 //*************************************************************************************************
1670 template< typename Type // Data type of the matrix
1671  , size_t M // Number of rows
1672  , size_t N // Number of columns
1673  , bool SO > // Storage order
1674 inline void HybridMatrix<Type,M,N,SO>::extend( size_t m, size_t n, bool preserve )
1675 {
1676  UNUSED_PARAMETER( preserve );
1677  resize( m_+m, n_+n );
1678 }
1679 //*************************************************************************************************
1680 
1681 
1682 //*************************************************************************************************
1693 template< typename Type // Data type of the matrix
1694  , size_t M // Number of rows
1695  , size_t N // Number of columns
1696  , bool SO > // Storage order
1698 {
1699  using std::swap;
1700 
1701  if( m_ > N || n_ > M )
1702  throw std::logic_error( "Impossible transpose operation" );
1703 
1704  const size_t maxsize( max( m_, n_ ) );
1705  for( size_t i=1UL; i<maxsize; ++i )
1706  for( size_t j=0UL; j<i; ++j )
1707  swap( v_[i*NN+j], v_[j*NN+i] );
1708 
1709  if( IsVectorizable<Type>::value && m_ < n_ ) {
1710  for( size_t i=0UL; i<m_; ++i ) {
1711  for( size_t j=m_; j<n_; ++j ) {
1712  v_[i*NN+j] = Type();
1713  }
1714  }
1715  }
1716 
1717  if( IsVectorizable<Type>::value && m_ > n_ ) {
1718  for( size_t i=n_; i<m_; ++i ) {
1719  for( size_t j=0UL; j<n_; ++j ) {
1720  v_[i*NN+j] = Type();
1721  }
1722  }
1723  }
1724 
1725  swap( m_, n_ );
1726 
1727  return *this;
1728 }
1729 //*************************************************************************************************
1730 
1731 
1732 //*************************************************************************************************
1738 template< typename Type // Data type of the matrix
1739  , size_t M // Number of rows
1740  , size_t N // Number of columns
1741  , bool SO > // Storage order
1742 template< typename Other > // Data type of the scalar value
1744 {
1745  for( size_t i=0UL; i<m_; ++i )
1746  for( size_t j=0UL; j<n_; ++j )
1747  v_[i*NN+j] *= scalar;
1748 
1749  return *this;
1750 }
1751 //*************************************************************************************************
1752 
1753 
1754 //*************************************************************************************************
1761 template< typename Type // Data type of the matrix
1762  , size_t M // Number of rows
1763  , size_t N // Number of columns
1764  , bool SO > // Storage order
1765 inline void HybridMatrix<Type,M,N,SO>::swap( HybridMatrix& m ) /* throw() */
1766 {
1767  using std::swap;
1768 
1769  const size_t maxrows( max( m_, m.m_ ) );
1770  const size_t maxcols( max( n_, m.n_ ) );
1771 
1772  for( size_t i=0UL; i<maxrows; ++i ) {
1773  for( size_t j=0UL; j<maxcols; ++j ) {
1774  swap( v_[i*NN+j], m(i,j) );
1775  }
1776  }
1777 
1778  swap( m_, m.m_ );
1779  swap( n_, m.n_ );
1780 }
1781 //*************************************************************************************************
1782 
1783 
1784 
1785 
1786 //=================================================================================================
1787 //
1788 // MEMORY FUNCTIONS
1789 //
1790 //=================================================================================================
1791 
1792 //*************************************************************************************************
1802 template< typename Type // Data type of the matrix
1803  , size_t M // Number of rows
1804  , size_t N // Number of columns
1805  , bool SO > // Storage order
1806 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size )
1807 {
1809 
1810  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
1811 
1812  return allocate<HybridMatrix>( 1UL );
1813 }
1814 //*************************************************************************************************
1815 
1816 
1817 //*************************************************************************************************
1827 template< typename Type // Data type of the matrix
1828  , size_t M // Number of rows
1829  , size_t N // Number of columns
1830  , bool SO > // Storage order
1831 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size )
1832 {
1833  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
1834  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
1835 
1836  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
1837 }
1838 //*************************************************************************************************
1839 
1840 
1841 //*************************************************************************************************
1851 template< typename Type // Data type of the matrix
1852  , size_t M // Number of rows
1853  , size_t N // Number of columns
1854  , bool SO > // Storage order
1855 inline void* HybridMatrix<Type,M,N,SO>::operator new( std::size_t size, const std::nothrow_t& )
1856 {
1857  UNUSED_PARAMETER( size );
1858 
1859  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
1860 
1861  return allocate<HybridMatrix>( 1UL );
1862 }
1863 //*************************************************************************************************
1864 
1865 
1866 //*************************************************************************************************
1876 template< typename Type // Data type of the matrix
1877  , size_t M // Number of rows
1878  , size_t N // Number of columns
1879  , bool SO > // Storage order
1880 inline void* HybridMatrix<Type,M,N,SO>::operator new[]( std::size_t size, const std::nothrow_t& )
1881 {
1882  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
1883  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
1884 
1885  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
1886 }
1887 //*************************************************************************************************
1888 
1889 
1890 //*************************************************************************************************
1896 template< typename Type // Data type of the matrix
1897  , size_t M // Number of rows
1898  , size_t N // Number of columns
1899  , bool SO > // Storage order
1900 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr )
1901 {
1902  deallocate( static_cast<HybridMatrix*>( ptr ) );
1903 }
1904 //*************************************************************************************************
1905 
1906 
1907 //*************************************************************************************************
1913 template< typename Type // Data type of the matrix
1914  , size_t M // Number of rows
1915  , size_t N // Number of columns
1916  , bool SO > // Storage order
1917 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr )
1918 {
1919  deallocate( static_cast<HybridMatrix*>( ptr ) );
1920 }
1921 //*************************************************************************************************
1922 
1923 
1924 //*************************************************************************************************
1930 template< typename Type // Data type of the matrix
1931  , size_t M // Number of rows
1932  , size_t N // Number of columns
1933  , bool SO > // Storage order
1934 inline void HybridMatrix<Type,M,N,SO>::operator delete( void* ptr, const std::nothrow_t& )
1935 {
1936  deallocate( static_cast<HybridMatrix*>( ptr ) );
1937 }
1938 //*************************************************************************************************
1939 
1940 
1941 //*************************************************************************************************
1947 template< typename Type // Data type of the matrix
1948  , size_t M // Number of rows
1949  , size_t N // Number of columns
1950  , bool SO > // Storage order
1951 inline void HybridMatrix<Type,M,N,SO>::operator delete[]( void* ptr, const std::nothrow_t& )
1952 {
1953  deallocate( static_cast<HybridMatrix*>( ptr ) );
1954 }
1955 //*************************************************************************************************
1956 
1957 
1958 
1959 
1960 //=================================================================================================
1961 //
1962 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1963 //
1964 //=================================================================================================
1965 
1966 //*************************************************************************************************
1976 template< typename Type // Data type of the matrix
1977  , size_t M // Number of rows
1978  , size_t N // Number of columns
1979  , bool SO > // Storage order
1980 template< typename Other > // Data type of the foreign expression
1981 inline bool HybridMatrix<Type,M,N,SO>::canAlias( const Other* alias ) const
1982 {
1983  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1984 }
1985 //*************************************************************************************************
1986 
1987 
1988 //*************************************************************************************************
1998 template< typename Type // Data type of the matrix
1999  , size_t M // Number of rows
2000  , size_t N // Number of columns
2001  , bool SO > // Storage order
2002 template< typename Other > // Data type of the foreign expression
2003 inline bool HybridMatrix<Type,M,N,SO>::isAliased( const Other* alias ) const
2004 {
2005  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
2006 }
2007 //*************************************************************************************************
2008 
2009 
2010 //*************************************************************************************************
2019 template< typename Type // Data type of the matrix
2020  , size_t M // Number of rows
2021  , size_t N // Number of columns
2022  , bool SO > // Storage order
2024 {
2025  return true;
2026 }
2027 //*************************************************************************************************
2028 
2029 
2030 //*************************************************************************************************
2045 template< typename Type // Data type of the matrix
2046  , size_t M // Number of rows
2047  , size_t N // Number of columns
2048  , bool SO > // Storage order
2050  HybridMatrix<Type,M,N,SO>::load( size_t i, size_t j ) const
2051 {
2052  using blaze::load;
2053 
2055 
2056  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
2057  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
2058  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN , "Invalid column access index" );
2059  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2060 
2061  return load( &v_[i*NN+j] );
2062 }
2063 //*************************************************************************************************
2064 
2065 
2066 //*************************************************************************************************
2081 template< typename Type // Data type of the matrix
2082  , size_t M // Number of rows
2083  , size_t N // Number of columns
2084  , bool SO > // Storage order
2086  HybridMatrix<Type,M,N,SO>::loadu( size_t i, size_t j ) const
2087 {
2088  using blaze::loadu;
2089 
2091 
2092  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
2093  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
2094  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN , "Invalid column access index" );
2095 
2096  return loadu( &v_[i*NN+j] );
2097 }
2098 //*************************************************************************************************
2099 
2100 
2101 //*************************************************************************************************
2117 template< typename Type // Data type of the matrix
2118  , size_t M // Number of rows
2119  , size_t N // Number of columns
2120  , bool SO > // Storage order
2122  HybridMatrix<Type,M,N,SO>::store( size_t i, size_t j, const IntrinsicType& value )
2123 {
2124  using blaze::store;
2125 
2127 
2128  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
2129  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
2130  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN , "Invalid column access index" );
2131  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2132 
2133  store( &v_[i*NN+j], value );
2134 }
2135 //*************************************************************************************************
2136 
2137 
2138 //*************************************************************************************************
2154 template< typename Type // Data type of the matrix
2155  , size_t M // Number of rows
2156  , size_t N // Number of columns
2157  , bool SO > // Storage order
2159  HybridMatrix<Type,M,N,SO>::storeu( size_t i, size_t j, const IntrinsicType& value )
2160 {
2161  using blaze::storeu;
2162 
2164 
2165  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
2166  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
2167  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN, "Invalid column access index" );
2168 
2169  storeu( &v_[i*NN+j], value );
2170 }
2171 //*************************************************************************************************
2172 
2173 
2174 //*************************************************************************************************
2190 template< typename Type // Data type of the matrix
2191  , size_t M // Number of rows
2192  , size_t N // Number of columns
2193  , bool SO > // Storage order
2195  HybridMatrix<Type,M,N,SO>::stream( size_t i, size_t j, const IntrinsicType& value )
2196 {
2197  using blaze::stream;
2198 
2200 
2201  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
2202  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
2203  BLAZE_INTERNAL_ASSERT( j + IT::size <= NN , "Invalid column access index" );
2204  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
2205 
2206  stream( &v_[i*NN+j], value );
2207 }
2208 //*************************************************************************************************
2209 
2210 
2211 //*************************************************************************************************
2222 template< typename Type // Data type of the matrix
2223  , size_t M // Number of rows
2224  , size_t N // Number of columns
2225  , bool SO > // Storage order
2226 template< typename MT // Type of the right-hand side dense matrix
2227  , bool SO2 > // Storage order of the right-hand side dense matrix
2228 inline typename DisableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2230 {
2231  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2232 
2233  for( size_t i=0UL; i<m_; ++i ) {
2234  for( size_t j=0UL; j<n_; ++j ) {
2235  v_[i*NN+j] = (~rhs)(i,j);
2236  }
2237  }
2238 }
2239 //*************************************************************************************************
2240 
2241 
2242 //*************************************************************************************************
2253 template< typename Type // Data type of the matrix
2254  , size_t M // Number of rows
2255  , size_t N // Number of columns
2256  , bool SO > // Storage order
2257 template< typename MT // Type of the right-hand side dense matrix
2258  , bool SO2 > // Storage order of the right-hand side dense matrix
2259 inline typename EnableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
2261 {
2262  using blaze::store;
2263 
2265 
2266  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2267 
2268  for( size_t i=0UL; i<m_; ++i ) {
2269  for( size_t j=0UL; j<n_; j+=IT::size ) {
2270  store( &v_[i*NN+j], (~rhs).load(i,j) );
2271  }
2272  }
2273 }
2274 //*************************************************************************************************
2275 
2276 
2277 //*************************************************************************************************
2288 template< typename Type // Data type of the matrix
2289  , size_t M // Number of rows
2290  , size_t N // Number of columns
2291  , bool SO > // Storage order
2292 template< typename MT > // Type of the right-hand side sparse matrix
2294 {
2295  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2296 
2297  typedef typename MT::ConstIterator RhsConstIterator;
2298 
2299  for( size_t i=0UL; i<m_; ++i )
2300  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2301  v_[i*NN+element->index()] = element->value();
2302 }
2303 //*************************************************************************************************
2304 
2305 
2306 //*************************************************************************************************
2317 template< typename Type // Data type of the matrix
2318  , size_t M // Number of rows
2319  , size_t N // Number of columns
2320  , bool SO > // Storage order
2321 template< typename MT > // Type of the right-hand side sparse matrix
2323 {
2325 
2326  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2327 
2328  typedef typename MT::ConstIterator RhsConstIterator;
2329 
2330  for( size_t j=0UL; j<n_; ++j )
2331  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2332  v_[element->index()*NN+j] = element->value();
2333 }
2334 //*************************************************************************************************
2335 
2336 
2337 //*************************************************************************************************
2348 template< typename Type // Data type of the matrix
2349  , size_t M // Number of rows
2350  , size_t N // Number of columns
2351  , bool SO > // Storage order
2352 template< typename MT // Type of the right-hand side dense matrix
2353  , bool SO2 > // Storage order of the right-hand side dense matrix
2354 inline typename DisableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2356 {
2357  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2358 
2359  for( size_t i=0UL; i<m_; ++i )
2360  {
2361  if( IsDiagonal<MT>::value )
2362  {
2363  v_[i*NN+i] += (~rhs)(i,i);
2364  }
2365  else
2366  {
2367  const size_t jbegin( ( IsUpper<MT>::value )
2368  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2369  :( 0UL ) );
2370  const size_t jend ( ( IsLower<MT>::value )
2371  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2372  :( n_ ) );
2373  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2374 
2375  for( size_t j=jbegin; j<jend; ++j ) {
2376  v_[i*NN+j] += (~rhs)(i,j);
2377  }
2378  }
2379  }
2380 }
2381 //*************************************************************************************************
2382 
2383 
2384 //*************************************************************************************************
2395 template< typename Type // Data type of the matrix
2396  , size_t M // Number of rows
2397  , size_t N // Number of columns
2398  , bool SO > // Storage order
2399 template< typename MT // Type of the right-hand side dense matrix
2400  , bool SO2 > // Storage order of the right-hand side dense matrix
2401 inline typename EnableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
2403 {
2404  using blaze::load;
2405  using blaze::store;
2406 
2409 
2410  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2411 
2412  for( size_t i=0UL; i<m_; ++i )
2413  {
2414  const size_t jbegin( ( IsUpper<MT>::value )
2415  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-IT::size) )
2416  :( 0UL ) );
2417  const size_t jend ( ( IsLower<MT>::value )
2418  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2419  :( n_ ) );
2420  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2421 
2422  for( size_t j=jbegin; j<jend; j+=IT::size ) {
2423  store( &v_[i*NN+j], load( &v_[i*NN+j] ) + (~rhs).load(i,j) );
2424  }
2425  }
2426 }
2427 //*************************************************************************************************
2428 
2429 
2430 //*************************************************************************************************
2441 template< typename Type // Data type of the matrix
2442  , size_t M // Number of rows
2443  , size_t N // Number of columns
2444  , bool SO > // Storage order
2445 template< typename MT > // Type of the right-hand side sparse matrix
2447 {
2448  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2449 
2450  typedef typename MT::ConstIterator RhsConstIterator;
2451 
2452  for( size_t i=0UL; i<m_; ++i )
2453  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2454  v_[i*NN+element->index()] += element->value();
2455 }
2456 //*************************************************************************************************
2457 
2458 
2459 //*************************************************************************************************
2470 template< typename Type // Data type of the matrix
2471  , size_t M // Number of rows
2472  , size_t N // Number of columns
2473  , bool SO > // Storage order
2474 template< typename MT > // Type of the right-hand side sparse matrix
2476 {
2478 
2479  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2480 
2481  typedef typename MT::ConstIterator RhsConstIterator;
2482 
2483  for( size_t j=0UL; j<n_; ++j )
2484  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2485  v_[element->index()*NN+j] += element->value();
2486 }
2487 //*************************************************************************************************
2488 
2489 
2490 //*************************************************************************************************
2501 template< typename Type // Data type of the matrix
2502  , size_t M // Number of rows
2503  , size_t N // Number of columns
2504  , bool SO > // Storage order
2505 template< typename MT // Type of the right-hand side dense matrix
2506  , bool SO2 > // Storage order of the right-hand side dense matrix
2507 inline typename DisableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2509 {
2510  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2511 
2512  for( size_t i=0UL; i<m_; ++i )
2513  {
2514  if( IsDiagonal<MT>::value )
2515  {
2516  v_[i*NN+i] -= (~rhs)(i,i);
2517  }
2518  else
2519  {
2520  const size_t jbegin( ( IsUpper<MT>::value )
2521  ?( IsStrictlyUpper<MT>::value ? i+1UL : i )
2522  :( 0UL ) );
2523  const size_t jend ( ( IsLower<MT>::value )
2524  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2525  :( n_ ) );
2526  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2527 
2528  for( size_t j=jbegin; j<jend; ++j ) {
2529  v_[i*NN+j] -= (~rhs)(i,j);
2530  }
2531  }
2532  }
2533 }
2534 //*************************************************************************************************
2535 
2536 
2537 //*************************************************************************************************
2548 template< typename Type // Data type of the matrix
2549  , size_t M // Number of rows
2550  , size_t N // Number of columns
2551  , bool SO > // Storage order
2552 template< typename MT // Type of the right-hand side dense matrix
2553  , bool SO2 > // Storage order of the right-hand side dense matrix
2554 inline typename EnableIf< typename HybridMatrix<Type,M,N,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2556 {
2557  using blaze::load;
2558  using blaze::store;
2559 
2562 
2563  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2564 
2565  for( size_t i=0UL; i<m_; ++i )
2566  {
2567  const size_t jbegin( ( IsUpper<MT>::value )
2568  ?( ( IsStrictlyUpper<MT>::value ? i+1UL : i ) & size_t(-IT::size) )
2569  :( 0UL ) );
2570  const size_t jend ( ( IsLower<MT>::value )
2571  ?( IsStrictlyLower<MT>::value ? i : i+1UL )
2572  :( n_ ) );
2573  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2574 
2575  for( size_t j=jbegin; j<jend; j+=IT::size ) {
2576  store( &v_[i*NN+j], load( &v_[i*NN+j] ) - (~rhs).load(i,j) );
2577  }
2578  }
2579 }
2580 //*************************************************************************************************
2581 
2582 
2583 //*************************************************************************************************
2594 template< typename Type // Data type of the matrix
2595  , size_t M // Number of rows
2596  , size_t N // Number of columns
2597  , bool SO > // Storage order
2598 template< typename MT > // Type of the right-hand side sparse matrix
2600 {
2601  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2602 
2603  typedef typename MT::ConstIterator RhsConstIterator;
2604 
2605  for( size_t i=0UL; i<m_; ++i )
2606  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2607  v_[i*NN+element->index()] -= element->value();
2608 }
2609 //*************************************************************************************************
2610 
2611 
2612 //*************************************************************************************************
2623 template< typename Type // Data type of the matrix
2624  , size_t M // Number of rows
2625  , size_t N // Number of columns
2626  , bool SO > // Storage order
2627 template< typename MT > // Type of the right-hand side sparse matrix
2629 {
2631 
2632  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
2633 
2634  typedef typename MT::ConstIterator RhsConstIterator;
2635 
2636  for( size_t j=0UL; j<n_; ++j )
2637  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2638  v_[element->index()*NN+j] -= element->value();
2639 }
2640 //*************************************************************************************************
2641 
2642 
2643 
2644 
2645 
2646 
2647 
2648 
2649 //=================================================================================================
2650 //
2651 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2652 //
2653 //=================================================================================================
2654 
2655 //*************************************************************************************************
2663 template< typename Type // Data type of the matrix
2664  , size_t M // Number of rows
2665  , size_t N > // Number of columns
2666 class HybridMatrix<Type,M,N,true> : public DenseMatrix< HybridMatrix<Type,M,N,true>, true >
2667 {
2668  private:
2669  //**Type definitions****************************************************************************
2670  typedef IntrinsicTrait<Type> IT;
2671  //**********************************************************************************************
2672 
2673  //**********************************************************************************************
2675  enum { MM = M + ( IT::size - ( M % IT::size ) ) % IT::size };
2676  //**********************************************************************************************
2677 
2678  public:
2679  //**Type definitions****************************************************************************
2680  typedef HybridMatrix<Type,M,N,true> This;
2681  typedef This ResultType;
2682  typedef HybridMatrix<Type,M,N,false> OppositeType;
2683  typedef HybridMatrix<Type,N,M,false> TransposeType;
2684  typedef Type ElementType;
2685  typedef typename IT::Type IntrinsicType;
2686  typedef const Type& ReturnType;
2687  typedef const This& CompositeType;
2688  typedef Type& Reference;
2689  typedef const Type& ConstReference;
2690  typedef Type* Pointer;
2691  typedef const Type* ConstPointer;
2692  typedef DenseIterator<Type> Iterator;
2693  typedef DenseIterator<const Type> ConstIterator;
2694  //**********************************************************************************************
2695 
2696  //**Rebind struct definition********************************************************************
2699  template< typename ET > // Data type of the other matrix
2700  struct Rebind {
2701  typedef HybridMatrix<ET,M,N,true> Other;
2702  };
2703  //**********************************************************************************************
2704 
2705  //**Compilation flags***************************************************************************
2707 
2711  enum { vectorizable = IsVectorizable<Type>::value };
2712 
2714 
2717  enum { smpAssignable = 0 };
2718  //**********************************************************************************************
2719 
2720  //**Constructors********************************************************************************
2723  explicit inline HybridMatrix();
2724  explicit inline HybridMatrix( size_t m, size_t n );
2725  explicit inline HybridMatrix( size_t m, size_t n, const Type& init );
2726  template< typename Other > explicit inline HybridMatrix( size_t m, size_t n, const Other* array );
2727 
2728  template< typename Other, size_t M2, size_t N2 >
2729  explicit inline HybridMatrix( const Other (&array)[M2][N2] );
2730 
2731  inline HybridMatrix( const HybridMatrix& m );
2732  template< typename MT, bool SO > inline HybridMatrix( const Matrix<MT,SO>& m );
2734  //**********************************************************************************************
2735 
2736  //**Destructor**********************************************************************************
2737  // No explicitly declared destructor.
2738  //**********************************************************************************************
2739 
2740  //**Data access functions***********************************************************************
2743  inline Reference operator()( size_t i, size_t j );
2744  inline ConstReference operator()( size_t i, size_t j ) const;
2745  inline Pointer data ();
2746  inline ConstPointer data () const;
2747  inline Pointer data ( size_t j );
2748  inline ConstPointer data ( size_t j ) const;
2749  inline Iterator begin ( size_t j );
2750  inline ConstIterator begin ( size_t j ) const;
2751  inline ConstIterator cbegin( size_t j ) const;
2752  inline Iterator end ( size_t j );
2753  inline ConstIterator end ( size_t j ) const;
2754  inline ConstIterator cend ( size_t j ) const;
2756  //**********************************************************************************************
2757 
2758  //**Assignment operators************************************************************************
2761  template< typename Other, size_t M2, size_t N2 >
2762  inline HybridMatrix& operator=( const Other (&array)[M2][N2] );
2763 
2764  inline HybridMatrix& operator= ( const Type& set );
2765  inline HybridMatrix& operator= ( const HybridMatrix& rhs );
2766  template< typename MT, bool SO > inline HybridMatrix& operator= ( const Matrix<MT,SO>& rhs );
2767  template< typename MT, bool SO > inline HybridMatrix& operator+=( const Matrix<MT,SO>& rhs );
2768  template< typename MT, bool SO > inline HybridMatrix& operator-=( const Matrix<MT,SO>& rhs );
2769  template< typename MT, bool SO > inline HybridMatrix& operator*=( const Matrix<MT,SO>& rhs );
2770 
2771  template< typename Other >
2772  inline typename EnableIf< IsNumeric<Other>, HybridMatrix >::Type&
2773  operator*=( Other rhs );
2774 
2775  template< typename Other >
2776  inline typename EnableIf< IsNumeric<Other>, HybridMatrix >::Type&
2777  operator/=( Other rhs );
2779  //**********************************************************************************************
2780 
2781  //**Utility functions***************************************************************************
2784  inline size_t rows() const;
2785  inline size_t columns() const;
2786  inline size_t spacing() const;
2787  inline size_t capacity() const;
2788  inline size_t capacity( size_t j ) const;
2789  inline size_t nonZeros() const;
2790  inline size_t nonZeros( size_t j ) const;
2791  inline void reset();
2792  inline void reset( size_t i );
2793  inline void clear();
2794  void resize ( size_t m, size_t n, bool preserve=true );
2795  inline void extend ( size_t m, size_t n, bool preserve=true );
2796  inline HybridMatrix& transpose();
2797  template< typename Other > inline HybridMatrix& scale( const Other& scalar );
2798  inline void swap( HybridMatrix& m ) /* throw() */;
2800  //**********************************************************************************************
2801 
2802  //**Memory functions****************************************************************************
2805  static inline void* operator new ( std::size_t size );
2806  static inline void* operator new[]( std::size_t size );
2807  static inline void* operator new ( std::size_t size, const std::nothrow_t& );
2808  static inline void* operator new[]( std::size_t size, const std::nothrow_t& );
2809 
2810  static inline void operator delete ( void* ptr );
2811  static inline void operator delete[]( void* ptr );
2812  static inline void operator delete ( void* ptr, const std::nothrow_t& );
2813  static inline void operator delete[]( void* ptr, const std::nothrow_t& );
2815  //**********************************************************************************************
2816 
2817  private:
2818  //**********************************************************************************************
2820  template< typename MT >
2821  struct VectorizedAssign {
2822  enum { value = vectorizable && MT::vectorizable &&
2823  IsSame<Type,typename MT::ElementType>::value &&
2824  IsColumnMajorMatrix<MT>::value };
2825  };
2826  //**********************************************************************************************
2827 
2828  //**********************************************************************************************
2830  template< typename MT >
2831  struct VectorizedAddAssign {
2832  enum { value = vectorizable && MT::vectorizable &&
2833  IsSame<Type,typename MT::ElementType>::value &&
2834  IntrinsicTrait<Type>::addition &&
2835  IsColumnMajorMatrix<MT>::value &&
2836  !IsDiagonal<MT>::value };
2837  };
2838  //**********************************************************************************************
2839 
2840  //**********************************************************************************************
2842  template< typename MT >
2843  struct VectorizedSubAssign {
2844  enum { value = vectorizable && MT::vectorizable &&
2845  IsSame<Type,typename MT::ElementType>::value &&
2846  IntrinsicTrait<Type>::subtraction &&
2847  IsColumnMajorMatrix<MT>::value &&
2848  !IsDiagonal<MT>::value };
2849  };
2850  //**********************************************************************************************
2851 
2852  public:
2853  //**Expression template evaluation functions****************************************************
2856  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2857  template< typename Other > inline bool isAliased( const Other* alias ) const;
2858 
2859  inline bool isAligned() const;
2860 
2861  BLAZE_ALWAYS_INLINE IntrinsicType load ( size_t i, size_t j ) const;
2862  BLAZE_ALWAYS_INLINE IntrinsicType loadu( size_t i, size_t j ) const;
2863 
2864  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const IntrinsicType& value );
2865  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const IntrinsicType& value );
2866  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const IntrinsicType& value );
2867 
2868  template< typename MT, bool SO >
2869  inline typename DisableIf< VectorizedAssign<MT> >::Type
2870  assign( const DenseMatrix<MT,SO>& rhs );
2871 
2872  template< typename MT, bool SO >
2873  inline typename EnableIf< VectorizedAssign<MT> >::Type
2874  assign( const DenseMatrix<MT,SO>& rhs );
2875 
2876  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
2877  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
2878 
2879  template< typename MT, bool SO >
2880  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
2881  addAssign( const DenseMatrix<MT,SO>& rhs );
2882 
2883  template< typename MT, bool SO >
2884  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
2885  addAssign( const DenseMatrix<MT,SO>& rhs );
2886 
2887  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
2888  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
2889 
2890  template< typename MT, bool SO >
2891  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
2892  subAssign( const DenseMatrix<MT,SO>& rhs );
2893 
2894  template< typename MT, bool SO >
2895  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
2896  subAssign( const DenseMatrix<MT,SO>& rhs );
2897 
2898  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
2899  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
2901  //**********************************************************************************************
2902 
2903  private:
2904  //**Member variables****************************************************************************
2907  AlignedArray<Type,MM*N> v_;
2908 
2910  size_t m_;
2911  size_t n_;
2912 
2913  //**********************************************************************************************
2914 
2915  //**Compile time checks*************************************************************************
2920  BLAZE_STATIC_ASSERT( MM % IT::size == 0UL );
2921  BLAZE_STATIC_ASSERT( MM >= M );
2922  //**********************************************************************************************
2923 };
2925 //*************************************************************************************************
2926 
2927 
2928 
2929 
2930 //=================================================================================================
2931 //
2932 // CONSTRUCTORS
2933 //
2934 //=================================================================================================
2935 
2936 //*************************************************************************************************
2942 template< typename Type // Data type of the matrix
2943  , size_t M // Number of rows
2944  , size_t N > // Number of columns
2946  : v_() // The statically allocated matrix elements
2947  , m_( 0UL ) // The current number of rows of the matrix
2948  , n_( 0UL ) // The current number of columns of the matrix
2949 {
2950  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
2951 
2952  if( IsNumeric<Type>::value ) {
2953  for( size_t i=0UL; i<MM*N; ++i )
2954  v_[i] = Type();
2955  }
2956 }
2958 //*************************************************************************************************
2959 
2960 
2961 //*************************************************************************************************
2975 template< typename Type // Data type of the matrix
2976  , size_t M // Number of rows
2977  , size_t N > // Number of columns
2978 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n )
2979  : v_() // The statically allocated matrix elements
2980  , m_( m ) // The current number of rows of the matrix
2981  , n_( n ) // The current number of columns of the matrix
2982 {
2983  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
2984 
2985  if( m > M )
2986  throw std::invalid_argument( "Invalid number of rows for hybrid matrix" );
2987 
2988  if( n > N )
2989  throw std::invalid_argument( "Invalid number of columns for hybrid matrix" );
2990 
2991  if( IsNumeric<Type>::value ) {
2992  for( size_t i=0UL; i<MM*N; ++i )
2993  v_[i] = Type();
2994  }
2995 }
2997 //*************************************************************************************************
2998 
2999 
3000 //*************************************************************************************************
3015 template< typename Type // Data type of the matrix
3016  , size_t M // Number of rows
3017  , size_t N > // Number of columns
3018 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Type& init )
3019  : v_() // The statically allocated matrix elements
3020  , m_( m ) // The current number of rows of the matrix
3021  , n_( n ) // The current number of columns of the matrix
3022 {
3023  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3024 
3025  if( m > M )
3026  throw std::invalid_argument( "Invalid number of rows for hybrid matrix" );
3027 
3028  if( n > N )
3029  throw std::invalid_argument( "Invalid number of columns for hybrid matrix" );
3030 
3031  for( size_t j=0UL; j<n; ++j ) {
3032  for( size_t i=0UL; i<m; ++i )
3033  v_[i+j*MM] = init;
3034 
3035  if( IsNumeric<Type>::value ) {
3036  for( size_t i=m; i<MM; ++i )
3037  v_[i+j*MM] = Type();
3038  }
3039  }
3040 
3041  if( IsNumeric<Type>::value ) {
3042  for( size_t j=n; j<N; ++j )
3043  for( size_t i=0UL; i<MM; ++i )
3044  v_[i+j*MM] = Type();
3045  }
3046 }
3048 //*************************************************************************************************
3049 
3050 
3051 //*************************************************************************************************
3079 template< typename Type // Data type of the matrix
3080  , size_t M // Number of rows
3081  , size_t N > // Number of columns
3082 template< typename Other > // Data type of the initialization array
3083 inline HybridMatrix<Type,M,N,true>::HybridMatrix( size_t m, size_t n, const Other* array )
3084  : v_() // The statically allocated matrix elements
3085  , m_( m ) // The current number of rows of the matrix
3086  , n_( n ) // The current number of columns of the matrix
3087 {
3088  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3089 
3090  if( m > M )
3091  throw std::invalid_argument( "Invalid number of rows for hybrid matrix" );
3092 
3093  if( n > N )
3094  throw std::invalid_argument( "Invalid number of columns for hybrid matrix" );
3095 
3096  for( size_t j=0UL; j<n; ++j ) {
3097  for( size_t i=0UL; i<m; ++i )
3098  v_[i+j*MM] = array[i+j*m];
3099 
3100  if( IsNumeric<Type>::value ) {
3101  for( size_t i=m; i<MM; ++i )
3102  v_[i+j*MM] = Type();
3103  }
3104  }
3105 
3106  if( IsNumeric<Type>::value ) {
3107  for( size_t j=n; j<N; ++j )
3108  for( size_t i=0UL; i<MM; ++i )
3109  v_[i+j*MM] = Type();
3110  }
3111 }
3113 //*************************************************************************************************
3114 
3115 
3116 //*************************************************************************************************
3138 template< typename Type // Data type of the matrix
3139  , size_t M // Number of rows
3140  , size_t N > // Number of columns
3141 template< typename Other // Data type of the initialization array
3142  , size_t M2 // Number of rows of the initialization array
3143  , size_t N2 > // Number of columns of the initialization array
3144 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const Other (&array)[M2][N2] )
3145  : v_() // The statically allocated matrix elements
3146  , m_( M2 ) // The current number of rows of the matrix
3147  , n_( N2 ) // The current number of columns of the matrix
3148 {
3149  BLAZE_STATIC_ASSERT( M2 <= M );
3150  BLAZE_STATIC_ASSERT( N2 <= N );
3151  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3152 
3153  for( size_t j=0UL; j<N2; ++j ) {
3154  for( size_t i=0UL; i<M2; ++i )
3155  v_[i+j*MM] = array[i][j];
3156 
3157  if( IsNumeric<Type>::value ) {
3158  for( size_t i=M2; i<MM; ++i )
3159  v_[i+j*MM] = Type();
3160  }
3161  }
3162 
3163  if( IsNumeric<Type>::value ) {
3164  for( size_t j=N2; j<N; ++j )
3165  for( size_t i=0UL; i<MM; ++i )
3166  v_[i+j*MM] = Type();
3167  }
3168 }
3170 //*************************************************************************************************
3171 
3172 
3173 //*************************************************************************************************
3182 template< typename Type // Data type of the matrix
3183  , size_t M // Number of rows
3184  , size_t N > // Number of columns
3185 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const HybridMatrix& m )
3186  : v_() // The statically allocated matrix elements
3187  , m_( m.m_ ) // The current number of rows of the matrix
3188  , n_( m.n_ ) // The current number of columns of the matrix
3189 {
3190  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3191 
3192  for( size_t j=0UL; j<n_; ++j ) {
3193  for( size_t i=0UL; i<m_; ++i )
3194  v_[i+j*MM] = m.v_[i+j*MM];
3195 
3196  if( IsNumeric<Type>::value ) {
3197  for( size_t i=m_; i<MM; ++i )
3198  v_[i+j*MM] = Type();
3199  }
3200  }
3201 
3202  if( IsNumeric<Type>::value ) {
3203  for( size_t j=n_; j<N; ++j )
3204  for( size_t i=0UL; i<MM; ++i )
3205  v_[i+j*MM] = Type();
3206  }
3207 }
3209 //*************************************************************************************************
3210 
3211 
3212 //*************************************************************************************************
3219 template< typename Type // Data type of the matrix
3220  , size_t M // Number of rows
3221  , size_t N > // Number of columns
3222 template< typename MT // Type of the foreign matrix
3223  , bool SO2 > // Storage order of the foreign matrix
3224 inline HybridMatrix<Type,M,N,true>::HybridMatrix( const Matrix<MT,SO2>& m )
3225  : v_() // The statically allocated matrix elements
3226  , m_( (~m).rows() ) // The current number of rows of the matrix
3227  , n_( (~m).columns() ) // The current number of columns of the matrix
3228 {
3229  using blaze::assign;
3230 
3231  BLAZE_STATIC_ASSERT( IsVectorizable<Type>::value || MM == M );
3232 
3233  if( (~m).rows() > M || (~m).columns() > N )
3234  throw std::invalid_argument( "Invalid setup of hybrid matrix" );
3235 
3236  for( size_t j=0UL; j<n_; ++j ) {
3237  for( size_t i=( IsSparseMatrix<MT>::value ? 0UL : m_ );
3238  i<( IsNumeric<Type>::value ? MM : m_ );
3239  ++i ) {
3240  v_[i+j*MM] = Type();
3241  }
3242  }
3243 
3244  if( IsNumeric<Type>::value ) {
3245  for( size_t j=n_; j<N; ++j )
3246  for( size_t i=0UL; i<MM; ++i )
3247  v_[i+j*MM] = Type();
3248  }
3249 
3250  assign( *this, ~m );
3251 }
3253 //*************************************************************************************************
3254 
3255 
3256 
3257 
3258 //=================================================================================================
3259 //
3260 // DATA ACCESS FUNCTIONS
3261 //
3262 //=================================================================================================
3263 
3264 //*************************************************************************************************
3272 template< typename Type // Data type of the matrix
3273  , size_t M // Number of rows
3274  , size_t N > // Number of columns
3276  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j )
3277 {
3278  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3279  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3280  return v_[i+j*MM];
3281 }
3283 //*************************************************************************************************
3284 
3285 
3286 //*************************************************************************************************
3294 template< typename Type // Data type of the matrix
3295  , size_t M // Number of rows
3296  , size_t N > // Number of columns
3298  HybridMatrix<Type,M,N,true>::operator()( size_t i, size_t j ) const
3299 {
3300  BLAZE_USER_ASSERT( i<M, "Invalid row access index" );
3301  BLAZE_USER_ASSERT( j<N, "Invalid column access index" );
3302  return v_[i+j*MM];
3303 }
3305 //*************************************************************************************************
3306 
3307 
3308 //*************************************************************************************************
3320 template< typename Type // Data type of the matrix
3321  , size_t M // Number of rows
3322  , size_t N > // Number of columns
3323 inline typename HybridMatrix<Type,M,N,true>::Pointer
3325 {
3326  return v_;
3327 }
3329 //*************************************************************************************************
3330 
3331 
3332 //*************************************************************************************************
3344 template< typename Type // Data type of the matrix
3345  , size_t M // Number of rows
3346  , size_t N > // Number of columns
3347 inline typename HybridMatrix<Type,M,N,true>::ConstPointer
3349 {
3350  return v_;
3351 }
3353 //*************************************************************************************************
3354 
3355 
3356 //*************************************************************************************************
3365 template< typename Type // Data type of the matrix
3366  , size_t M // Number of rows
3367  , size_t N > // Number of columns
3368 inline typename HybridMatrix<Type,M,N,true>::Pointer
3370 {
3371  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3372  return v_ + j*MM;
3373 }
3375 //*************************************************************************************************
3376 
3377 
3378 //*************************************************************************************************
3387 template< typename Type // Data type of the matrix
3388  , size_t M // Number of rows
3389  , size_t N > // Number of columns
3390 inline typename HybridMatrix<Type,M,N,true>::ConstPointer
3391  HybridMatrix<Type,M,N,true>::data( size_t j ) const
3392 {
3393  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3394  return v_ + j*MM;
3395 }
3397 //*************************************************************************************************
3398 
3399 
3400 //*************************************************************************************************
3407 template< typename Type // Data type of the matrix
3408  , size_t M // Number of rows
3409  , size_t N > // Number of columns
3412 {
3413  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3414  return Iterator( v_ + j*MM );
3415 }
3417 //*************************************************************************************************
3418 
3419 
3420 //*************************************************************************************************
3427 template< typename Type // Data type of the matrix
3428  , size_t M // Number of rows
3429  , size_t N > // Number of columns
3431  HybridMatrix<Type,M,N,true>::begin( size_t j ) const
3432 {
3433  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3434  return ConstIterator( v_ + j*MM );
3435 }
3437 //*************************************************************************************************
3438 
3439 
3440 //*************************************************************************************************
3447 template< typename Type // Data type of the matrix
3448  , size_t M // Number of rows
3449  , size_t N > // Number of columns
3451  HybridMatrix<Type,M,N,true>::cbegin( size_t j ) const
3452 {
3453  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3454  return ConstIterator( v_ + j*MM );
3455 }
3457 //*************************************************************************************************
3458 
3459 
3460 //*************************************************************************************************
3467 template< typename Type // Data type of the matrix
3468  , size_t M // Number of rows
3469  , size_t N > // Number of columns
3472 {
3473  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3474  return Iterator( v_ + j*MM + M );
3475 }
3477 //*************************************************************************************************
3478 
3479 
3480 //*************************************************************************************************
3487 template< typename Type // Data type of the matrix
3488  , size_t M // Number of rows
3489  , size_t N > // Number of columns
3491  HybridMatrix<Type,M,N,true>::end( size_t j ) const
3492 {
3493  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3494  return ConstIterator( v_ + j*MM + M );
3495 }
3497 //*************************************************************************************************
3498 
3499 
3500 //*************************************************************************************************
3507 template< typename Type // Data type of the matrix
3508  , size_t M // Number of rows
3509  , size_t N > // Number of columns
3511  HybridMatrix<Type,M,N,true>::cend( size_t j ) const
3512 {
3513  BLAZE_USER_ASSERT( j < N, "Invalid dense matrix column access index" );
3514  return ConstIterator( v_ + j*MM + M );
3515 }
3517 //*************************************************************************************************
3518 
3519 
3520 
3521 
3522 //=================================================================================================
3523 //
3524 // ASSIGNMENT OPERATORS
3525 //
3526 //=================================================================================================
3527 
3528 //*************************************************************************************************
3550 template< typename Type // Data type of the matrix
3551  , size_t M // Number of rows
3552  , size_t N > // Number of columns
3553 template< typename Other // Data type of the initialization array
3554  , size_t M2 // Number of rows of the initialization array
3555  , size_t N2 > // Number of columns of the initialization array
3556 inline HybridMatrix<Type,M,N,true>&
3557  HybridMatrix<Type,M,N,true>::operator=( const Other (&array)[M2][N2] )
3558 {
3559  BLAZE_STATIC_ASSERT( M2 <= M );
3560  BLAZE_STATIC_ASSERT( N2 <= N );
3561 
3562  resize( M2, N2 );
3563 
3564  for( size_t j=0UL; j<N2; ++j )
3565  for( size_t i=0UL; i<M2; ++i )
3566  v_[i+j*MM] = array[i][j];
3567 
3568  return *this;
3569 }
3571 //*************************************************************************************************
3572 
3573 
3574 //*************************************************************************************************
3581 template< typename Type // Data type of the matrix
3582  , size_t M // Number of rows
3583  , size_t N > // Number of columns
3584 inline HybridMatrix<Type,M,N,true>&
3585  HybridMatrix<Type,M,N,true>::operator=( const Type& set )
3586 {
3587  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
3588  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
3589 
3590  for( size_t j=0UL; j<n_; ++j )
3591  for( size_t i=0UL; i<m_; ++i )
3592  v_[i+j*MM] = set;
3593 
3594  return *this;
3595 }
3597 //*************************************************************************************************
3598 
3599 
3600 //*************************************************************************************************
3609 template< typename Type // Data type of the matrix
3610  , size_t M // Number of rows
3611  , size_t N > // Number of columns
3612 inline HybridMatrix<Type,M,N,true>&
3613  HybridMatrix<Type,M,N,true>::operator=( const HybridMatrix& rhs )
3614 {
3615  using blaze::assign;
3616 
3617  BLAZE_INTERNAL_ASSERT( m_ <= M, "Invalid number of rows detected" );
3618  BLAZE_INTERNAL_ASSERT( n_ <= N, "Invalid number of columns detected" );
3619 
3620  resize( rhs.rows(), rhs.columns() );
3621  assign( *this, ~rhs );
3622 
3623  return *this;
3624 }
3626 //*************************************************************************************************
3627 
3628 
3629 //*************************************************************************************************
3641 template< typename Type // Data type of the matrix
3642  , size_t M // Number of rows
3643  , size_t N > // Number of columns
3644 template< typename MT // Type of the right-hand side matrix
3645  , bool SO > // Storage order of the right-hand side matrix
3646 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator=( const Matrix<MT,SO>& rhs )
3647 {
3648  using blaze::assign;
3649 
3650  if( (~rhs).rows() > M || (~rhs).columns() > N )
3651  throw std::invalid_argument( "Invalid assignment to hybrid matrix" );
3652 
3653  if( (~rhs).canAlias( this ) ) {
3654  HybridMatrix tmp( ~rhs );
3655  swap( tmp );
3656  }
3657  else {
3658  resize( (~rhs).rows(), (~rhs).columns() );
3659  if( IsSparseMatrix<MT>::value )
3660  reset();
3661  assign( *this, ~rhs );
3662  }
3663 
3664  return *this;
3665 }
3667 //*************************************************************************************************
3668 
3669 
3670 //*************************************************************************************************
3681 template< typename Type // Data type of the matrix
3682  , size_t M // Number of rows
3683  , size_t N > // Number of columns
3684 template< typename MT // Type of the right-hand side matrix
3685  , bool SO > // Storage order of the right-hand side matrix
3686 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator+=( const Matrix<MT,SO>& rhs )
3687 {
3688  using blaze::addAssign;
3689 
3690  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3691  throw std::invalid_argument( "Matrix sizes do not match" );
3692 
3693  if( (~rhs).canAlias( this ) ) {
3694  typename MT::ResultType tmp( ~rhs );
3695  addAssign( *this, tmp );
3696  }
3697  else {
3698  addAssign( *this, ~rhs );
3699  }
3700 
3701  return *this;
3702 }
3704 //*************************************************************************************************
3705 
3706 
3707 //*************************************************************************************************
3718 template< typename Type // Data type of the matrix
3719  , size_t M // Number of rows
3720  , size_t N > // Number of columns
3721 template< typename MT // Type of the right-hand side matrix
3722  , bool SO > // Storage order of the right-hand side matrix
3723 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator-=( const Matrix<MT,SO>& rhs )
3724 {
3725  using blaze::subAssign;
3726 
3727  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3728  throw std::invalid_argument( "Matrix sizes do not match" );
3729 
3730  if( (~rhs).canAlias( this ) ) {
3731  typename MT::ResultType tmp( ~rhs );
3732  subAssign( *this, tmp );
3733  }
3734  else {
3735  subAssign( *this, ~rhs );
3736  }
3737 
3738  return *this;
3739 }
3741 //*************************************************************************************************
3742 
3743 
3744 //*************************************************************************************************
3755 template< typename Type // Data type of the matrix
3756  , size_t M // Number of rows
3757  , size_t N > // Number of columns
3758 template< typename MT // Type of the right-hand side matrix
3759  , bool SO > // Storage order of the right-hand side matrix
3760 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::operator*=( const Matrix<MT,SO>& rhs )
3761 {
3762  if( n_ != (~rhs).rows() || (~rhs).columns() > N )
3763  throw std::invalid_argument( "Matrix sizes do not match" );
3764 
3765  HybridMatrix tmp( *this * (~rhs) );
3766  return this->operator=( tmp );
3767 }
3769 //*************************************************************************************************
3770 
3771 
3772 //*************************************************************************************************
3780 template< typename Type // Data type of the matrix
3781  , size_t M // Number of rows
3782  , size_t N > // Number of columns
3783 template< typename Other > // Data type of the right-hand side scalar
3784 inline typename EnableIf< IsNumeric<Other>, HybridMatrix<Type,M,N,true> >::Type&
3785  HybridMatrix<Type,M,N,true>::operator*=( Other rhs )
3786 {
3787  using blaze::assign;
3788 
3789  assign( *this, (*this) * rhs );
3790  return *this;
3791 }
3793 //*************************************************************************************************
3794 
3795 
3796 //*************************************************************************************************
3806 template< typename Type // Data type of the matrix
3807  , size_t M // Number of rows
3808  , size_t N > // Number of columns
3809 template< typename Other > // Data type of the right-hand side scalar
3810 inline typename EnableIf< IsNumeric<Other>, HybridMatrix<Type,M,N,true> >::Type&
3811  HybridMatrix<Type,M,N,true>::operator/=( Other rhs )
3812 {
3813  using blaze::assign;
3814 
3815  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3816 
3817  assign( *this, (*this) / rhs );
3818  return *this;
3819 }
3821 //*************************************************************************************************
3822 
3823 
3824 
3825 
3826 //=================================================================================================
3827 //
3828 // UTILITY FUNCTIONS
3829 //
3830 //=================================================================================================
3831 
3832 //*************************************************************************************************
3838 template< typename Type // Data type of the matrix
3839  , size_t M // Number of rows
3840  , size_t N > // Number of columns
3841 inline size_t HybridMatrix<Type,M,N,true>::rows() const
3842 {
3843  return m_;
3844 }
3846 //*************************************************************************************************
3847 
3848 
3849 //*************************************************************************************************
3855 template< typename Type // Data type of the matrix
3856  , size_t M // Number of rows
3857  , size_t N > // Number of columns
3858 inline size_t HybridMatrix<Type,M,N,true>::columns() const
3859 {
3860  return n_;
3861 }
3863 //*************************************************************************************************
3864 
3865 
3866 //*************************************************************************************************
3875 template< typename Type // Data type of the matrix
3876  , size_t M // Number of rows
3877  , size_t N > // Number of columns
3878 inline size_t HybridMatrix<Type,M,N,true>::spacing() const
3879 {
3880  return MM;
3881 }
3883 //*************************************************************************************************
3884 
3885 
3886 //*************************************************************************************************
3892 template< typename Type // Data type of the matrix
3893  , size_t M // Number of rows
3894  , size_t N > // Number of columns
3895 inline size_t HybridMatrix<Type,M,N,true>::capacity() const
3896 {
3897  return MM*N;
3898 }
3900 //*************************************************************************************************
3901 
3902 
3903 //*************************************************************************************************
3910 template< typename Type // Data type of the matrix
3911  , size_t M // Number of rows
3912  , size_t N > // Number of columns
3913 inline size_t HybridMatrix<Type,M,N,true>::capacity( size_t j ) const
3914 {
3915  UNUSED_PARAMETER( j );
3916 
3917  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3918 
3919  return MM;
3920 }
3922 //*************************************************************************************************
3923 
3924 
3925 //*************************************************************************************************
3931 template< typename Type // Data type of the matrix
3932  , size_t M // Number of rows
3933  , size_t N > // Number of columns
3934 inline size_t HybridMatrix<Type,M,N,true>::nonZeros() const
3935 {
3936  size_t nonzeros( 0UL );
3937 
3938  for( size_t j=0UL; j<n_; ++j )
3939  for( size_t i=0UL; i<m_; ++i )
3940  if( !isDefault( v_[i+j*MM] ) )
3941  ++nonzeros;
3942 
3943  return nonzeros;
3944 }
3946 //*************************************************************************************************
3947 
3948 
3949 //*************************************************************************************************
3956 template< typename Type // Data type of the matrix
3957  , size_t M // Number of rows
3958  , size_t N > // Number of columns
3959 inline size_t HybridMatrix<Type,M,N,true>::nonZeros( size_t j ) const
3960 {
3961  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3962 
3963  const size_t iend( j*MM+m_ );
3964  size_t nonzeros( 0UL );
3965 
3966  for( size_t i=j*MM; i<iend; ++i )
3967  if( !isDefault( v_[i] ) )
3968  ++nonzeros;
3969 
3970  return nonzeros;
3971 }
3973 //*************************************************************************************************
3974 
3975 
3976 //*************************************************************************************************
3982 template< typename Type // Data type of the matrix
3983  , size_t M // Number of rows
3984  , size_t N > // Number of columns
3986 {
3987  using blaze::clear;
3988 
3989  for( size_t j=0UL; j<n_; ++j )
3990  for( size_t i=0UL; i<m_; ++i )
3991  clear( v_[i+j*MM] );
3992 }
3994 //*************************************************************************************************
3995 
3996 
3997 //*************************************************************************************************
4007 template< typename Type // Data type of the matrix
4008  , size_t M // Number of rows
4009  , size_t N > // Number of columns
4010 inline void HybridMatrix<Type,M,N,true>::reset( size_t j )
4011 {
4012  using blaze::clear;
4013 
4014  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4015  for( size_t i=0UL; i<m_; ++i )
4016  clear( v_[i+j*MM] );
4017 }
4019 //*************************************************************************************************
4020 
4021 
4022 //*************************************************************************************************
4030 template< typename Type // Data type of the matrix
4031  , size_t M // Number of rows
4032  , size_t N > // Number of columns
4034 {
4035  resize( 0UL, 0UL );
4036 }
4038 //*************************************************************************************************
4039 
4040 
4041 //*************************************************************************************************
4078 template< typename Type // Data type of the matrix
4079  , size_t M // Number of rows
4080  , size_t N > // Number of columns
4081 void HybridMatrix<Type,M,N,true>::resize( size_t m, size_t n, bool preserve )
4082 {
4083  UNUSED_PARAMETER( preserve );
4084 
4085  if( m > M )
4086  throw std::invalid_argument( "Invalid number of rows for hybrid matrix" );
4087 
4088  if( n > N )
4089  throw std::invalid_argument( "Invalid number of columns for hybrid matrix" );
4090 
4091  if( IsVectorizable<Type>::value && m < m_ ) {
4092  for( size_t j=0UL; j<n; ++j )
4093  for( size_t i=m; i<m_; ++i )
4094  v_[i+j*MM] = Type();
4095  }
4096 
4097  if( IsVectorizable<Type>::value && n < n_ ) {
4098  for( size_t j=n; j<n_; ++j )
4099  for( size_t i=0UL; i<m_; ++i )
4100  v_[i+j*MM] = Type();
4101  }
4102 
4103  m_ = m;
4104  n_ = n;
4105 }
4107 //*************************************************************************************************
4108 
4109 
4110 //*************************************************************************************************
4126 template< typename Type // Data type of the matrix
4127  , size_t M // Number of rows
4128  , size_t N > // Number of columns
4129 inline void HybridMatrix<Type,M,N,true>::extend( size_t m, size_t n, bool preserve )
4130 {
4131  UNUSED_PARAMETER( preserve );
4132  resize( m_+m, n_+n );
4133 }
4135 //*************************************************************************************************
4136 
4137 
4138 //*************************************************************************************************
4150 template< typename Type // Data type of the matrix
4151  , size_t M // Number of rows
4152  , size_t N > // Number of columns
4153 inline HybridMatrix<Type,M,N,true>& HybridMatrix<Type,M,N,true>::transpose()
4154 {
4155  using std::swap;
4156 
4157  if( m_ > N || n_ > M )
4158  throw std::logic_error( "Impossible transpose operation" );
4159 
4160  const size_t maxsize( max( m_, n_ ) );
4161  for( size_t j=1UL; j<maxsize; ++j )
4162  for( size_t i=0UL; i<j; ++i )
4163  swap( v_[i+j*MM], v_[j+i*MM] );
4164 
4165  if( IsVectorizable<Type>::value && n_ < m_ ) {
4166  for( size_t j=0UL; j<n_; ++j ) {
4167  for( size_t i=n_; i<m_; ++i ) {
4168  v_[i+j*MM] = Type();
4169  }
4170  }
4171  }
4172 
4173  if( IsVectorizable<Type>::value && n_ > m_ ) {
4174  for( size_t j=m_; j<n_; ++j )
4175  for( size_t i=0UL; i<m_; ++i )
4176  v_[i+j*MM] = Type();
4177  }
4178 
4179  swap( m_, n_ );
4180 
4181  return *this;
4182 }
4184 //*************************************************************************************************
4185 
4186 
4187 //*************************************************************************************************
4194 template< typename Type // Data type of the matrix
4195  , size_t M // Number of rows
4196  , size_t N > // Number of columns
4197 template< typename Other > // Data type of the scalar value
4198 inline HybridMatrix<Type,M,N,true>&
4199  HybridMatrix<Type,M,N,true>::scale( const Other& scalar )
4200 {
4201  for( size_t j=0UL; j<n_; ++j )
4202  for( size_t i=0UL; i<m_; ++i )
4203  v_[i+j*MM] *= scalar;
4204 
4205  return *this;
4206 }
4208 //*************************************************************************************************
4209 
4210 
4211 //*************************************************************************************************
4219 template< typename Type // Data type of the matrix
4220  , size_t M // Number of rows
4221  , size_t N > // Number of columns
4222 inline void HybridMatrix<Type,M,N,true>::swap( HybridMatrix& m ) /* throw() */
4223 {
4224  using std::swap;
4225 
4226  const size_t maxrows( max( m_, m.m_ ) );
4227  const size_t maxcols( max( n_, m.n_ ) );
4228 
4229  for( size_t j=0UL; j<maxcols; ++j ) {
4230  for( size_t i=0UL; i<maxrows; ++i ) {
4231  swap( v_[i+j*MM], m(i,j) );
4232  }
4233  }
4234 
4235  swap( m_, m.m_ );
4236  swap( n_, m.n_ );
4237 }
4239 //*************************************************************************************************
4240 
4241 
4242 
4243 
4244 //=================================================================================================
4245 //
4246 // MEMORY FUNCTIONS
4247 //
4248 //=================================================================================================
4249 
4250 //*************************************************************************************************
4261 template< typename Type // Data type of the matrix
4262  , size_t M // Number of rows
4263  , size_t N > // Number of columns
4264 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size )
4265 {
4266  UNUSED_PARAMETER( size );
4267 
4268  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
4269 
4270  return allocate<HybridMatrix>( 1UL );
4271 }
4273 //*************************************************************************************************
4274 
4275 
4276 //*************************************************************************************************
4287 template< typename Type // Data type of the matrix
4288  , size_t M // Number of rows
4289  , size_t N > // Number of columns
4290 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size )
4291 {
4292  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
4293  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
4294 
4295  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
4296 }
4298 //*************************************************************************************************
4299 
4300 
4301 //*************************************************************************************************
4312 template< typename Type // Data type of the matrix
4313  , size_t M // Number of rows
4314  , size_t N > // Number of columns
4315 inline void* HybridMatrix<Type,M,N,true>::operator new( std::size_t size, const std::nothrow_t& )
4316 {
4317  UNUSED_PARAMETER( size );
4318 
4319  BLAZE_INTERNAL_ASSERT( size == sizeof( HybridMatrix ), "Invalid number of bytes detected" );
4320 
4321  return allocate<HybridMatrix>( 1UL );
4322 }
4324 //*************************************************************************************************
4325 
4326 
4327 //*************************************************************************************************
4338 template< typename Type // Data type of the matrix
4339  , size_t M // Number of rows
4340  , size_t N > // Number of columns
4341 inline void* HybridMatrix<Type,M,N,true>::operator new[]( std::size_t size, const std::nothrow_t& )
4342 {
4343  BLAZE_INTERNAL_ASSERT( size >= sizeof( HybridMatrix ) , "Invalid number of bytes detected" );
4344  BLAZE_INTERNAL_ASSERT( size % sizeof( HybridMatrix ) == 0UL, "Invalid number of bytes detected" );
4345 
4346  return allocate<HybridMatrix>( size/sizeof(HybridMatrix) );
4347 }
4349 //*************************************************************************************************
4350 
4351 
4352 //*************************************************************************************************
4359 template< typename Type // Data type of the matrix
4360  , size_t M // Number of rows
4361  , size_t N > // Number of columns
4362 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr )
4363 {
4364  deallocate( static_cast<HybridMatrix*>( ptr ) );
4365 }
4367 //*************************************************************************************************
4368 
4369 
4370 //*************************************************************************************************
4377 template< typename Type // Data type of the matrix
4378  , size_t M // Number of rows
4379  , size_t N > // Number of columns
4380 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr )
4381 {
4382  deallocate( static_cast<HybridMatrix*>( ptr ) );
4383 }
4385 //*************************************************************************************************
4386 
4387 
4388 //*************************************************************************************************
4395 template< typename Type // Data type of the matrix
4396  , size_t M // Number of rows
4397  , size_t N > // Number of columns
4398 inline void HybridMatrix<Type,M,N,true>::operator delete( void* ptr, const std::nothrow_t& )
4399 {
4400  deallocate( static_cast<HybridMatrix*>( ptr ) );
4401 }
4403 //*************************************************************************************************
4404 
4405 
4406 //*************************************************************************************************
4413 template< typename Type // Data type of the matrix
4414  , size_t M // Number of rows
4415  , size_t N > // Number of columns
4416 inline void HybridMatrix<Type,M,N,true>::operator delete[]( void* ptr, const std::nothrow_t& )
4417 {
4418  deallocate( static_cast<HybridMatrix*>( ptr ) );
4419 }
4421 //*************************************************************************************************
4422 
4423 
4424 
4425 
4426 //=================================================================================================
4427 //
4428 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4429 //
4430 //=================================================================================================
4431 
4432 //*************************************************************************************************
4443 template< typename Type // Data type of the matrix
4444  , size_t M // Number of rows
4445  , size_t N > // Number of columns
4446 template< typename Other > // Data type of the foreign expression
4447 inline bool HybridMatrix<Type,M,N,true>::canAlias( const Other* alias ) const
4448 {
4449  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4450 }
4452 //*************************************************************************************************
4453 
4454 
4455 //*************************************************************************************************
4466 template< typename Type // Data type of the matrix
4467  , size_t M // Number of rows
4468  , size_t N > // Number of columns
4469 template< typename Other > // Data type of the foreign expression
4470 inline bool HybridMatrix<Type,M,N,true>::isAliased( const Other* alias ) const
4471 {
4472  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
4473 }
4475 //*************************************************************************************************
4476 
4477 
4478 //*************************************************************************************************
4488 template< typename Type // Data type of the matrix
4489  , size_t M // Number of rows
4490  , size_t N > // Number of columns
4491 inline bool HybridMatrix<Type,M,N,true>::isAligned() const
4492 {
4493  return true;
4494 }
4496 //*************************************************************************************************
4497 
4498 
4499 //*************************************************************************************************
4514 template< typename Type // Data type of the matrix
4515  , size_t M // Number of rows
4516  , size_t N > // Number of columns
4517 BLAZE_ALWAYS_INLINE typename HybridMatrix<Type,M,N,true>::IntrinsicType
4518  HybridMatrix<Type,M,N,true>::load( size_t i, size_t j ) const
4519 {
4520  using blaze::load;
4521 
4523 
4524  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
4525  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM , "Invalid row access index" );
4526  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
4527  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
4528 
4529  return load( &v_[i+j*MM] );
4530 }
4532 //*************************************************************************************************
4533 
4534 
4535 //*************************************************************************************************
4550 template< typename Type // Data type of the matrix
4551  , size_t M // Number of rows
4552  , size_t N > // Number of columns
4553 BLAZE_ALWAYS_INLINE typename HybridMatrix<Type,M,N,true>::IntrinsicType
4554  HybridMatrix<Type,M,N,true>::loadu( size_t i, size_t j ) const
4555 {
4556  using blaze::loadu;
4557 
4559 
4560  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
4561  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM , "Invalid row access index" );
4562  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
4563 
4564  return loadu( &v_[i+j*MM] );
4565 }
4567 //*************************************************************************************************
4568 
4569 
4570 //*************************************************************************************************
4586 template< typename Type // Data type of the matrix
4587  , size_t M // Number of rows
4588  , size_t N > // Number of columns
4590  HybridMatrix<Type,M,N,true>::store( size_t i, size_t j, const IntrinsicType& value )
4591 {
4592  using blaze::store;
4593 
4595 
4596  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
4597  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM , "Invalid row access index" );
4598  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
4599  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
4600 
4601  store( &v_[i+j*MM], value );
4602 }
4604 //*************************************************************************************************
4605 
4606 
4607 //*************************************************************************************************
4623 template< typename Type // Data type of the matrix
4624  , size_t M // Number of rows
4625  , size_t N > // Number of columns
4627  HybridMatrix<Type,M,N,true>::storeu( size_t i, size_t j, const IntrinsicType& value )
4628 {
4629  using blaze::storeu;
4630 
4632 
4633  BLAZE_INTERNAL_ASSERT( i < m_, "Invalid row access index" );
4634  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM, "Invalid row access index" );
4635  BLAZE_INTERNAL_ASSERT( j < n_, "Invalid column access index" );
4636 
4637  storeu( &v_[i+j*MM], value );
4638 }
4640 //*************************************************************************************************
4641 
4642 
4643 //*************************************************************************************************
4660 template< typename Type // Data type of the matrix
4661  , size_t M // Number of rows
4662  , size_t N > // Number of columns
4664  HybridMatrix<Type,M,N,true>::stream( size_t i, size_t j, const IntrinsicType& value )
4665 {
4666  using blaze::stream;
4667 
4669 
4670  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
4671  BLAZE_INTERNAL_ASSERT( i + IT::size <= MM , "Invalid row access index" );
4672  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
4673  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
4674 
4675  stream( &v_[i+j*MM], value );
4676 }
4678 //*************************************************************************************************
4679 
4680 
4681 //*************************************************************************************************
4693 template< typename Type // Data type of the matrix
4694  , size_t M // Number of rows
4695  , size_t N > // Number of columns
4696 template< typename MT // Type of the right-hand side dense matrix
4697  , bool SO > // Storage order of the right-hand side dense matrix
4698 inline typename DisableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
4699  HybridMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
4700 {
4701  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
4702 
4703  for( size_t j=0UL; j<n_; ++j ) {
4704  for( size_t i=0UL; i<m_; ++i ) {
4705  v_[i+j*MM] = (~rhs)(i,j);
4706  }
4707  }
4708 }
4710 //*************************************************************************************************
4711 
4712 
4713 //*************************************************************************************************
4725 template< typename Type // Data type of the matrix
4726  , size_t M // Number of rows
4727  , size_t N > // Number of columns
4728 template< typename MT // Type of the right-hand side dense matrix
4729  , bool SO > // Storage order of the right-hand side dense matrix
4730 inline typename EnableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
4731  HybridMatrix<Type,M,N,true>::assign( const DenseMatrix<MT,SO>& rhs )
4732 {
4733  using blaze::store;
4734 
4736 
4737  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
4738 
4739  for( size_t j=0UL; j<n_; ++j ) {
4740  for( size_t i=0UL; i<m_; i+=IT::size ) {
4741  store( &v_[i+j*MM], (~rhs).load(i,j) );
4742  }
4743  }
4744 }
4746 //*************************************************************************************************
4747 
4748 
4749 //*************************************************************************************************
4761 template< typename Type // Data type of the matrix
4762  , size_t M // Number of rows
4763  , size_t N > // Number of columns
4764 template< typename MT > // Type of the right-hand side sparse matrix
4765 inline void HybridMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,true>& rhs )
4766 {
4767  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
4768 
4769  typedef typename MT::ConstIterator RhsConstIterator;
4770 
4771  for( size_t j=0UL; j<n_; ++j )
4772  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4773  v_[element->index()+j*MM] = element->value();
4774 }
4776 //*************************************************************************************************
4777 
4778 
4779 //*************************************************************************************************
4791 template< typename Type // Data type of the matrix
4792  , size_t M // Number of rows
4793  , size_t N > // Number of columns
4794 template< typename MT > // Type of the right-hand side sparse matrix
4795 inline void HybridMatrix<Type,M,N,true>::assign( const SparseMatrix<MT,false>& rhs )
4796 {
4798 
4799  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
4800 
4801  typedef typename MT::ConstIterator RhsConstIterator;
4802 
4803  for( size_t i=0UL; i<m_; ++i )
4804  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4805  v_[i+element->index()*MM] = element->value();
4806 }
4808 //*************************************************************************************************
4809 
4810 
4811 //*************************************************************************************************
4823 template< typename Type // Data type of the matrix
4824  , size_t M // Number of rows
4825  , size_t N > // Number of columns
4826 template< typename MT // Type of the right-hand side dense matrix
4827  , bool SO > // Storage order of the right-hand side dense matrix
4828 inline typename DisableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
4829  HybridMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4830 {
4831  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
4832 
4833  for( size_t j=0UL; j<n_; ++j )
4834  {
4835  if( IsDiagonal<MT>::value )
4836  {
4837  v_[j+j*MM] += (~rhs)(j,j);
4838  }
4839  else
4840  {
4841  const size_t ibegin( ( IsLower<MT>::value )
4842  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
4843  :( 0UL ) );
4844  const size_t iend ( ( IsUpper<MT>::value )
4845  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
4846  :( m_ ) );
4847  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
4848 
4849  for( size_t i=ibegin; i<iend; ++i ) {
4850  v_[i+j*MM] += (~rhs)(i,j);
4851  }
4852  }
4853  }
4854 }
4856 //*************************************************************************************************
4857 
4858 
4859 //*************************************************************************************************
4871 template< typename Type // Data type of the matrix
4872  , size_t M // Number of rows
4873  , size_t N > // Number of columns
4874 template< typename MT // Type of the right-hand side dense matrix
4875  , bool SO > // Storage order of the right-hand side dense matrix
4876 inline typename EnableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
4877  HybridMatrix<Type,M,N,true>::addAssign( const DenseMatrix<MT,SO>& rhs )
4878 {
4879  using blaze::load;
4880  using blaze::store;
4881 
4884 
4885  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
4886 
4887  for( size_t j=0UL; j<n_; ++j )
4888  {
4889  const size_t ibegin( ( IsLower<MT>::value )
4890  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
4891  :( 0UL ) );
4892  const size_t iend ( ( IsUpper<MT>::value )
4893  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
4894  :( m_ ) );
4895  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
4896 
4897  for( size_t i=ibegin; i<iend; i+=IT::size ) {
4898  store( &v_[i+j*MM], load( &v_[i+j*MM] ) + (~rhs).load(i,j) );
4899  }
4900  }
4901 }
4903 //*************************************************************************************************
4904 
4905 
4906 //*************************************************************************************************
4918 template< typename Type // Data type of the matrix
4919  , size_t M // Number of rows
4920  , size_t N > // Number of columns
4921 template< typename MT > // Type of the right-hand side sparse matrix
4922 inline void HybridMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,true>& rhs )
4923 {
4924  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
4925 
4926  typedef typename MT::ConstIterator RhsConstIterator;
4927 
4928  for( size_t j=0UL; j<n_; ++j )
4929  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4930  v_[element->index()+j*MM] += element->value();
4931 }
4933 //*************************************************************************************************
4934 
4935 
4936 //*************************************************************************************************
4948 template< typename Type // Data type of the matrix
4949  , size_t M // Number of rows
4950  , size_t N > // Number of columns
4951 template< typename MT > // Type of the right-hand side sparse matrix
4952 inline void HybridMatrix<Type,M,N,true>::addAssign( const SparseMatrix<MT,false>& rhs )
4953 {
4955 
4956  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
4957 
4958  typedef typename MT::ConstIterator RhsConstIterator;
4959 
4960  for( size_t i=0UL; i<m_; ++i )
4961  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4962  v_[i+element->index()*MM] += element->value();
4963 }
4965 //*************************************************************************************************
4966 
4967 
4968 //*************************************************************************************************
4980 template< typename Type // Data type of the matrix
4981  , size_t M // Number of rows
4982  , size_t N > // Number of columns
4983 template< typename MT // Type of the right-hand side dense matrix
4984  , bool SO > // Storage order of the right-hand side dense matrix
4985 inline typename DisableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
4986  HybridMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
4987 {
4988  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
4989 
4990  for( size_t j=0UL; j<n_; ++j )
4991  {
4992  if( IsDiagonal<MT>::value )
4993  {
4994  v_[j+j*MM] -= (~rhs)(j,j);
4995  }
4996  else
4997  {
4998  const size_t ibegin( ( IsLower<MT>::value )
4999  ?( IsStrictlyLower<MT>::value ? j+1UL : j )
5000  :( 0UL ) );
5001  const size_t iend ( ( IsUpper<MT>::value )
5002  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5003  :( m_ ) );
5004  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5005 
5006  for( size_t i=ibegin; i<iend; ++i ) {
5007  v_[i+j*MM] -= (~rhs)(i,j);
5008  }
5009  }
5010  }
5011 }
5013 //*************************************************************************************************
5014 
5015 
5016 //*************************************************************************************************
5028 template< typename Type // Data type of the matrix
5029  , size_t M // Number of rows
5030  , size_t N > // Number of columns
5031 template< typename MT // Type of the right-hand side dense matrix
5032  , bool SO > // Storage order of the right-hand side dense matrix
5033 inline typename EnableIf< typename HybridMatrix<Type,M,N,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
5034  HybridMatrix<Type,M,N,true>::subAssign( const DenseMatrix<MT,SO>& rhs )
5035 {
5036  using blaze::load;
5037  using blaze::store;
5038 
5041 
5042  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5043 
5044  for( size_t j=0UL; j<n_; ++j )
5045  {
5046  const size_t ibegin( ( IsLower<MT>::value )
5047  ?( ( IsStrictlyLower<MT>::value ? j+1UL : j ) & size_t(-IT::size) )
5048  :( 0UL ) );
5049  const size_t iend ( ( IsUpper<MT>::value )
5050  ?( IsStrictlyUpper<MT>::value ? j : j+1UL )
5051  :( m_ ) );
5052  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
5053 
5054  for( size_t i=ibegin; i<iend; i+=IT::size ) {
5055  store( &v_[i+j*MM], load( &v_[i+j*MM] ) - (~rhs).load(i,j) );
5056  }
5057  }
5058 }
5060 //*************************************************************************************************
5061 
5062 
5063 //*************************************************************************************************
5075 template< typename Type // Data type of the matrix
5076  , size_t M // Number of rows
5077  , size_t N > // Number of columns
5078 template< typename MT > // Type of the right-hand side sparse matrix
5079 inline void HybridMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,true>& rhs )
5080 {
5081  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5082 
5083  typedef typename MT::ConstIterator RhsConstIterator;
5084 
5085  for( size_t j=0UL; j<n_; ++j )
5086  for( RhsConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5087  v_[element->index()+j*MM] -= element->value();
5088 }
5090 //*************************************************************************************************
5091 
5092 
5093 //*************************************************************************************************
5105 template< typename Type // Data type of the matrix
5106  , size_t M // Number of rows
5107  , size_t N > // Number of columns
5108 template< typename MT > // Type of the right-hand side sparse matrix
5109 inline void HybridMatrix<Type,M,N,true>::subAssign( const SparseMatrix<MT,false>& rhs )
5110 {
5112 
5113  BLAZE_INTERNAL_ASSERT( (~rhs).rows() == m_ && (~rhs).columns() == n_, "Invalid matrix size" );
5114 
5115  typedef typename MT::ConstIterator RhsConstIterator;
5116 
5117  for( size_t i=0UL; i<m_; ++i )
5118  for( RhsConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5119  v_[i+element->index()*MM] -= element->value();
5120 }
5122 //*************************************************************************************************
5123 
5124 
5125 
5126 
5127 
5128 
5129 
5130 
5131 //=================================================================================================
5132 //
5133 // UNDEFINED CLASS TEMPLATE SPECIALIZATIONS
5134 //
5135 //=================================================================================================
5136 
5137 //*************************************************************************************************
5145 template< typename Type // Data type of the matrix
5146  , size_t M // Number of rows
5147  , bool SO > // Storage order
5148 class HybridMatrix<Type,M,0UL,SO>;
5150 //*************************************************************************************************
5151 
5152 
5153 //*************************************************************************************************
5161 template< typename Type // Data type of the matrix
5162  , size_t N // Number of columns
5163  , bool SO > // Storage order
5164 class HybridMatrix<Type,0UL,N,SO>;
5166 //*************************************************************************************************
5167 
5168 
5169 //*************************************************************************************************
5177 template< typename Type // Data type of the matrix
5178  , bool SO > // Storage order
5179 class HybridMatrix<Type,0UL,0UL,SO>;
5181 //*************************************************************************************************
5182 
5183 
5184 
5185 
5186 
5187 
5188 
5189 
5190 //=================================================================================================
5191 //
5192 // STATICMATRIX OPERATORS
5193 //
5194 //=================================================================================================
5195 
5196 //*************************************************************************************************
5199 template< typename Type, size_t M, size_t N, bool SO >
5200 inline void reset( HybridMatrix<Type,M,N,SO>& m );
5201 
5202 template< typename Type, size_t M, size_t N, bool SO >
5203 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i );
5204 
5205 template< typename Type, size_t M, size_t N, bool SO >
5206 inline void clear( HybridMatrix<Type,M,N,SO>& m );
5207 
5208 template< typename Type, size_t M, size_t N, bool SO >
5209 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m );
5210 
5211 template< typename Type, size_t M, size_t N, bool SO >
5212 inline void swap( HybridMatrix<Type,M,N,SO>& a, HybridMatrix<Type,M,N,SO>& b ) /* throw() */;
5213 
5214 template< typename Type, size_t M, size_t N, bool SO >
5215 inline void move( HybridMatrix<Type,M,N,SO>& dst, HybridMatrix<Type,M,N,SO>& src ) /* throw() */;
5217 //*************************************************************************************************
5218 
5219 
5220 //*************************************************************************************************
5227 template< typename Type // Data type of the matrix
5228  , size_t M // Number of rows
5229  , size_t N // Number of columns
5230  , bool SO > // Storage order
5232 {
5233  m.reset();
5234 }
5235 //*************************************************************************************************
5236 
5237 
5238 //*************************************************************************************************
5251 template< typename Type // Data type of the matrix
5252  , size_t M // Number of rows
5253  , size_t N // Number of columns
5254  , bool SO > // Storage order
5255 inline void reset( HybridMatrix<Type,M,N,SO>& m, size_t i )
5256 {
5257  m.reset( i );
5258 }
5259 //*************************************************************************************************
5260 
5261 
5262 //*************************************************************************************************
5269 template< typename Type // Data type of the matrix
5270  , size_t M // Number of rows
5271  , size_t N // Number of columns
5272  , bool SO > // Storage order
5274 {
5275  m.clear();
5276 }
5277 //*************************************************************************************************
5278 
5279 
5280 //*************************************************************************************************
5298 template< typename Type // Data type of the matrix
5299  , size_t M // Number of rows
5300  , size_t N // Number of columns
5301  , bool SO > // Storage order
5302 inline bool isDefault( const HybridMatrix<Type,M,N,SO>& m )
5303 {
5304  return ( m.rows() == 0UL && m.columns() == 0UL );
5305 }
5306 //*************************************************************************************************
5307 
5308 
5309 //*************************************************************************************************
5318 template< typename Type // Data type of the matrix
5319  , size_t M // Number of rows
5320  , size_t N // Number of columns
5321  , bool SO > // Storage order
5322 inline void swap( HybridMatrix<Type,M,N,SO>& a, HybridMatrix<Type,M,N,SO>& b ) /* throw() */
5323 {
5324  a.swap( b );
5325 }
5326 //*************************************************************************************************
5327 
5328 
5329 //*************************************************************************************************
5338 template< typename Type // Data type of the matrix
5339  , size_t M // Number of rows
5340  , size_t N // Number of columns
5341  , bool SO > // Storage order
5342 inline void move( HybridMatrix<Type,M,N,SO>& dst, HybridMatrix<Type,M,N,SO>& src ) /* throw() */
5343 {
5344  dst = src;
5345 }
5346 //*************************************************************************************************
5347 
5348 
5349 
5350 
5351 //=================================================================================================
5352 //
5353 // HASCONSTDATAACCESS SPECIALIZATIONS
5354 //
5355 //=================================================================================================
5356 
5357 //*************************************************************************************************
5359 template< typename T, size_t M, size_t N, bool SO >
5360 struct HasConstDataAccess< HybridMatrix<T,M,N,SO> > : public TrueType
5361 {
5362  enum { value = 1 };
5363  typedef TrueType Type;
5364 };
5366 //*************************************************************************************************
5367 
5368 
5369 
5370 
5371 //=================================================================================================
5372 //
5373 // HASMUTABLEDATAACCESS SPECIALIZATIONS
5374 //
5375 //=================================================================================================
5376 
5377 //*************************************************************************************************
5379 template< typename T, size_t M, size_t N, bool SO >
5380 struct HasMutableDataAccess< HybridMatrix<T,M,N,SO> > : public TrueType
5381 {
5382  enum { value = 1 };
5383  typedef TrueType Type;
5384 };
5386 //*************************************************************************************************
5387 
5388 
5389 
5390 
5391 //=================================================================================================
5392 //
5393 // ISRESIZABLE SPECIALIZATIONS
5394 //
5395 //=================================================================================================
5396 
5397 //*************************************************************************************************
5399 template< typename T, size_t M, size_t N, bool SO >
5400 struct IsResizable< HybridMatrix<T,M,N,SO> > : public TrueType
5401 {
5402  enum { value = 1 };
5403  typedef TrueType Type;
5404 };
5406 //*************************************************************************************************
5407 
5408 
5409 
5410 
5411 //=================================================================================================
5412 //
5413 // ADDTRAIT SPECIALIZATIONS
5414 //
5415 //=================================================================================================
5416 
5417 //*************************************************************************************************
5419 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
5420 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
5421 {
5422  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M2, N2, SO > Type;
5423 };
5424 
5425 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5426 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
5427 {
5428  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M2, N2, false > Type;
5429 };
5430 
5431 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
5432 struct AddTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
5433 {
5434  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M2, N2, SO > Type;
5435 };
5436 
5437 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5438 struct AddTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
5439 {
5440  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M2, N2, false > Type;
5441 };
5442 
5443 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
5444 struct AddTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
5445 {
5446  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO > Type;
5447 };
5448 
5449 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5450 struct AddTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
5451 {
5452  typedef HybridMatrix< typename AddTrait<T1,T2>::Type, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false > Type;
5453 };
5455 //*************************************************************************************************
5456 
5457 
5458 
5459 
5460 //=================================================================================================
5461 //
5462 // SUBTRAIT SPECIALIZATIONS
5463 //
5464 //=================================================================================================
5465 
5466 //*************************************************************************************************
5468 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
5469 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, StaticMatrix<T2,M2,N2,SO> >
5470 {
5471  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M2, N2, SO > Type;
5472 };
5473 
5474 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5475 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
5476 {
5477  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M2, N2, false > Type;
5478 };
5479 
5480 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
5481 struct SubTrait< StaticMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
5482 {
5483  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M2, N2, SO > Type;
5484 };
5485 
5486 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5487 struct SubTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
5488 {
5489  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M2, N2, false > Type;
5490 };
5491 
5492 template< typename T1, size_t M1, size_t N1, bool SO, typename T2, size_t M2, size_t N2 >
5493 struct SubTrait< HybridMatrix<T1,M1,N1,SO>, HybridMatrix<T2,M2,N2,SO> >
5494 {
5495  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), SO > Type;
5496 };
5497 
5498 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5499 struct SubTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
5500 {
5501  typedef HybridMatrix< typename SubTrait<T1,T2>::Type, ( M1 < M2 )?( M1 ):( M2 ), ( N1 < N2 )?( N1 ):( N2 ), false > Type;
5502 };
5504 //*************************************************************************************************
5505 
5506 
5507 
5508 
5509 //=================================================================================================
5510 //
5511 // MULTTRAIT SPECIALIZATIONS
5512 //
5513 //=================================================================================================
5514 
5515 //*************************************************************************************************
5517 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5518 struct MultTrait< HybridMatrix<T1,M,N,SO>, T2 >
5519 {
5520  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M, N, SO > Type;
5522 };
5523 
5524 template< typename T1, typename T2, size_t M, size_t N, bool SO >
5525 struct MultTrait< T1, HybridMatrix<T2,M,N,SO> >
5526 {
5527  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M, N, SO > Type;
5529 };
5530 
5531 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
5532 struct MultTrait< HybridMatrix<T1,M,N,SO>, StaticVector<T2,K,false> >
5533 {
5534  typedef HybridVector< typename MultTrait<T1,T2>::Type, M, false > Type;
5535 };
5536 
5537 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
5538 struct MultTrait< StaticVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
5539 {
5540  typedef HybridVector< typename MultTrait<T1,T2>::Type, N, true > Type;
5541 };
5542 
5543 template< typename T1, size_t M, size_t N, bool SO, typename T2, size_t K >
5544 struct MultTrait< HybridMatrix<T1,M,N,SO>, HybridVector<T2,K,false> >
5545 {
5546  typedef HybridVector< typename MultTrait<T1,T2>::Type, M, false > Type;
5547 };
5548 
5549 template< typename T1, size_t K, typename T2, size_t M, size_t N, bool SO >
5550 struct MultTrait< HybridVector<T1,K,true>, HybridMatrix<T2,M,N,SO> >
5551 {
5552  typedef HybridVector< typename MultTrait<T1,T2>::Type, N, true > Type;
5553 };
5554 
5555 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5556 struct MultTrait< HybridMatrix<T1,M,N,SO>, DynamicVector<T2,false> >
5557 {
5558  typedef HybridVector< typename MultTrait<T1,T2>::Type, M, false > Type;
5559 };
5560 
5561 template< typename T1, typename T2, size_t M, size_t N, bool SO >
5562 struct MultTrait< DynamicVector<T1,true>, HybridMatrix<T2,M,N,SO> >
5563 {
5564  typedef HybridVector< typename MultTrait<T1,T2>::Type, N, true > Type;
5565 };
5566 
5567 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5568 struct MultTrait< HybridMatrix<T1,M,N,SO>, CompressedVector<T2,false> >
5569 {
5570  typedef HybridVector< typename MultTrait<T1,T2>::Type, M, false > Type;
5571 };
5572 
5573 template< typename T1, typename T2, size_t M, size_t N, bool SO >
5574 struct MultTrait< CompressedVector<T1,true>, HybridMatrix<T2,M,N,SO> >
5575 {
5576  typedef HybridVector< typename MultTrait<T1,T2>::Type, N, true > Type;
5577 };
5578 
5579 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5580 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, StaticMatrix<T2,M2,N2,SO2> >
5581 {
5582  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M1, N2, SO1 > Type;
5583 };
5584 
5585 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5586 struct MultTrait< StaticMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
5587 {
5588  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M1, N2, SO1 > Type;
5589 };
5590 
5591 template< typename T1, size_t M1, size_t N1, bool SO1, typename T2, size_t M2, size_t N2, bool SO2 >
5592 struct MultTrait< HybridMatrix<T1,M1,N1,SO1>, HybridMatrix<T2,M2,N2,SO2> >
5593 {
5594  typedef HybridMatrix< typename MultTrait<T1,T2>::Type, M1, N2, SO1 > Type;
5595 };
5597 //*************************************************************************************************
5598 
5599 
5600 
5601 
5602 //=================================================================================================
5603 //
5604 // DIVTRAIT SPECIALIZATIONS
5605 //
5606 //=================================================================================================
5607 
5608 //*************************************************************************************************
5610 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5611 struct DivTrait< HybridMatrix<T1,M,N,SO>, T2 >
5612 {
5613  typedef HybridMatrix< typename DivTrait<T1,T2>::Type, M, N, SO > Type;
5615 };
5617 //*************************************************************************************************
5618 
5619 
5620 
5621 
5622 //=================================================================================================
5623 //
5624 // MATHTRAIT SPECIALIZATIONS
5625 //
5626 //=================================================================================================
5627 
5628 //*************************************************************************************************
5630 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
5631 struct MathTrait< HybridMatrix<T1,M,N,SO>, HybridMatrix<T2,M,N,SO> >
5632 {
5633  typedef HybridMatrix< typename MathTrait<T1,T2>::HighType, M, N, SO > HighType;
5634  typedef HybridMatrix< typename MathTrait<T1,T2>::LowType , M, N, SO > LowType;
5635 };
5637 //*************************************************************************************************
5638 
5639 
5640 
5641 
5642 //=================================================================================================
5643 //
5644 // SUBMATRIXTRAIT SPECIALIZATIONS
5645 //
5646 //=================================================================================================
5647 
5648 //*************************************************************************************************
5650 template< typename T1, size_t M, size_t N, bool SO >
5651 struct SubmatrixTrait< HybridMatrix<T1,M,N,SO> >
5652 {
5653  typedef HybridMatrix<T1,M,N,SO> Type;
5654 };
5656 //*************************************************************************************************
5657 
5658 
5659 
5660 
5661 //=================================================================================================
5662 //
5663 // ROWTRAIT SPECIALIZATIONS
5664 //
5665 //=================================================================================================
5666 
5667 //*************************************************************************************************
5669 template< typename T1, size_t M, size_t N, bool SO >
5670 struct RowTrait< HybridMatrix<T1,M,N,SO> >
5671 {
5672  typedef HybridVector<T1,N,true> Type;
5673 };
5675 //*************************************************************************************************
5676 
5677 
5678 
5679 
5680 //=================================================================================================
5681 //
5682 // COLUMNTRAIT SPECIALIZATIONS
5683 //
5684 //=================================================================================================
5685 
5686 //*************************************************************************************************
5688 template< typename T1, size_t M, size_t N, bool SO >
5689 struct ColumnTrait< HybridMatrix<T1,M,N,SO> >
5690 {
5691  typedef HybridVector<T1,M,false> Type;
5692 };
5694 //*************************************************************************************************
5695 
5696 } // namespace blaze
5697 
5698 #endif
Compile time check for vectorizable types.Depending on the available instruction set (SSE...
Definition: IsVectorizable.h:108
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
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
ConstIterator cbegin(size_t i) const
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:996
ConstIterator cend(size_t i) const
Returns an iterator just past the last element of row/column i.
Definition: HybridMatrix.h:1068
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Constraint on the data type.
Header file for mathematical functions.
#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 UNUSED_PARAMETER function template.
Header file for the subtraction trait.
Type ElementType
Type of the matrix elements.
Definition: HybridMatrix.h:214
Header file for basic type definitions.
size_t spacing() const
Returns the spacing between the beginning of two rows.
Definition: HybridMatrix.h:1420
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:264
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type stream(T *address, const sse_int16_t &value)
Aligned, non-temporal store of a vector of 2-byte integral values.
Definition: Stream.h:76
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:258
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)
Aligned store of an intrinsic element of the matrix.
Definition: HybridMatrix.h:2122
Header file for the IsSame and IsStrictlySame type traits.
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:821
IT::Type IntrinsicType
Intrinsic type of the matrix elements.
Definition: HybridMatrix.h:215
size_t m_
The current number of rows of the sparse matrix.
Definition: CompressedMatrix.h:2665
Reference operator()(size_t i, size_t j)
2D-access to the matrix elements.
Definition: HybridMatrix.h:812
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix)
Returns the current number of rows of the matrix.
Definition: Matrix.h:316
const Type * ConstPointer
Pointer to a constant matrix value.
Definition: HybridMatrix.h:221
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
#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:219
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.
HybridMatrix< Type, N, M,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: HybridMatrix.h:213
Type & Reference
Reference to a non-constant matrix value.
Definition: HybridMatrix.h:218
bool isAliased(const Other *alias) const
Returns whether the matrix is aliased with the given address alias.
Definition: HybridMatrix.h:2003
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:107
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:861
Constraint on the data type.
Header file for the SparseMatrix base class.
const This & CompositeType
Data type for composite expression templates.
Definition: HybridMatrix.h:217
void resize(size_t m, size_t n, bool preserve=true)
Changing the size of the matrix.
Definition: HybridMatrix.h:1627
Header file for the DisableIf class template.
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:1385
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
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, sse_int16_t >::Type loadu(const T *address)
Loads a vector of 2-byte integral values.
Definition: Loadu.h:76
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:1020
void swap(CompressedMatrix< Type, SO > &a, CompressedMatrix< Type, SO > &b)
Swapping the contents of two compressed matrices.
Definition: CompressedMatrix.h:4807
Header file for all forward declarations of the math module.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2511
size_t nonZeros() const
Returns the total number of non-zero elements in the matrix.
Definition: HybridMatrix.h:1478
#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
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type store(T *address, const sse_int16_t &value)
Aligned store of a vector of 2-byte integral values.
Definition: Store.h:80
bool isAligned() const
Returns whether the matrix is properly aligned in memory.
Definition: HybridMatrix.h:2023
bool canAlias(const Other *alias) const
Returns whether the matrix can alias with the given address alias.
Definition: HybridMatrix.h:1981
Header file for the DenseMatrix base class.
Pointer data()
Low-level data access to the matrix elements.
Definition: HybridMatrix.h:859
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
EnableIf< IsBuiltin< T > >::Type deallocate(T *address)
Deallocation of memory for built-in data types.
Definition: Memory.h:226
Header file for the DenseIterator class template.
HybridMatrix()
The default constructor for HybridMatrix.
Definition: HybridMatrix.h:488
Type * Pointer
Pointer to a non-constant matrix value.
Definition: HybridMatrix.h:220
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:216
Header file for the IsLower type trait.
IntrinsicTrait< Type > IT
Intrinsic trait for the matrix element type.
Definition: HybridMatrix.h:200
size_t m_
The current number of rows of the matrix.
Definition: HybridMatrix.h:452
HybridMatrix< Type, M, N, SO > This
Type of this HybridMatrix instance.
Definition: HybridMatrix.h:210
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:1532
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:195
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:535
DenseIterator< Type > Iterator
Iterator over non-constant elements.
Definition: HybridMatrix.h:222
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2509
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:841
Header file for the IsVectorizable type trait.
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, sse_int16_t >::Type load(const T *address)
Loads a vector of 2-byte integral values.
Definition: Load.h:79
HybridMatrix< Type, M, N,!SO > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: HybridMatrix.h:212
Header file for the IsNumeric type trait.
Header file for the HasConstDataAccess type trait.
Iterator begin(size_t i)
Returns an iterator to the first element of row/column i.
Definition: HybridMatrix.h:948
AlignedArray< Type, M *NN > v_
The statically allocated matrix elements.
Definition: HybridMatrix.h:442
#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
Intrinsic characteristics of data types.The IntrinsicTrait class template provides the intrinsic char...
Definition: IntrinsicTrait.h:749
DenseIterator< const Type > ConstIterator
Iterator over constant elements.
Definition: HybridMatrix.h:223
Header file for run time assertion macros.
HybridMatrix & transpose()
Transposing the matrix.
Definition: HybridMatrix.h:1697
Header file for the addition trait.
BLAZE_ALWAYS_INLINE void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:742
Header file for the division trait.
size_t capacity() const
Returns the maximum capacity of the matrix.
Definition: HybridMatrix.h:1436
Header file for the submatrix trait.
Constraint on the data type.
This ResultType
Result type for expression template evaluations.
Definition: HybridMatrix.h:211
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.
#define BLAZE_CONSTRAINT_MUST_BE_NUMERIC_TYPE(T)
Constraint on the data type.In case the given data type T is not a numeric (integral or floating poin...
Definition: Numeric.h:79
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > > >::Type storeu(T *address, const sse_int16_t &value)
Unaligned store of a vector of 2-byte integral values.
Definition: Storeu.h:77
void move(DynamicMatrix< Type, SO > &dst, DynamicMatrix< Type, SO > &src)
Moving the contents of one dynamic matrix to another.
Definition: DynamicMatrix.h:4934
Header file for the AlignedArray implementation.
Efficient implementation of a dynamically sized matrix with static memory.The HybridMatrix class temp...
Definition: Forward.h:56
#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:2510
Header file for the column trait.
Header file for the isDefault shim.
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:87
Constraint on the data type.
Constraint on the data type.
Header file for the HasMutableDataAccess type trait.
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:200
BLAZE_ALWAYS_INLINE EnableIf< And< IsIntegral< T >, HasSize< T, 2UL > >, sse_int16_t >::Type set(T value)
Sets all values in the vector to the given 2-byte integral value.
Definition: Set.h:73
Implementation of a generic iterator for dense vectors and matrices.The DenseIterator represents a ge...
Definition: DenseIterator.h:58
Header file for all intrinsic functionality.
Header file for the mathematical trait.
Rebind mechanism to obtain a HybridMatrix with different data/element type.
Definition: HybridMatrix.h:230
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
HybridMatrix< ET, M, N, SO > Other
The type of the other HybridMatrix.
Definition: HybridMatrix.h:231
size_t n_
The current number of columns of the sparse matrix.
Definition: CompressedMatrix.h:2666
Header file for the IsRowMajorMatrix type trait.
BLAZE_ALWAYS_INLINE IntrinsicType load(size_t i, size_t j) const
Aligned load of an intrinsic element of the matrix.
Definition: HybridMatrix.h:2050
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:2195
size_t n_
The current number of columns of the matrix.
Definition: HybridMatrix.h:453
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2502
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix)
Returns the current number of columns of the matrix.
Definition: Matrix.h:332
void swap(HybridMatrix &m)
Swapping the contents of two hybrid matrices.
Definition: HybridMatrix.h:1765
void clear()
Clearing the hybrid matrix.
Definition: HybridMatrix.h:1580
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:1401
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2508
Header file for the IsUpper type trait.
boost::true_type TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
void extend(size_t m, size_t n, bool preserve=true)
Extending the size of the matrix.
Definition: HybridMatrix.h:1674
#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:2159
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:2086
BLAZE_ALWAYS_INLINE void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:849