All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DynamicMatrix.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_DENSE_DYNAMICMATRIX_H_
23 #define _BLAZE_MATH_DENSE_DYNAMICMATRIX_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <algorithm>
31 #include <stdexcept>
33 #include <blaze/math/Functions.h>
34 #include <blaze/math/Intrinsics.h>
35 #include <blaze/math/shims/Equal.h>
37 #include <blaze/math/shims/IsNaN.h>
38 #include <blaze/math/shims/Reset.h>
44 #include <blaze/math/Types.h>
48 #include <blaze/system/CacheSize.h>
49 #include <blaze/system/Restrict.h>
51 #include <blaze/util/Assert.h>
58 #include <blaze/util/DisableIf.h>
59 #include <blaze/util/EnableIf.h>
60 #include <blaze/util/Memory.h>
61 #include <blaze/util/mpl/If.h>
62 #include <blaze/util/Null.h>
63 #include <blaze/util/Template.h>
64 #include <blaze/util/Types.h>
70 
71 
72 namespace blaze {
73 
74 //=================================================================================================
75 //
76 // CLASS DEFINITION
77 //
78 //=================================================================================================
79 
80 //*************************************************************************************************
159 template< typename Type // Data type of the matrix
160  , bool SO = defaultStorageOrder > // Storage order
161 class DynamicMatrix : public DenseMatrix< DynamicMatrix<Type,SO>, SO >
162 {
163  private:
164  //**Type definitions****************************************************************************
166  //**********************************************************************************************
167 
168  public:
169  //**Type definitions****************************************************************************
171  typedef This ResultType;
174  typedef Type ElementType;
175  typedef const Type& ReturnType;
176  typedef typename IT::Type IntrinsicType;
177  typedef const This& CompositeType;
178  typedef Type& Reference;
179  typedef const Type& ConstReference;
180  typedef Type* Iterator;
181  typedef const Type* ConstIterator;
182  //**********************************************************************************************
183 
184  //**Compilation flags***************************************************************************
186 
190  enum { vectorizable = IsVectorizable<Type>::value };
191 
193 
196  enum { canAlias = 0 };
197  //**********************************************************************************************
198 
199  //**Constructors********************************************************************************
202  explicit inline DynamicMatrix();
203  explicit inline DynamicMatrix( size_t m, size_t n );
204  explicit inline DynamicMatrix( size_t m, size_t n, Type init );
205  inline DynamicMatrix( const DynamicMatrix& m );
206  template< typename MT, bool SO2 > inline DynamicMatrix( const Matrix<MT,SO2>& m );
207 
208  template< typename Other, size_t M, size_t N >
209  inline DynamicMatrix( const Other (&rhs)[M][N] );
211  //**********************************************************************************************
212 
213  //**Destructor**********************************************************************************
216  inline ~DynamicMatrix();
218  //**********************************************************************************************
219 
220  //**Data access functions***********************************************************************
223  inline Reference operator()( size_t i, size_t j );
224  inline ConstReference operator()( size_t i, size_t j ) const;
225  inline Type* data();
226  inline const Type* data() const;
227  inline Iterator begin ( size_t i );
228  inline ConstIterator begin ( size_t i ) const;
229  inline ConstIterator cbegin( size_t i ) const;
230  inline Iterator end ( size_t i );
231  inline ConstIterator end ( size_t i ) const;
232  inline ConstIterator cend ( size_t i ) const;
234  //**********************************************************************************************
235 
236  //**Assignment operators************************************************************************
239  template< typename Other, size_t M, size_t N >
240  inline DynamicMatrix& operator=( const Other (&rhs)[M][N] );
241 
242  inline DynamicMatrix& operator= ( Type set );
243  inline DynamicMatrix& operator= ( const DynamicMatrix& set );
244  template< typename MT, bool SO2 > inline DynamicMatrix& operator= ( const Matrix<MT,SO2>& rhs );
245  template< typename MT, bool SO2 > inline DynamicMatrix& operator+=( const Matrix<MT,SO2>& rhs );
246  template< typename MT, bool SO2 > inline DynamicMatrix& operator-=( const Matrix<MT,SO2>& rhs );
247  template< typename MT, bool SO2 > inline DynamicMatrix& operator*=( const Matrix<MT,SO2>& rhs );
248 
249  template< typename Other >
250  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
251  operator*=( Other rhs );
252 
253  template< typename Other >
254  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
255  operator/=( Other rhs );
257  //**********************************************************************************************
258 
259  //**Utility functions***************************************************************************
262  inline size_t rows() const;
263  inline size_t columns() const;
264  inline size_t spacing() const;
265  inline size_t capacity() const;
266  inline size_t nonZeros() const;
267  inline size_t nonZeros( size_t i ) const;
268  inline void reset();
269  inline void clear();
270  void resize ( size_t m, size_t n, bool preserve=true );
271  inline void extend ( size_t m, size_t n, bool preserve=true );
272  inline void reserve( size_t elements );
273  inline DynamicMatrix& transpose();
274  inline DynamicMatrix& invert();
275  inline bool isDiagonal() const;
276  inline bool isSymmetric() const;
277  template< typename Other > inline DynamicMatrix& scale( Other scalar );
278  inline void swap( DynamicMatrix& m ) /* throw() */;
280  //**********************************************************************************************
281 
282  private:
283  //**********************************************************************************************
285 
286  template< typename MT >
287  struct VectorizedAssign {
288  enum { value = vectorizable && MT::vectorizable &&
289  IsSame<Type,typename MT::ElementType>::value };
290  };
292  //**********************************************************************************************
293 
294  //**********************************************************************************************
296 
297  template< typename MT >
298  struct VectorizedAddAssign {
299  enum { value = vectorizable && MT::vectorizable &&
300  IsSame<Type,typename MT::ElementType>::value &&
301  IntrinsicTrait<Type>::addition };
302  };
304  //**********************************************************************************************
305 
306  //**********************************************************************************************
308 
309  template< typename MT >
310  struct VectorizedSubAssign {
311  enum { value = vectorizable && MT::vectorizable &&
312  IsSame<Type,typename MT::ElementType>::value &&
313  IntrinsicTrait<Type>::subtraction };
314  };
316  //**********************************************************************************************
317 
318  public:
319  //**Expression template evaluation functions****************************************************
322  template< typename Other > inline bool isAliased( const Other* alias ) const;
323  inline IntrinsicType get ( size_t i, size_t j ) const;
324 
325  template< typename MT >
326  inline typename DisableIf< VectorizedAssign<MT> >::Type
327  assign( const DenseMatrix<MT,SO>& rhs );
328 
329  template< typename MT >
330  inline typename EnableIf< VectorizedAssign<MT> >::Type
331  assign( const DenseMatrix<MT,SO>& rhs );
332 
333  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
334  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
335  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
336 
337  template< typename MT >
338  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
339  addAssign( const DenseMatrix<MT,SO>& rhs );
340 
341  template< typename MT >
342  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
343  addAssign( const DenseMatrix<MT,SO>& rhs );
344 
345  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
346  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
347  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
348 
349  template< typename MT >
350  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
351  subAssign( const DenseMatrix<MT,SO>& rhs );
352 
353  template< typename MT >
354  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
355  subAssign( const DenseMatrix<MT,SO>& rhs );
356 
357  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
358  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
359  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
361  //**********************************************************************************************
362 
363  private:
364  //**Utility functions***************************************************************************
367  inline size_t adjustColumns( size_t minColumns ) const;
369  //**********************************************************************************************
370 
371  //**Member variables****************************************************************************
374  size_t m_;
375  size_t n_;
376  size_t nn_;
377  size_t capacity_;
378  Type* BLAZE_RESTRICT v_;
379 
389  //**********************************************************************************************
390 
391  //**Compile time checks*************************************************************************
398  //**********************************************************************************************
399 };
400 //*************************************************************************************************
401 
402 
403 
404 
405 //=================================================================================================
406 //
407 // CONSTRUCTORS
408 //
409 //=================================================================================================
410 
411 //*************************************************************************************************
414 template< typename Type // Data type of the matrix
415  , bool SO > // Storage order
417  : m_ ( 0UL ) // The current number of rows of the matrix
418  , n_ ( 0UL ) // The current number of columns of the matrix
419  , nn_ ( 0UL ) // The alignment adjusted number of columns
420  , capacity_( 0UL ) // The maximum capacity of the matrix
421  , v_ ( NULL ) // The matrix elements
422 {}
423 //*************************************************************************************************
424 
425 
426 //*************************************************************************************************
435 template< typename Type // Data type of the matrix
436  , bool SO > // Storage order
437 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n )
438  : m_ ( m ) // The current number of rows of the matrix
439  , n_ ( n ) // The current number of columns of the matrix
440  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
441  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
442  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
443 {
444  if( IsBuiltin<Type>::value ) {
445  for( size_t i=0UL; i<m_; ++i ) {
446  for( size_t j=n_; j<nn_; ++j )
447  v_[i*nn_+j] = Type();
448  }
449  }
450 }
451 //*************************************************************************************************
452 
453 
454 //*************************************************************************************************
463 template< typename Type // Data type of the matrix
464  , bool SO > // Storage order
465 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, Type init )
466  : m_ ( m ) // The current number of rows of the matrix
467  , n_ ( n ) // The current number of columns of the matrix
468  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
469  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
470  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
471 {
472  for( size_t i=0UL; i<m; ++i ) {
473  for( size_t j=0UL; j<n_; ++j )
474  v_[i*nn_+j] = init;
475 
476  if( IsBuiltin<Type>::value ) {
477  for( size_t j=n_; j<nn_; ++j )
478  v_[i*nn_+j] = Type();
479  }
480  }
481 }
482 //*************************************************************************************************
483 
484 
485 //*************************************************************************************************
493 template< typename Type // Data type of the matrix
494  , bool SO > // Storage order
496  : m_ ( m.m_ ) // The current number of rows of the matrix
497  , n_ ( m.n_ ) // The current number of columns of the matrix
498  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
499  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
500  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
501 {
502  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
503 
504  for( size_t i=0UL; i<capacity_; ++i )
505  v_[i] = m.v_[i];
506 }
507 //*************************************************************************************************
508 
509 
510 //*************************************************************************************************
515 template< typename Type // Data type of the matrix
516  , bool SO > // Storage order
517 template< typename MT // Type of the foreign matrix
518  , bool SO2 > // Storage order of the foreign matrix
520  : m_ ( (~m).rows() ) // The current number of rows of the matrix
521  , n_ ( (~m).columns() ) // The current number of columns of the matrix
522  , nn_ ( adjustColumns( n_ ) ) // The alignment adjusted number of columns
523  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
524  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
525 {
526  using blaze::assign;
527 
528  if( IsBuiltin<Type>::value ) {
529  for( size_t i=0UL; i<m_; ++i ) {
530  for( size_t j=( IsSparseMatrix<MT>::value )?( 0UL ):( n_ ); j<nn_; ++j )
531  v_[i*nn_+j] = Type();
532  }
533  }
534 
535  assign( *this, ~m );
536 }
537 //*************************************************************************************************
538 
539 
540 //*************************************************************************************************
558 template< typename Type // Data type of the matrix
559  , bool SO > // Storage order
560 template< typename Other // Data type of the initialization array
561  , size_t M // Number of rows of the initialization array
562  , size_t N > // Number of columns of the initialization array
563 inline DynamicMatrix<Type,SO>::DynamicMatrix( const Other (&rhs)[M][N] )
564  : m_ ( M ) // The current number of rows of the matrix
565  , n_ ( N ) // The current number of columns of the matrix
566  , nn_ ( adjustColumns( N ) ) // The alignment adjusted number of columns
567  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
568  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
569 {
570  for( size_t i=0UL; i<M; ++i ) {
571  for( size_t j=0UL; j<N; ++j )
572  v_[i*nn_+j] = rhs[i][j];
573 
574  if( IsBuiltin<Type>::value ) {
575  for( size_t j=N; j<nn_; ++j )
576  v_[i*nn_+j] = Type();
577  }
578  }
579 }
580 //*************************************************************************************************
581 
582 
583 
584 
585 //=================================================================================================
586 //
587 // DESTRUCTOR
588 //
589 //=================================================================================================
590 
591 //*************************************************************************************************
594 template< typename Type // Data type of the matrix
595  , bool SO > // Storage order
597 {
598  deallocate( v_ );
599 }
600 //*************************************************************************************************
601 
602 
603 
604 
605 //=================================================================================================
606 //
607 // DATA ACCESS FUNCTIONS
608 //
609 //=================================================================================================
610 
611 //*************************************************************************************************
618 template< typename Type // Data type of the matrix
619  , bool SO > // Storage order
620 inline typename DynamicMatrix<Type,SO>::Reference
622 {
623  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
624  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
625  return v_[i*nn_+j];
626 }
627 //*************************************************************************************************
628 
629 
630 //*************************************************************************************************
637 template< typename Type // Data type of the matrix
638  , bool SO > // Storage order
640  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) const
641 {
642  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
643  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
644  return v_[i*nn_+j];
645 }
646 //*************************************************************************************************
647 
648 
649 //*************************************************************************************************
654 template< typename Type // Data type of the matrix
655  , bool SO > // Storage order
657 {
658  return v_;
659 }
660 //*************************************************************************************************
661 
662 
663 //*************************************************************************************************
668 template< typename Type // Data type of the matrix
669  , bool SO > // Storage order
670 inline const Type* DynamicMatrix<Type,SO>::data() const
671 {
672  return v_;
673 }
674 //*************************************************************************************************
675 
676 
677 //*************************************************************************************************
688 template< typename Type // Data type of the matrix
689  , bool SO > // Storage order
690 inline typename DynamicMatrix<Type,SO>::Iterator
692 {
693  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
694  return v_ + i*nn_;
695 }
696 //*************************************************************************************************
697 
698 
699 //*************************************************************************************************
710 template< typename Type // Data type of the matrix
711  , bool SO > // Storage order
714 {
715  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
716  return v_ + i*nn_;
717 }
718 //*************************************************************************************************
719 
720 
721 //*************************************************************************************************
732 template< typename Type // Data type of the matrix
733  , bool SO > // Storage order
736 {
737  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
738  return v_ + i*nn_;
739 }
740 //*************************************************************************************************
741 
742 
743 //*************************************************************************************************
754 template< typename Type // Data type of the matrix
755  , bool SO > // Storage order
756 inline typename DynamicMatrix<Type,SO>::Iterator
758 {
759  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
760  return v_ + i*nn_ + n_;
761 }
762 //*************************************************************************************************
763 
764 
765 //*************************************************************************************************
776 template< typename Type // Data type of the matrix
777  , bool SO > // Storage order
779  DynamicMatrix<Type,SO>::end( size_t i ) const
780 {
781  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
782  return v_ + i*nn_ + n_;
783 }
784 //*************************************************************************************************
785 
786 
787 //*************************************************************************************************
798 template< typename Type // Data type of the matrix
799  , bool SO > // Storage order
802 {
803  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
804  return v_ + i*nn_ + n_;
805 }
806 //*************************************************************************************************
807 
808 
809 
810 
811 //=================================================================================================
812 //
813 // ASSIGNMENT OPERATORS
814 //
815 //=================================================================================================
816 
817 //*************************************************************************************************
836 template< typename Type // Data type of the matrix
837  , bool SO > // Storage order
838 template< typename Other // Data type of the initialization array
839  , size_t M // Number of rows of the initialization array
840  , size_t N > // Number of columns of the initialization array
842 {
843  resize( M, N, false );
844 
845  for( size_t i=0UL; i<M; ++i )
846  for( size_t j=0UL; j<N; ++j )
847  v_[i*nn_+j] = rhs[i][j];
848 
849  return *this;
850 }
851 //*************************************************************************************************
852 
853 
854 //*************************************************************************************************
860 template< typename Type // Data type of the matrix
861  , bool SO > // Storage order
863 {
864  for( size_t i=0UL; i<m_; ++i )
865  for( size_t j=0UL; j<n_; ++j )
866  v_[i*nn_+j] = rhs;
867 
868  return *this;
869 }
870 //*************************************************************************************************
871 
872 
873 //*************************************************************************************************
882 template< typename Type // Data type of the matrix
883  , bool SO > // Storage order
885 {
886  if( &rhs == this ) return *this;
887 
888  resize( rhs.m_, rhs.n_, false );
889 
890  for( size_t i=0UL; i<m_; ++i )
891  for( size_t j=0UL; j<n_; ++j )
892  v_[i*nn_+j] = rhs(i,j);
893 
894  return *this;
895 }
896 //*************************************************************************************************
897 
898 
899 //*************************************************************************************************
908 template< typename Type // Data type of the matrix
909  , bool SO > // Storage order
910 template< typename MT // Type of the right-hand side matrix
911  , bool SO2 > // Storage order of the right-hand side matrix
913 {
914  using blaze::assign;
915 
916  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
917  DynamicMatrix tmp( ~rhs );
918  swap( tmp );
919  }
920  else {
921  resize( (~rhs).rows(), (~rhs).columns(), false );
923  reset();
924  assign( *this, ~rhs );
925  }
926 
927  return *this;
928 }
929 //*************************************************************************************************
930 
931 
932 //*************************************************************************************************
942 template< typename Type // Data type of the matrix
943  , bool SO > // Storage order
944 template< typename MT // Type of the right-hand side matrix
945  , bool SO2 > // Storage order of the right-hand side matrix
947 {
948  using blaze::addAssign;
949 
950  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
951  throw std::invalid_argument( "Matrix sizes do not match" );
952 
953  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
954  typename MT::ResultType tmp( ~rhs );
955  addAssign( *this, tmp );
956  }
957  else {
958  addAssign( *this, ~rhs );
959  }
960 
961  return *this;
962 }
963 //*************************************************************************************************
964 
965 
966 //*************************************************************************************************
976 template< typename Type // Data type of the matrix
977  , bool SO > // Storage order
978 template< typename MT // Type of the right-hand side matrix
979  , bool SO2 > // Storage order of the right-hand side matrix
981 {
982  using blaze::subAssign;
983 
984  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
985  throw std::invalid_argument( "Matrix sizes do not match" );
986 
987  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
988  typename MT::ResultType tmp( ~rhs );
989  subAssign( *this, tmp );
990  }
991  else {
992  subAssign( *this, ~rhs );
993  }
994 
995  return *this;
996 }
997 //*************************************************************************************************
998 
999 
1000 //*************************************************************************************************
1010 template< typename Type // Data type of the matrix
1011  , bool SO > // Storage order
1012 template< typename MT // Type of the right-hand side matrix
1013  , bool SO2 > // Storage order of the right-hand side matrix
1015 {
1016  if( (~rhs).rows() != n_ )
1017  throw std::invalid_argument( "Matrix sizes do not match" );
1018 
1019  DynamicMatrix tmp( *this * (~rhs) );
1020  swap( tmp );
1021 
1022  return *this;
1023 }
1024 //*************************************************************************************************
1025 
1026 
1027 //*************************************************************************************************
1034 template< typename Type // Data type of the matrix
1035  , bool SO > // Storage order
1036 template< typename Other > // Data type of the right-hand side scalar
1037 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,SO> >::Type&
1039 {
1040  return operator=( (*this) * rhs );
1041 }
1042 //*************************************************************************************************
1043 
1044 
1045 //*************************************************************************************************
1052 template< typename Type // Data type of the matrix
1053  , bool SO > // Storage order
1054 template< typename Other > // Data type of the right-hand side scalar
1055 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,SO> >::Type&
1057 {
1058  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1059 
1060  return operator=( (*this) / rhs );
1061 }
1062 //*************************************************************************************************
1063 
1064 
1065 
1066 
1067 //=================================================================================================
1068 //
1069 // UTILITY FUNCTIONS
1070 //
1071 //=================================================================================================
1072 
1073 //*************************************************************************************************
1078 template< typename Type // Data type of the matrix
1079  , bool SO > // Storage order
1080 inline size_t DynamicMatrix<Type,SO>::rows() const
1081 {
1082  return m_;
1083 }
1084 //*************************************************************************************************
1085 
1086 
1087 //*************************************************************************************************
1092 template< typename Type // Data type of the matrix
1093  , bool SO > // Storage order
1094 inline size_t DynamicMatrix<Type,SO>::columns() const
1095 {
1096  return n_;
1097 }
1098 //*************************************************************************************************
1099 
1100 
1101 //*************************************************************************************************
1109 template< typename Type // Data type of the matrix
1110  , bool SO > // Storage order
1111 inline size_t DynamicMatrix<Type,SO>::spacing() const
1112 {
1113  return nn_;
1114 }
1115 //*************************************************************************************************
1116 
1117 
1118 //*************************************************************************************************
1123 template< typename Type // Data type of the matrix
1124  , bool SO > // Storage order
1126 {
1127  return capacity_;
1128 }
1129 //*************************************************************************************************
1130 
1131 
1132 //*************************************************************************************************
1137 template< typename Type // Data type of the matrix
1138  , bool SO > // Storage order
1140 {
1141  size_t nonzeros( 0UL );
1142 
1143  for( size_t i=0UL; i<m_; ++i )
1144  for( size_t j=0UL; j<n_; ++j )
1145  if( !isDefault( v_[i*nn_+j] ) )
1146  ++nonzeros;
1147 
1148  return nonzeros;
1149 }
1150 //*************************************************************************************************
1151 
1152 
1153 //*************************************************************************************************
1159 template< typename Type // Data type of the matrix
1160  , bool SO > // Storage order
1161 inline size_t DynamicMatrix<Type,SO>::nonZeros( size_t i ) const
1162 {
1163  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1164 
1165  const size_t jend( (i+1UL)*nn_ );
1166  size_t nonzeros( 0UL );
1167 
1168  for( size_t j=i*nn_; j<jend; ++j )
1169  if( !isDefault( v_[j] ) )
1170  ++nonzeros;
1171 
1172  return nonzeros;
1173 }
1174 //*************************************************************************************************
1175 
1176 
1177 //*************************************************************************************************
1182 template< typename Type // Data type of the matrix
1183  , bool SO > // Storage order
1185 {
1186  using blaze::reset;
1187  for( size_t i=0UL; i<m_; ++i )
1188  for( size_t j=0UL; j<n_; ++j )
1189  reset( v_[i*nn_+j] );
1190 }
1191 //*************************************************************************************************
1192 
1193 
1194 //*************************************************************************************************
1201 template< typename Type // Data type of the matrix
1202  , bool SO > // Storage order
1204 {
1205  m_ = 0UL;
1206  n_ = 0UL;
1207  nn_ = 0UL;
1208 }
1209 //*************************************************************************************************
1210 
1211 
1212 //*************************************************************************************************
1244 template< typename Type // Data type of the matrix
1245  , bool SO > // Storage order
1246 void DynamicMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1247 {
1248  using blaze::min;
1249 
1250  if( m == m_ && n == n_ ) return;
1251 
1252  const size_t nn( adjustColumns( n ) );
1253 
1254  if( preserve )
1255  {
1256  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1257  const size_t min_m( min( m, m_ ) );
1258  const size_t min_n( min( n, n_ ) );
1259 
1260  for( size_t i=0UL; i<min_m; ++i )
1261  for( size_t j=0UL; j<min_n; ++j )
1262  v[i*nn+j] = v_[i*nn_+j];
1263 
1264  if( IsBuiltin<Type>::value ) {
1265  for( size_t i=0UL; i<m; ++i )
1266  for( size_t j=n; j<nn; ++j )
1267  v[i*nn+j] = Type();
1268  }
1269 
1270  std::swap( v_, v );
1271  deallocate( v );
1272  capacity_ = m*nn;
1273  }
1274  else if( m*nn > capacity_ ) {
1275  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1276 
1277  if( IsBuiltin<Type>::value ) {
1278  for( size_t i=0UL; i<m; ++i )
1279  for( size_t j=n; j<nn; ++j )
1280  v[i*nn+j] = Type();
1281  }
1282 
1283  std::swap( v_, v );
1284  deallocate( v );
1285  capacity_ = m*nn;
1286  }
1287 
1288  m_ = m;
1289  n_ = n;
1290  nn_ = nn;
1291 }
1292 //*************************************************************************************************
1293 
1294 
1295 //*************************************************************************************************
1309 template< typename Type // Data type of the matrix
1310  , bool SO > // Storage order
1311 inline void DynamicMatrix<Type,SO>::extend( size_t m, size_t n, bool preserve )
1312 {
1313  resize( m_+m, n_+n, preserve );
1314 }
1315 //*************************************************************************************************
1316 
1317 
1318 //*************************************************************************************************
1327 template< typename Type // Data type of the matrix
1328  , bool SO > // Storage order
1329 inline void DynamicMatrix<Type,SO>::reserve( size_t elements )
1330 {
1331  if( elements > capacity_ )
1332  {
1333  // Allocating a new array
1334  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
1335 
1336  // Initializing the new array
1337  std::copy( v_, v_+capacity_, tmp );
1338 
1339  if( IsBuiltin<Type>::value ) {
1340  for( size_t i=capacity_; i<elements; ++i )
1341  tmp[i] = Type();
1342  }
1343 
1344  // Replacing the old array
1345  std::swap( tmp, v_ );
1346  deallocate( tmp );
1347  capacity_ = elements;
1348  }
1349 }
1350 //*************************************************************************************************
1351 
1352 
1353 //*************************************************************************************************
1358 template< typename Type // Data type of the matrix
1359  , bool SO > // Storage order
1361 {
1362  DynamicMatrix tmp( trans(*this) );
1363  swap( tmp );
1364  return *this;
1365 }
1366 //*************************************************************************************************
1367 
1368 
1369 //*************************************************************************************************
1377 template< typename Type // Data type of the matrix
1378  , bool SO > // Storage order
1380 {
1382 
1383  return *this;
1384 }
1385 //*************************************************************************************************
1386 
1387 
1388 //*************************************************************************************************
1405 template< typename Type // Data type of the matrix
1406  , bool SO > // Storage order
1408 {
1409  if( m_ != n_ ) return false;
1410 
1411  for( size_t i=1UL; i<m_; ++i ) {
1412  for( size_t j=0UL; j<i; ++j ) {
1413  if( !isDefault( v_[i*nn_+j] ) || !isDefault( v_[j*nn_+i] ) )
1414  return false;
1415  }
1416  }
1417 
1418  return true;
1419 }
1420 //*************************************************************************************************
1421 
1422 
1423 //*************************************************************************************************
1428 template< typename Type // Data type of the matrix
1429  , bool SO > // Storage order
1431 {
1432  if( m_ != n_ ) return false;
1433 
1434  for( size_t i=1UL; i<m_; ++i ) {
1435  for( size_t j=0UL; j<i; ++j ) {
1436  if( !equal( v_[i*nn_+j], v_[j*nn_+i] ) )
1437  return false;
1438  }
1439  }
1440 
1441  return true;
1442 }
1443 //*************************************************************************************************
1444 
1445 
1446 //*************************************************************************************************
1452 template< typename Type // Data type of the matrix
1453  , bool SO > // Storage order
1454 template< typename Other > // Data type of the scalar value
1456 {
1457  for( size_t i=0UL; i<m_; ++i )
1458  for( size_t j=0UL; j<n_; ++j )
1459  v_[i*nn_+j] *= scalar;
1460 
1461  return *this;
1462 }
1463 //*************************************************************************************************
1464 
1465 
1466 //*************************************************************************************************
1473 template< typename Type // Data type of the matrix
1474  , bool SO > // Storage order
1475 inline void DynamicMatrix<Type,SO>::swap( DynamicMatrix& m ) /* throw() */
1476 {
1477  std::swap( m_ , m.m_ );
1478  std::swap( n_ , m.n_ );
1479  std::swap( nn_, m.nn_ );
1480  std::swap( capacity_, m.capacity_ );
1481  std::swap( v_ , m.v_ );
1482 }
1483 //*************************************************************************************************
1484 
1485 
1486 //*************************************************************************************************
1492 template< typename Type // Data type of the matrix
1493  , bool SO > // Storage order
1494 inline size_t DynamicMatrix<Type,SO>::adjustColumns( size_t minColumns ) const
1495 {
1497  return minColumns + ( IT::size - ( minColumns % IT::size ) ) % IT::size;
1498  else return minColumns;
1499 }
1500 //*************************************************************************************************
1501 
1502 
1503 
1504 
1505 //=================================================================================================
1506 //
1507 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1508 //
1509 //=================================================================================================
1510 
1511 //*************************************************************************************************
1517 template< typename Type // Data type of the matrix
1518  , bool SO > // Storage order
1519 template< typename Other > // Data type of the foreign expression
1520 inline bool DynamicMatrix<Type,SO>::isAliased( const Other* alias ) const
1521 {
1522  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1523 }
1524 //*************************************************************************************************
1525 
1526 
1527 //*************************************************************************************************
1539 template< typename Type // Data type of the matrix
1540  , bool SO > // Storage order
1542  DynamicMatrix<Type,SO>::get( size_t i, size_t j ) const
1543 {
1545 
1546  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
1547  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
1548  BLAZE_INTERNAL_ASSERT( j + IT::size <= nn_, "Invalid column access index" );
1549  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
1550 
1551  return load( &v_[i*nn_+j] );
1552 }
1553 //*************************************************************************************************
1554 
1555 
1556 //*************************************************************************************************
1567 template< typename Type // Data type of the matrix
1568  , bool SO > // Storage order
1569 template< typename MT > // Type of the right-hand side dense matrix
1570 inline typename DisableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
1572 {
1573  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1574  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1575 
1576  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == ( n_ & size_t(-2) ), "Invalid end calculation" );
1577  const size_t jend( n_ & size_t(-2) );
1578 
1579  for( size_t i=0UL; i<m_; ++i ) {
1580  for( size_t j=0UL; j<jend; j+=2UL ) {
1581  v_[i*nn_+j ] = (~rhs)(i,j );
1582  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
1583  }
1584  if( jend < n_ ) {
1585  v_[i*nn_+jend] = (~rhs)(i,jend);
1586  }
1587  }
1588 }
1589 //*************************************************************************************************
1590 
1591 
1592 //*************************************************************************************************
1603 template< typename Type // Data type of the matrix
1604  , bool SO > // Storage order
1605 template< typename MT > // Type of the right-hand side dense matrix
1606 inline typename EnableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
1608 {
1609  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1610  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1611 
1613 
1614  if( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
1615  {
1616  for( size_t i=0UL; i<m_; ++i )
1617  for( size_t j=0UL; j<n_; j+=IT::size )
1618  stream( &v_[i*nn_+j], (~rhs).get(i,j) );
1619  }
1620  else
1621  {
1622  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == ( n_ & size_t(-IT::size*4) ), "Invalid end calculation" );
1623  const size_t jend( n_ & size_t(-IT::size*4) );
1624 
1625  for( size_t i=0UL; i<m_; ++i ) {
1626  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1627  store( &v_[i*nn_+j ], (~rhs).get(i,j ) );
1628  store( &v_[i*nn_+j+IT::size ], (~rhs).get(i,j+IT::size ) );
1629  store( &v_[i*nn_+j+IT::size*2UL], (~rhs).get(i,j+IT::size*2UL) );
1630  store( &v_[i*nn_+j+IT::size*3UL], (~rhs).get(i,j+IT::size*3UL) );
1631  }
1632  for( size_t j=jend; j<n_; j+=IT::size ) {
1633  store( &v_[i*nn_+j], (~rhs).get(i,j) );
1634  }
1635  }
1636  }
1637 }
1638 //*************************************************************************************************
1639 
1640 
1641 //*************************************************************************************************
1652 template< typename Type // Data type of the matrix
1653  , bool SO > // Storage order
1654 template< typename MT > // Type of the right-hand side dense matrix
1656 {
1657  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1658  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1659 
1660  const size_t block( 16UL );
1661 
1662  for( size_t ii=0UL; ii<m_; ii+=block ) {
1663  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
1664  for( size_t jj=0UL; jj<n_; jj+=block ) {
1665  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
1666  for( size_t i=ii; i<iend; ++i ) {
1667  for( size_t j=jj; j<jend; ++j ) {
1668  v_[i*nn_+j] = (~rhs)(i,j);
1669  }
1670  }
1671  }
1672  }
1673 }
1674 //*************************************************************************************************
1675 
1676 
1677 //*************************************************************************************************
1688 template< typename Type // Data type of the matrix
1689  , bool SO > // Storage order
1690 template< typename MT > // Type of the right-hand side sparse matrix
1692 {
1693  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1694  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1695 
1696  for( size_t i=0UL; i<m_; ++i )
1697  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1698  v_[i*nn_+element->index()] = element->value();
1699 }
1700 //*************************************************************************************************
1701 
1702 
1703 //*************************************************************************************************
1714 template< typename Type // Data type of the matrix
1715  , bool SO > // Storage order
1716 template< typename MT > // Type of the right-hand side sparse matrix
1718 {
1719  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1720  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1721 
1722  for( size_t j=0UL; j<n_; ++j )
1723  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1724  v_[element->index()*nn_+j] = element->value();
1725 }
1726 //*************************************************************************************************
1727 
1728 
1729 //*************************************************************************************************
1740 template< typename Type // Data type of the matrix
1741  , bool SO > // Storage order
1742 template< typename MT > // Type of the right-hand side dense matrix
1743 inline typename DisableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
1745 {
1746  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1747  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1748 
1749  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == ( n_ & size_t(-2) ), "Invalid end calculation" );
1750  const size_t jend( n_ & size_t(-2) );
1751 
1752  for( size_t i=0UL; i<m_; ++i ) {
1753  for( size_t j=0UL; j<jend; j+=2UL ) {
1754  v_[i*nn_+j ] += (~rhs)(i,j );
1755  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
1756  }
1757  if( jend < n_ ) {
1758  v_[i*nn_+jend] += (~rhs)(i,jend);
1759  }
1760  }
1761 }
1762 //*************************************************************************************************
1763 
1764 
1765 //*************************************************************************************************
1776 template< typename Type // Data type of the matrix
1777  , bool SO > // Storage order
1778 template< typename MT > // Type of the right-hand side dense matrix
1779 inline typename EnableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
1781 {
1782  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1783  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1784 
1786 
1787  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == ( n_ & size_t(-IT::size*4) ), "Invalid end calculation" );
1788  const size_t jend( n_ & size_t(-IT::size*4) );
1789 
1790  for( size_t i=0UL; i<m_; ++i ) {
1791  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1792  store( &v_[i*nn_+j ], load( &v_[i*nn_+j ] ) + (~rhs).get(i,j ) );
1793  store( &v_[i*nn_+j+IT::size ], load( &v_[i*nn_+j+IT::size ] ) + (~rhs).get(i,j+IT::size ) );
1794  store( &v_[i*nn_+j+IT::size*2UL], load( &v_[i*nn_+j+IT::size*2UL] ) + (~rhs).get(i,j+IT::size*2UL) );
1795  store( &v_[i*nn_+j+IT::size*3UL], load( &v_[i*nn_+j+IT::size*3UL] ) + (~rhs).get(i,j+IT::size*3UL) );
1796  }
1797  for( size_t j=jend; j<n_; j+=IT::size ) {
1798  store( &v_[i*nn_+j], load( &v_[i*nn_+j] ) + (~rhs).get(i,j) );
1799  }
1800  }
1801 }
1802 //*************************************************************************************************
1803 
1804 
1805 //*************************************************************************************************
1816 template< typename Type // Data type of the matrix
1817  , bool SO > // Storage order
1818 template< typename MT > // Type of the right-hand side dense matrix
1820 {
1821  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1822  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1823 
1824  const size_t block( 16UL );
1825 
1826  for( size_t ii=0UL; ii<m_; ii+=block ) {
1827  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
1828  for( size_t jj=0UL; jj<n_; jj+=block ) {
1829  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
1830  for( size_t i=ii; i<iend; ++i ) {
1831  for( size_t j=jj; j<jend; ++j ) {
1832  v_[i*nn_+j] += (~rhs)(i,j);
1833  }
1834  }
1835  }
1836  }
1837 }
1838 //*************************************************************************************************
1839 
1840 
1841 //*************************************************************************************************
1852 template< typename Type // Data type of the matrix
1853  , bool SO > // Storage order
1854 template< typename MT > // Type of the right-hand side sparse matrix
1856 {
1857  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1858  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1859 
1860  for( size_t i=0UL; i<m_; ++i )
1861  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1862  v_[i*nn_+element->index()] += element->value();
1863 }
1864 //*************************************************************************************************
1865 
1866 
1867 //*************************************************************************************************
1878 template< typename Type // Data type of the matrix
1879  , bool SO > // Storage order
1880 template< typename MT > // Type of the right-hand side sparse matrix
1882 {
1883  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1884  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1885 
1886  for( size_t j=0UL; j<n_; ++j )
1887  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1888  v_[element->index()*nn_+j] += element->value();
1889 }
1890 //*************************************************************************************************
1891 
1892 
1893 //*************************************************************************************************
1904 template< typename Type // Data type of the matrix
1905  , bool SO > // Storage order
1906 template< typename MT > // Type of the right-hand side dense matrix
1907 inline typename DisableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
1909 {
1910  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1911  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1912 
1913  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == ( n_ & size_t(-2) ), "Invalid end calculation" );
1914  const size_t jend( n_ & size_t(-2) );
1915 
1916  for( size_t i=0UL; i<m_; ++i ) {
1917  for( size_t j=0UL; j<jend; j+=2UL ) {
1918  v_[i*nn_+j ] -= (~rhs)(i,j );
1919  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
1920  }
1921  if( jend < n_ ) {
1922  v_[i*nn_+jend] -= (~rhs)(i,jend);
1923  }
1924  }
1925 }
1926 //*************************************************************************************************
1927 
1928 
1929 //*************************************************************************************************
1940 template< typename Type // Data type of the matrix
1941  , bool SO > // Storage order
1942 template< typename MT > // Type of the right-hand side dense matrix
1943 inline typename EnableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
1945 {
1946  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1947  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1948 
1950 
1951  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == ( n_ & size_t(-IT::size*4) ), "Invalid end calculation" );
1952  const size_t jend( n_ & size_t(-IT::size*4) );
1953 
1954  for( size_t i=0UL; i<m_; ++i ) {
1955  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1956  store( &v_[i*nn_+j ], load( &v_[i*nn_+j ] ) - (~rhs).get(i,j ) );
1957  store( &v_[i*nn_+j+IT::size ], load( &v_[i*nn_+j+IT::size ] ) - (~rhs).get(i,j+IT::size ) );
1958  store( &v_[i*nn_+j+IT::size*2UL], load( &v_[i*nn_+j+IT::size*2UL] ) - (~rhs).get(i,j+IT::size*2UL) );
1959  store( &v_[i*nn_+j+IT::size*3UL], load( &v_[i*nn_+j+IT::size*3UL] ) - (~rhs).get(i,j+IT::size*3UL) );
1960  }
1961  for( size_t j=jend; j<n_; j+=IT::size ) {
1962  store( &v_[i*nn_+j], load( &v_[i*nn_+j] ) - (~rhs).get(i,j) );
1963  }
1964  }
1965 }
1966 //*************************************************************************************************
1967 
1968 
1969 //*************************************************************************************************
1980 template< typename Type // Data type of the matrix
1981  , bool SO > // Storage order
1982 template< typename MT > // Type of the right-hand side dense matrix
1984 {
1985  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1986  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1987 
1988  const size_t block( 16UL );
1989 
1990  for( size_t ii=0UL; ii<m_; ii+=block ) {
1991  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
1992  for( size_t jj=0UL; jj<n_; jj+=block ) {
1993  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
1994  for( size_t i=ii; i<iend; ++i ) {
1995  for( size_t j=jj; j<jend; ++j ) {
1996  v_[i*nn_+j] -= (~rhs)(i,j);
1997  }
1998  }
1999  }
2000  }
2001 }
2002 //*************************************************************************************************
2003 
2004 
2005 //*************************************************************************************************
2016 template< typename Type // Data type of the matrix
2017  , bool SO > // Storage order
2018 template< typename MT > // Type of the right-hand side sparse matrix
2020 {
2021  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2022  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2023 
2024  for( size_t i=0UL; i<m_; ++i )
2025  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2026  v_[i*nn_+element->index()] -= element->value();
2027 }
2028 //*************************************************************************************************
2029 
2030 
2031 //*************************************************************************************************
2042 template< typename Type // Data type of the matrix
2043  , bool SO > // Storage order
2044 template< typename MT > // Type of the right-hand side sparse matrix
2046 {
2047  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2048  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2049 
2050  for( size_t j=0UL; j<n_; ++j )
2051  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2052  v_[element->index()*nn_+j] -= element->value();
2053 }
2054 //*************************************************************************************************
2055 
2056 
2057 
2058 
2059 
2060 
2061 
2062 
2063 //=================================================================================================
2064 //
2065 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2066 //
2067 //=================================================================================================
2068 
2069 //*************************************************************************************************
2077 template< typename Type > // Data type of the matrix
2078 class DynamicMatrix<Type,true> : public DenseMatrix< DynamicMatrix<Type,true>, true >
2079 {
2080  private:
2081  //**Type definitions****************************************************************************
2082  typedef IntrinsicTrait<Type> IT;
2083  //**********************************************************************************************
2084 
2085  public:
2086  //**Type definitions****************************************************************************
2087  typedef DynamicMatrix<Type,true> This;
2088  typedef This ResultType;
2091  typedef Type ElementType;
2092  typedef const Type& ReturnType;
2093  typedef typename IT::Type IntrinsicType;
2094  typedef const This& CompositeType;
2095  typedef Type& Reference;
2096  typedef const Type& ConstReference;
2097  typedef Type* Iterator;
2098  typedef const Type* ConstIterator;
2099  //**********************************************************************************************
2100 
2101  //**Compilation flags***************************************************************************
2103 
2107  enum { vectorizable = IsVectorizable<Type>::value };
2108 
2110 
2113  enum { canAlias = 0 };
2114  //**********************************************************************************************
2115 
2116  //**Constructors********************************************************************************
2119  explicit inline DynamicMatrix();
2120  explicit inline DynamicMatrix( size_t m, size_t n );
2121  explicit inline DynamicMatrix( size_t m, size_t n, Type init );
2122  inline DynamicMatrix( const DynamicMatrix& m );
2123  template< typename MT, bool SO > inline DynamicMatrix( const Matrix<MT,SO>& m );
2124 
2125  template< typename Other, size_t M, size_t N >
2126  inline DynamicMatrix( const Other (&rhs)[M][N] );
2128  //**********************************************************************************************
2129 
2130  //**Destructor**********************************************************************************
2133  inline ~DynamicMatrix();
2135  //**********************************************************************************************
2136 
2137  //**Data access functions***********************************************************************
2140  inline Reference operator()( size_t i, size_t j );
2141  inline ConstReference operator()( size_t i, size_t j ) const;
2142  inline Type* data();
2143  inline const Type* data() const;
2144  inline Iterator begin ( size_t i );
2145  inline ConstIterator begin ( size_t i ) const;
2146  inline ConstIterator cbegin( size_t i ) const;
2147  inline Iterator end ( size_t i );
2148  inline ConstIterator end ( size_t i ) const;
2149  inline ConstIterator cend ( size_t i ) const;
2151  //**********************************************************************************************
2152 
2153  //**Assignment operators************************************************************************
2156  template< typename Other, size_t M, size_t N >
2157  inline DynamicMatrix& operator=( const Other (&rhs)[M][N] );
2158 
2159  inline DynamicMatrix& operator= ( Type set );
2160  inline DynamicMatrix& operator= ( const DynamicMatrix& set );
2161  template< typename MT, bool SO > inline DynamicMatrix& operator= ( const Matrix<MT,SO>& rhs );
2162  template< typename MT, bool SO > inline DynamicMatrix& operator+=( const Matrix<MT,SO>& rhs );
2163  template< typename MT, bool SO > inline DynamicMatrix& operator-=( const Matrix<MT,SO>& rhs );
2164  template< typename MT, bool SO > inline DynamicMatrix& operator*=( const Matrix<MT,SO>& rhs );
2165 
2166  template< typename Other >
2167  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
2168  operator*=( Other rhs );
2169 
2170  template< typename Other >
2171  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
2172  operator/=( Other rhs );
2174  //**********************************************************************************************
2175 
2176  //**Utility functions***************************************************************************
2179  inline size_t rows() const;
2180  inline size_t columns() const;
2181  inline size_t spacing() const;
2182  inline size_t capacity() const;
2183  inline size_t nonZeros() const;
2184  inline size_t nonZeros( size_t j ) const;
2185  inline void reset();
2186  inline void clear();
2187  void resize ( size_t m, size_t n, bool preserve=true );
2188  inline void extend ( size_t m, size_t n, bool preserve=true );
2189  inline void reserve( size_t elements );
2190  inline DynamicMatrix& transpose();
2191  inline DynamicMatrix& invert();
2192  inline bool isDiagonal() const;
2193  inline bool isSymmetric() const;
2194  template< typename Other > inline DynamicMatrix& scale( Other scalar );
2195  inline void swap( DynamicMatrix& m ) /* throw() */;
2197  //**********************************************************************************************
2198 
2199  private:
2200  //**********************************************************************************************
2202  template< typename MT >
2203  struct VectorizedAssign {
2204  enum { value = vectorizable && MT::vectorizable &&
2205  IsSame<Type,typename MT::ElementType>::value };
2206  };
2207  //**********************************************************************************************
2208 
2209  //**********************************************************************************************
2211  template< typename MT >
2212  struct VectorizedAddAssign {
2213  enum { value = vectorizable && MT::vectorizable &&
2214  IsSame<Type,typename MT::ElementType>::value &&
2215  IntrinsicTrait<Type>::addition };
2216  };
2217  //**********************************************************************************************
2218 
2219  //**********************************************************************************************
2221  template< typename MT >
2222  struct VectorizedSubAssign {
2223  enum { value = vectorizable && MT::vectorizable &&
2224  IsSame<Type,typename MT::ElementType>::value &&
2225  IntrinsicTrait<Type>::subtraction };
2226  };
2227  //**********************************************************************************************
2228 
2229  public:
2230  //**Expression template evaluation functions****************************************************
2233  template< typename Other > inline bool isAliased( const Other* alias ) const;
2234  inline IntrinsicType get ( size_t i, size_t j ) const;
2235 
2236  template< typename MT >
2237  inline typename DisableIf< VectorizedAssign<MT> >::Type
2238  assign( const DenseMatrix<MT,true>& rhs );
2239 
2240  template< typename MT >
2241  inline typename EnableIf< VectorizedAssign<MT> >::Type
2242  assign( const DenseMatrix<MT,true>& rhs );
2243 
2244  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
2245  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
2246  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
2247 
2248  template< typename MT >
2249  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
2250  addAssign( const DenseMatrix<MT,true>& rhs );
2251 
2252  template< typename MT >
2253  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
2254  addAssign( const DenseMatrix<MT,true>& rhs );
2255 
2256  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
2257  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
2258  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
2259 
2260  template< typename MT >
2261  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
2262  subAssign ( const DenseMatrix<MT,true>& rhs );
2263 
2264  template< typename MT >
2265  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
2266  subAssign ( const DenseMatrix<MT,true>& rhs );
2267 
2268  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
2269  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
2270  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
2272  //**********************************************************************************************
2273 
2274  private:
2275  //**Utility functions***************************************************************************
2278  inline size_t adjustRows( size_t minRows ) const;
2280  //**********************************************************************************************
2281 
2282  //**Member variables****************************************************************************
2285  size_t m_;
2286  size_t mm_;
2287  size_t n_;
2288  size_t capacity_;
2289  Type* BLAZE_RESTRICT v_;
2290 
2300  //**********************************************************************************************
2301 
2302  //**Compile time checks*************************************************************************
2307  //**********************************************************************************************
2308 };
2310 //*************************************************************************************************
2311 
2312 
2313 
2314 
2315 //=================================================================================================
2316 //
2317 // CONSTRUCTORS
2318 //
2319 //=================================================================================================
2320 
2321 //*************************************************************************************************
2325 template< typename Type > // Data type of the matrix
2327  : m_ ( 0UL ) // The current number of rows of the matrix
2328  , mm_ ( 0UL ) // The alignment adjusted number of rows
2329  , n_ ( 0UL ) // The current number of columns of the matrix
2330  , capacity_( 0UL ) // The maximum capacity of the matrix
2331  , v_ ( NULL ) // The matrix elements
2332 {}
2334 //*************************************************************************************************
2335 
2336 
2337 //*************************************************************************************************
2347 template< typename Type > // Data type of the matrix
2348 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n )
2349  : m_ ( m ) // The current number of rows of the matrix
2350  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
2351  , n_ ( n ) // The current number of columns of the matrix
2352  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2353  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2354 {
2355  if( IsBuiltin<Type>::value ) {
2356  for( size_t j=0UL; j<n_; ++j )
2357  for( size_t i=m_; i<mm_; ++i ) {
2358  v_[i+j*mm_] = Type();
2359  }
2360  }
2361 }
2363 //*************************************************************************************************
2364 
2365 
2366 //*************************************************************************************************
2376 template< typename Type > // Data type of the matrix
2377 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, Type init )
2378  : m_ ( m ) // The current number of rows of the matrix
2379  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
2380  , n_ ( n ) // The current number of columns of the matrix
2381  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2382  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2383 {
2384  for( size_t j=0UL; j<n_; ++j ) {
2385  for( size_t i=0UL; i<m_; ++i )
2386  v_[i+j*mm_] = init;
2387 
2388  if( IsBuiltin<Type>::value ) {
2389  for( size_t i=m_; i<mm_; ++i )
2390  v_[i+j*mm_] = Type();
2391  }
2392  }
2393 }
2395 //*************************************************************************************************
2396 
2397 
2398 //*************************************************************************************************
2407 template< typename Type > // Data type of the matrix
2408 inline DynamicMatrix<Type,true>::DynamicMatrix( const DynamicMatrix& m )
2409  : m_ ( m.m_ ) // The current number of rows of the matrix
2410  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
2411  , n_ ( m.n_ ) // The current number of columns of the matrix
2412  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2413  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2414 {
2415  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
2416 
2417  for( size_t i=0UL; i<capacity_; ++i )
2418  v_[i] = m.v_[i];
2419 }
2421 //*************************************************************************************************
2422 
2423 
2424 //*************************************************************************************************
2430 template< typename Type > // Data type of the matrix
2431 template< typename MT // Type of the foreign matrix
2432  , bool SO > // Storage order of the foreign matrix
2434  : m_ ( (~m).rows() ) // The current number of rows of the matrix
2435  , mm_ ( adjustRows( m_ ) ) // The alignment adjusted number of rows
2436  , n_ ( (~m).columns() ) // The current number of columns of the matrix
2437  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2438  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2439 {
2440  using blaze::assign;
2441 
2442  if( IsBuiltin<Type>::value ) {
2443  for( size_t j=0UL; j<n_; ++j )
2444  for( size_t i=( IsSparseMatrix<MT>::value )?( 0UL ):( m_ ); i<mm_; ++i ) {
2445  v_[i+j*mm_] = Type();
2446  }
2447  }
2448 
2449  assign( *this, ~m );
2450 }
2452 //*************************************************************************************************
2453 
2454 
2455 //*************************************************************************************************
2476 template< typename Type > // Data type of the matrix
2477 template< typename Other // Data type of the initialization array
2478  , size_t M // Number of rows of the initialization array
2479  , size_t N > // Number of columns of the initialization array
2480 inline DynamicMatrix<Type,true>::DynamicMatrix( const Other (&rhs)[M][N] )
2481  : m_ ( M ) // The current number of rows of the matrix
2482  , mm_ ( adjustRows( M ) ) // The alignment adjusted number of rows
2483  , n_ ( N ) // The current number of columns of the matrix
2484  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2485  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2486 {
2487  for( size_t j=0UL; j<N; ++j ) {
2488  for( size_t i=0UL; i<M; ++i )
2489  v_[i+j*mm_] = rhs[i][j];
2490 
2491  if( IsBuiltin<Type>::value ) {
2492  for( size_t i=M; i<mm_; ++i )
2493  v_[i+j*mm_] = Type();
2494  }
2495  }
2496 }
2498 //*************************************************************************************************
2499 
2500 
2501 
2502 
2503 //=================================================================================================
2504 //
2505 // DESTRUCTOR
2506 //
2507 //=================================================================================================
2508 
2509 //*************************************************************************************************
2513 template< typename Type > // Data type of the matrix
2515 {
2516  deallocate( v_ );
2517 }
2519 //*************************************************************************************************
2520 
2521 
2522 
2523 
2524 //=================================================================================================
2525 //
2526 // DATA ACCESS FUNCTIONS
2527 //
2528 //=================================================================================================
2529 
2530 //*************************************************************************************************
2538 template< typename Type > // Data type of the matrix
2539 inline typename DynamicMatrix<Type,true>::Reference
2540  DynamicMatrix<Type,true>::operator()( size_t i, size_t j )
2541 {
2542  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
2543  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
2544  return v_[i+j*mm_];
2545 }
2547 //*************************************************************************************************
2548 
2549 
2550 //*************************************************************************************************
2558 template< typename Type > // Data type of the matrix
2559 inline typename DynamicMatrix<Type,true>::ConstReference
2560  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) const
2561 {
2562  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
2563  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
2564  return v_[i+j*mm_];
2565 }
2567 //*************************************************************************************************
2568 
2569 
2570 //*************************************************************************************************
2576 template< typename Type > // Data type of the matrix
2577 inline Type* DynamicMatrix<Type,true>::data()
2578 {
2579  return v_;
2580 }
2582 //*************************************************************************************************
2583 
2584 
2585 //*************************************************************************************************
2591 template< typename Type > // Data type of the matrix
2592 inline const Type* DynamicMatrix<Type,true>::data() const
2593 {
2594  return v_;
2595 }
2597 //*************************************************************************************************
2598 
2599 
2600 //*************************************************************************************************
2607 template< typename Type > // Data type of the matrix
2608 inline typename DynamicMatrix<Type,true>::Iterator
2610 {
2611  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2612  return v_ + j*mm_;
2613 }
2615 //*************************************************************************************************
2616 
2617 
2618 //*************************************************************************************************
2625 template< typename Type > // Data type of the matrix
2626 inline typename DynamicMatrix<Type,true>::ConstIterator
2627  DynamicMatrix<Type,true>::begin( size_t j ) const
2628 {
2629  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2630  return v_ + j*mm_;
2631 }
2633 //*************************************************************************************************
2634 
2635 
2636 //*************************************************************************************************
2643 template< typename Type > // Data type of the matrix
2644 inline typename DynamicMatrix<Type,true>::ConstIterator
2645  DynamicMatrix<Type,true>::cbegin( size_t j ) const
2646 {
2647  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2648  return v_ + j*mm_;
2649 }
2651 //*************************************************************************************************
2652 
2653 
2654 //*************************************************************************************************
2661 template< typename Type > // Data type of the matrix
2662 inline typename DynamicMatrix<Type,true>::Iterator
2663  DynamicMatrix<Type,true>::end( size_t j )
2664 {
2665  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2666  return v_ + j*mm_ + m_;
2667 }
2669 //*************************************************************************************************
2670 
2671 
2672 //*************************************************************************************************
2679 template< typename Type > // Data type of the matrix
2680 inline typename DynamicMatrix<Type,true>::ConstIterator
2681  DynamicMatrix<Type,true>::end( size_t j ) const
2682 {
2683  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2684  return v_ + j*mm_ + m_;
2685 }
2687 //*************************************************************************************************
2688 
2689 
2690 //*************************************************************************************************
2697 template< typename Type > // Data type of the matrix
2698 inline typename DynamicMatrix<Type,true>::ConstIterator
2699  DynamicMatrix<Type,true>::cend( size_t j ) const
2700 {
2701  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2702  return v_ + j*mm_ + m_;
2703 }
2705 //*************************************************************************************************
2706 
2707 
2708 
2709 
2710 //=================================================================================================
2711 //
2712 // ASSIGNMENT OPERATORS
2713 //
2714 //=================================================================================================
2715 
2716 //*************************************************************************************************
2736 template< typename Type > // Data type of the matrix
2737 template< typename Other // Data type of the initialization array
2738  , size_t M // Number of rows of the initialization array
2739  , size_t N > // Number of columns of the initialization array
2740 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Other (&rhs)[M][N] )
2741 {
2742  resize( M, N, false );
2743 
2744  for( size_t j=0UL; j<N; ++j )
2745  for( size_t i=0UL; i<M; ++i )
2746  v_[i+j*mm_] = rhs[i][j];
2747 
2748  return *this;
2749 }
2751 //*************************************************************************************************
2752 
2753 
2754 //*************************************************************************************************
2761 template< typename Type > // Data type of the matrix
2762 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( Type rhs )
2763 {
2764  for( size_t j=0UL; j<n_; ++j )
2765  for( size_t i=0UL; i<m_; ++i )
2766  v_[i+j*mm_] = rhs;
2767 
2768  return *this;
2769 }
2771 //*************************************************************************************************
2772 
2773 
2774 //*************************************************************************************************
2784 template< typename Type > // Data type of the matrix
2785 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const DynamicMatrix& rhs )
2786 {
2787  if( &rhs == this ) return *this;
2788 
2789  resize( rhs.m_, rhs.n_, false );
2790 
2791  for( size_t j=0UL; j<n_; ++j )
2792  for( size_t i=0UL; i<m_; ++i )
2793  v_[i+j*mm_] = rhs(i,j);
2794 
2795  return *this;
2796 }
2798 //*************************************************************************************************
2799 
2800 
2801 //*************************************************************************************************
2811 template< typename Type > // Data type of the matrix
2812 template< typename MT // Type of the right-hand side matrix
2813  , bool SO > // Storage order of the right-hand side matrix
2814 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Matrix<MT,SO>& rhs )
2815 {
2816  using blaze::assign;
2817 
2818  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
2819  DynamicMatrix tmp( ~rhs );
2820  swap( tmp );
2821  }
2822  else {
2823  resize( (~rhs).rows(), (~rhs).columns(), false );
2824  if( IsSparseMatrix<MT>::value )
2825  reset();
2826  assign( *this, ~rhs );
2827  }
2828 
2829  return *this;
2830 }
2832 //*************************************************************************************************
2833 
2834 
2835 //*************************************************************************************************
2846 template< typename Type > // Data type of the matrix
2847 template< typename MT // Type of the right-hand side matrix
2848  , bool SO > // Storage order of the right-hand side matrix
2849 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
2850 {
2851  using blaze::addAssign;
2852 
2853  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
2854  throw std::invalid_argument( "Matrix sizes do not match" );
2855 
2856  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
2857  typename MT::ResultType tmp( ~rhs );
2858  addAssign( *this, tmp );
2859  }
2860  else {
2861  addAssign( *this, ~rhs );
2862  }
2863 
2864  return *this;
2865 }
2867 //*************************************************************************************************
2868 
2869 
2870 //*************************************************************************************************
2881 template< typename Type > // Data type of the matrix
2882 template< typename MT // Type of the right-hand side matrix
2883  , bool SO > // Storage order of the right-hand side matrix
2884 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
2885 {
2886  using blaze::subAssign;
2887 
2888  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
2889  throw std::invalid_argument( "Matrix sizes do not match" );
2890 
2891  if( CanAlias<MT>::value && (~rhs).isAliased( this ) ) {
2892  typename MT::ResultType tmp( ~rhs );
2893  subAssign( *this, tmp );
2894  }
2895  else {
2896  subAssign( *this, ~rhs );
2897  }
2898 
2899  return *this;
2900 }
2902 //*************************************************************************************************
2903 
2904 
2905 //*************************************************************************************************
2916 template< typename Type > // Data type of the matrix
2917 template< typename MT // Type of the right-hand side matrix
2918  , bool SO > // Storage order of the right-hand side matrix
2919 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
2920 {
2921  if( (~rhs).rows() != n_ )
2922  throw std::invalid_argument( "Matrix sizes do not match" );
2923 
2924  DynamicMatrix tmp( *this * (~rhs) );
2925  swap( tmp );
2926 
2927  return *this;
2928 }
2930 //*************************************************************************************************
2931 
2932 
2933 //*************************************************************************************************
2941 template< typename Type > // Data type of the matrix
2942 template< typename Other > // Data type of the right-hand side scalar
2943 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,true> >::Type&
2945 {
2946  return operator=( (*this) * rhs );
2947 }
2949 //*************************************************************************************************
2950 
2951 
2952 //*************************************************************************************************
2960 template< typename Type > // Data type of the matrix
2961 template< typename Other > // Data type of the right-hand side scalar
2962 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,true> >::Type&
2964 {
2965  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
2966 
2967  return operator=( (*this) / rhs );
2968 }
2970 //*************************************************************************************************
2971 
2972 
2973 
2974 
2975 //=================================================================================================
2976 //
2977 // UTILITY FUNCTIONS
2978 //
2979 //=================================================================================================
2980 
2981 //*************************************************************************************************
2987 template< typename Type > // Data type of the matrix
2988 inline size_t DynamicMatrix<Type,true>::rows() const
2989 {
2990  return m_;
2991 }
2993 //*************************************************************************************************
2994 
2995 
2996 //*************************************************************************************************
3002 template< typename Type > // Data type of the matrix
3003 inline size_t DynamicMatrix<Type,true>::columns() const
3004 {
3005  return n_;
3006 }
3008 //*************************************************************************************************
3009 
3010 
3011 //*************************************************************************************************
3020 template< typename Type > // Data type of the matrix
3021 inline size_t DynamicMatrix<Type,true>::spacing() const
3022 {
3023  return mm_;
3024 }
3026 //*************************************************************************************************
3027 
3028 
3029 //*************************************************************************************************
3035 template< typename Type > // Data type of the matrix
3036 inline size_t DynamicMatrix<Type,true>::capacity() const
3037 {
3038  return capacity_;
3039 }
3041 //*************************************************************************************************
3042 
3043 
3044 //*************************************************************************************************
3050 template< typename Type > // Data type of the matrix
3051 inline size_t DynamicMatrix<Type,true>::nonZeros() const
3052 {
3053  size_t nonzeros( 0UL );
3054 
3055  for( size_t j=0UL; j<n_; ++j )
3056  for( size_t i=0UL; i<m_; ++i )
3057  if( !isDefault( v_[i+j*mm_] ) )
3058  ++nonzeros;
3059 
3060  return nonzeros;
3061 }
3063 //*************************************************************************************************
3064 
3065 
3066 //*************************************************************************************************
3073 template< typename Type > // Data type of the matrix
3074 inline size_t DynamicMatrix<Type,true>::nonZeros( size_t j ) const
3075 {
3076  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3077 
3078  const size_t iend( (j+1UL)*mm_ );
3079  size_t nonzeros( 0UL );
3080 
3081  for( size_t i=j*mm_; i<iend; ++i )
3082  if( !isDefault( v_[i] ) )
3083  ++nonzeros;
3084 
3085  return nonzeros;
3086 }
3088 //*************************************************************************************************
3089 
3090 
3091 //*************************************************************************************************
3097 template< typename Type > // Data type of the matrix
3098 inline void DynamicMatrix<Type,true>::reset()
3099 {
3100  using blaze::reset;
3101  for( size_t j=0UL; j<n_; ++j )
3102  for( size_t i=0UL; i<m_; ++i )
3103  reset( v_[i+j*mm_] );
3104 }
3106 //*************************************************************************************************
3107 
3108 
3109 //*************************************************************************************************
3117 template< typename Type > // Data type of the matrix
3118 inline void DynamicMatrix<Type,true>::clear()
3119 {
3120  m_ = 0UL;
3121  mm_ = 0UL;
3122  n_ = 0UL;
3123 }
3125 //*************************************************************************************************
3126 
3127 
3128 //*************************************************************************************************
3161 template< typename Type > // Data type of the matrix
3162 void DynamicMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3163 {
3164  using blaze::min;
3165 
3166  if( m == m_ && n == n_ ) return;
3167 
3168  const size_t mm( adjustRows( m ) );
3169 
3170  if( preserve )
3171  {
3172  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
3173  const size_t min_m( min( m, m_ ) );
3174  const size_t min_n( min( n, n_ ) );
3175 
3176  for( size_t j=0UL; j<min_n; ++j )
3177  for( size_t i=0UL; i<min_m; ++i )
3178  v[i+j*mm] = v_[i+j*mm_];
3179 
3180  if( IsBuiltin<Type>::value ) {
3181  for( size_t j=0UL; j<n; ++j )
3182  for( size_t i=m; i<mm; ++i )
3183  v[i+j*mm] = Type();
3184  }
3185 
3186  std::swap( v_, v );
3187  deallocate( v );
3188  capacity_ = mm*n;
3189  }
3190  else if( mm*n > capacity_ ) {
3191  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
3192 
3193  if( IsBuiltin<Type>::value ) {
3194  for( size_t j=0UL; j<n; ++j )
3195  for( size_t i=m; i<mm; ++i )
3196  v[i+j*mm] = Type();
3197  }
3198 
3199  std::swap( v_, v );
3200  deallocate( v );
3201  capacity_ = mm*n;
3202  }
3203 
3204  m_ = m;
3205  mm_ = mm;
3206  n_ = n;
3207 }
3209 //*************************************************************************************************
3210 
3211 
3212 //*************************************************************************************************
3227 template< typename Type > // Data type of the matrix
3228 inline void DynamicMatrix<Type,true>::extend( size_t m, size_t n, bool preserve )
3229 {
3230  resize( m_+m, n_+n, preserve );
3231 }
3233 //*************************************************************************************************
3234 
3235 
3236 //*************************************************************************************************
3246 template< typename Type > // Data type of the matrix
3247 inline void DynamicMatrix<Type,true>::reserve( size_t elements )
3248 {
3249  if( elements > capacity_ )
3250  {
3251  // Allocating a new array
3252  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
3253 
3254  // Initializing the new array
3255  std::copy( v_, v_+capacity_, tmp );
3256 
3257  if( IsBuiltin<Type>::value ) {
3258  for( size_t i=capacity_; i<elements; ++i )
3259  tmp[i] = Type();
3260  }
3261 
3262  // Replacing the old array
3263  std::swap( tmp, v_ );
3264  deallocate( tmp );
3265  capacity_ = elements;
3266  }
3267 }
3269 //*************************************************************************************************
3270 
3271 
3272 //*************************************************************************************************
3278 template< typename Type > // Data type of the matrix
3279 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::transpose()
3280 {
3281  DynamicMatrix tmp( trans(*this) );
3282  swap( tmp );
3283  return *this;
3284 }
3286 //*************************************************************************************************
3287 
3288 
3289 //*************************************************************************************************
3298 template< typename Type > // Data type of the matrix
3299 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::invert()
3300 {
3302 
3303  return *this;
3304 }
3306 //*************************************************************************************************
3307 
3308 
3309 //*************************************************************************************************
3327 template< typename Type > // Data type of the matrix
3328 inline bool DynamicMatrix<Type,true>::isDiagonal() const
3329 {
3330  if( m_ != n_ ) return false;
3331 
3332  for( size_t j=1UL; j<n_; ++j ) {
3333  for( size_t i=0UL; i<j; ++i ) {
3334  if( !isDefault( v_[i+j*mm_] ) || !isDefault( v_[j+i*mm_] ) )
3335  return false;
3336  }
3337  }
3338 
3339  return true;
3340 }
3342 //*************************************************************************************************
3343 
3344 
3345 //*************************************************************************************************
3351 template< typename Type > // Data type of the matrix
3352 inline bool DynamicMatrix<Type,true>::isSymmetric() const
3353 {
3354  if( m_ != n_ ) return false;
3355 
3356  for( size_t j=1UL; j<n_; ++j ) {
3357  for( size_t i=0UL; i<j; ++i ) {
3358  if( !equal( v_[i+j*mm_], v_[j+i*mm_] ) )
3359  return false;
3360  }
3361  }
3362 
3363  return true;
3364 }
3366 //*************************************************************************************************
3367 
3368 
3369 //*************************************************************************************************
3376 template< typename Type > // Data type of the matrix
3377 template< typename Other > // Data type of the scalar value
3378 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::scale( Other scalar )
3379 {
3380  for( size_t j=0UL; j<n_; ++j )
3381  for( size_t i=0UL; i<m_; ++i )
3382  v_[i+j*mm_] *= scalar;
3383 
3384  return *this;
3385 }
3387 //*************************************************************************************************
3388 
3389 
3390 //*************************************************************************************************
3398 template< typename Type > // Data type of the matrix
3399 inline void DynamicMatrix<Type,true>::swap( DynamicMatrix& m ) /* throw() */
3400 {
3401  std::swap( m_ , m.m_ );
3402  std::swap( mm_, m.mm_ );
3403  std::swap( n_ , m.n_ );
3404  std::swap( capacity_, m.capacity_ );
3405  std::swap( v_ , m.v_ );
3406 }
3408 //*************************************************************************************************
3409 
3410 
3411 //*************************************************************************************************
3418 template< typename Type > // Data type of the matrix
3419 inline size_t DynamicMatrix<Type,true>::adjustRows( size_t minRows ) const
3420 {
3421  if( IsBuiltin<Type>::value )
3422  return minRows + ( IT::size - ( minRows % IT::size ) ) % IT::size;
3423  else return minRows;
3424 }
3426 //*************************************************************************************************
3427 
3428 
3429 
3430 
3431 //=================================================================================================
3432 //
3433 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3434 //
3435 //=================================================================================================
3436 
3437 //*************************************************************************************************
3444 template< typename Type > // Data type of the matrix
3445 template< typename Other > // Data type of the foreign expression
3446 inline bool DynamicMatrix<Type,true>::isAliased( const Other* alias ) const
3447 {
3448  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3449 }
3451 //*************************************************************************************************
3452 
3453 
3454 //*************************************************************************************************
3467 template< typename Type > // Data type of the matrix
3468 inline typename DynamicMatrix<Type,true>::IntrinsicType
3469  DynamicMatrix<Type,true>::get( size_t i, size_t j ) const
3470 {
3472 
3473  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
3474  BLAZE_INTERNAL_ASSERT( i + IT::size <= mm_, "Invalid row access index" );
3475  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
3476  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
3477 
3478  return load( &v_[i+j*mm_] );
3479 }
3481 //*************************************************************************************************
3482 
3483 
3484 //*************************************************************************************************
3496 template< typename Type > // Data type of the matrix
3497 template< typename MT > // Type of the right-hand side dense matrix
3498 inline typename DisableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
3499  DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
3500 {
3501  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3502  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3503 
3504  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ( m_ & size_t(-2) ), "Invalid end calculation" );
3505  const size_t iend( m_ & size_t(-2) );
3506 
3507  for( size_t j=0UL; j<n_; ++j ) {
3508  for( size_t i=0UL; i<iend; i+=2UL ) {
3509  v_[i +j*mm_] = (~rhs)(i ,j);
3510  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
3511  }
3512  if( iend < m_ ) {
3513  v_[iend+j*mm_] = (~rhs)(iend,j);
3514  }
3515  }
3516 }
3518 //*************************************************************************************************
3519 
3520 
3521 //*************************************************************************************************
3533 template< typename Type > // Data type of the matrix
3534 template< typename MT > // Type of the right-hand side dense matrix
3535 inline typename EnableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
3536  DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
3537 {
3538  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3539  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3540 
3542 
3543  if( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
3544  {
3545  for( size_t j=0UL; j<n_; ++j )
3546  for( size_t i=0UL; i<m_; i+=IT::size )
3547  stream( &v_[i+j*mm_], (~rhs).get(i,j) );
3548  }
3549  else
3550  {
3551  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ( m_ & size_t(-IT::size*4) ), "Invalid end calculation" );
3552  const size_t iend( m_ & size_t(-IT::size*4) );
3553 
3554  for( size_t j=0UL; j<n_; ++j ) {
3555  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3556  store( &v_[i+j*mm_ ], (~rhs).get(i ,j) );
3557  store( &v_[i+j*mm_+IT::size ], (~rhs).get(i+IT::size ,j) );
3558  store( &v_[i+j*mm_+IT::size*2UL], (~rhs).get(i+IT::size*2UL,j) );
3559  store( &v_[i+j*mm_+IT::size*3UL], (~rhs).get(i+IT::size*3UL,j) );
3560  }
3561  for( size_t i=iend; i<m_; i+=IT::size ) {
3562  store( &v_[i+j*mm_], (~rhs).get(i,j) );
3563  }
3564  }
3565  }
3566 }
3568 //*************************************************************************************************
3569 
3570 
3571 //*************************************************************************************************
3583 template< typename Type > // Data type of the matrix
3584 template< typename MT > // Type of the right-hand side dense matrix
3585 inline void DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,false>& rhs )
3586 {
3587  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3588  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3589 
3590  const size_t block( 16UL );
3591 
3592  for( size_t jj=0UL; jj<n_; jj+=block ) {
3593  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3594  for( size_t ii=0UL; ii<m_; ii+=block ) {
3595  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3596  for( size_t j=jj; j<jend; ++j ) {
3597  for( size_t i=ii; i<iend; ++i ) {
3598  v_[i+j*mm_] = (~rhs)(i,j);
3599  }
3600  }
3601  }
3602  }
3603 }
3605 //*************************************************************************************************
3606 
3607 
3608 //*************************************************************************************************
3620 template< typename Type > // Data type of the matrix
3621 template< typename MT > // Type of the right-hand side sparse matrix
3623 {
3624  for( size_t j=0UL; j<(~rhs).columns(); ++j )
3625  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3626  v_[element->index()+j*mm_] = element->value();
3627 }
3629 //*************************************************************************************************
3630 
3631 
3632 //*************************************************************************************************
3644 template< typename Type > // Data type of the matrix
3645 template< typename MT > // Type of the right-hand side sparse matrix
3647 {
3648  for( size_t i=0UL; i<(~rhs).rows(); ++i )
3649  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3650  v_[i+element->index()*mm_] = element->value();
3651 }
3653 //*************************************************************************************************
3654 
3655 
3656 //*************************************************************************************************
3668 template< typename Type > // Data type of the matrix
3669 template< typename MT > // Type of the right-hand side dense matrix
3670 inline typename DisableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
3671  DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
3672 {
3673  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3674  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3675 
3676  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ( m_ & size_t(-2) ), "Invalid end calculation" );
3677  const size_t iend( m_ & size_t(-2) );
3678 
3679  for( size_t j=0UL; j<n_; ++j ) {
3680  for( size_t i=0UL; i<iend; i+=2UL ) {
3681  v_[i +j*mm_] += (~rhs)(i ,j);
3682  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
3683  }
3684  if( iend < m_ ) {
3685  v_[iend+j*mm_] += (~rhs)(iend,j);
3686  }
3687  }
3688 }
3690 //*************************************************************************************************
3691 
3692 
3693 //*************************************************************************************************
3705 template< typename Type > // Data type of the matrix
3706 template< typename MT > // Type of the right-hand side dense matrix
3707 inline typename EnableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
3708  DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
3709 {
3710  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3711  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3712 
3714 
3715  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ( m_ & size_t(-IT::size*4) ), "Invalid end calculation" );
3716  const size_t iend( m_ & size_t(-IT::size*4) );
3717 
3718  for( size_t j=0UL; j<n_; ++j ) {
3719  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3720  store( &v_[i+j*mm_ ], load( &v_[i+j*mm_ ] ) + (~rhs).get(i ,j) );
3721  store( &v_[i+j*mm_+IT::size ], load( &v_[i+j*mm_+IT::size ] ) + (~rhs).get(i+IT::size ,j) );
3722  store( &v_[i+j*mm_+IT::size*2UL], load( &v_[i+j*mm_+IT::size*2UL] ) + (~rhs).get(i+IT::size*2UL,j) );
3723  store( &v_[i+j*mm_+IT::size*3UL], load( &v_[i+j*mm_+IT::size*3UL] ) + (~rhs).get(i+IT::size*3UL,j) );
3724  }
3725  for( size_t i=iend; i<m_; i+=IT::size ) {
3726  store( &v_[i+j*mm_], load( &v_[i+j*mm_] ) + (~rhs).get(i,j) );
3727  }
3728  }
3729 }
3731 //*************************************************************************************************
3732 
3733 
3734 //*************************************************************************************************
3746 template< typename Type > // Data type of the matrix
3747 template< typename MT > // Type of the right-hand side dense matrix
3748 inline void DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,false>& rhs )
3749 {
3750  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3751  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3752 
3753  const size_t block( 16UL );
3754 
3755  for( size_t jj=0UL; jj<n_; jj+=block ) {
3756  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3757  for( size_t ii=0UL; ii<m_; ii+=block ) {
3758  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3759  for( size_t j=jj; j<jend; ++j ) {
3760  for( size_t i=ii; i<iend; ++i ) {
3761  v_[i+j*mm_] += (~rhs)(i,j);
3762  }
3763  }
3764  }
3765  }
3766 }
3768 //*************************************************************************************************
3769 
3770 
3771 //*************************************************************************************************
3783 template< typename Type > // Data type of the matrix
3784 template< typename MT > // Type of the right-hand side sparse matrix
3786 {
3787  for( size_t j=0UL; j<(~rhs).columns(); ++j )
3788  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3789  v_[element->index()+j*mm_] += element->value();
3790 }
3792 //*************************************************************************************************
3793 
3794 
3795 //*************************************************************************************************
3807 template< typename Type > // Data type of the matrix
3808 template< typename MT > // Type of the right-hand side sparse matrix
3810 {
3811  for( size_t i=0UL; i<(~rhs).rows(); ++i )
3812  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3813  v_[i+element->index()*mm_] += element->value();
3814 }
3816 //*************************************************************************************************
3817 
3818 
3819 //*************************************************************************************************
3831 template< typename Type > // Data type of the matrix
3832 template< typename MT > // Type of the right-hand side dense matrix
3833 inline typename DisableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
3834  DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
3835 {
3836  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3837  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3838 
3839  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ( m_ & size_t(-2) ), "Invalid end calculation" );
3840  const size_t iend( m_ & size_t(-2) );
3841 
3842  for( size_t j=0UL; j<n_; ++j ) {
3843  for( size_t i=0UL; i<iend; i+=2UL ) {
3844  v_[i +j*mm_] -= (~rhs)(i ,j);
3845  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
3846  }
3847  if( iend < m_ ) {
3848  v_[iend+j*mm_] -= (~rhs)(iend,j);
3849  }
3850  }
3851 }
3853 //*************************************************************************************************
3854 
3855 
3856 //*************************************************************************************************
3869 template< typename Type > // Data type of the matrix
3870 template< typename MT > // Type of the right-hand side dense matrix
3871 inline typename EnableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
3872  DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
3873 {
3874  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3875  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3876 
3878 
3879  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ( m_ & size_t(-IT::size*4) ), "Invalid end calculation" );
3880  const size_t iend( m_ & size_t(-IT::size*4) );
3881 
3882  for( size_t j=0UL; j<n_; ++j ) {
3883  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3884  store( &v_[i+j*mm_ ], load( &v_[i+j*mm_ ] ) - (~rhs).get(i ,j) );
3885  store( &v_[i+j*mm_+IT::size ], load( &v_[i+j*mm_+IT::size ] ) - (~rhs).get(i+IT::size ,j) );
3886  store( &v_[i+j*mm_+IT::size*2UL], load( &v_[i+j*mm_+IT::size*2UL] ) - (~rhs).get(i+IT::size*2UL,j) );
3887  store( &v_[i+j*mm_+IT::size*3UL], load( &v_[i+j*mm_+IT::size*3UL] ) - (~rhs).get(i+IT::size*3UL,j) );
3888  }
3889  for( size_t i=iend; i<m_; i+=IT::size ) {
3890  store( &v_[i+j*mm_], load( &v_[i+j*mm_] ) - (~rhs).get(i,j) );
3891  }
3892  }
3893 }
3895 //*************************************************************************************************
3896 
3897 
3898 //*************************************************************************************************
3910 template< typename Type > // Data type of the matrix
3911 template< typename MT > // Type of the right-hand side dense matrix
3912 inline void DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,false>& rhs )
3913 {
3914  const size_t block( 16UL );
3915 
3916  for( size_t jj=0UL; jj<n_; jj+=block ) {
3917  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3918  for( size_t ii=0UL; ii<m_; ii+=block ) {
3919  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3920  for( size_t j=jj; j<jend; ++j ) {
3921  for( size_t i=ii; i<iend; ++i ) {
3922  v_[i+j*mm_] -= (~rhs)(i,j);
3923  }
3924  }
3925  }
3926  }
3927 }
3929 //*************************************************************************************************
3930 
3931 
3932 //*************************************************************************************************
3944 template< typename Type > // Data type of the matrix
3945 template< typename MT > // Type of the right-hand side sparse matrix
3947 {
3948  for( size_t j=0UL; j<(~rhs).columns(); ++j )
3949  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3950  v_[element->index()+j*mm_] -= element->value();
3951 }
3953 //*************************************************************************************************
3954 
3955 
3956 //*************************************************************************************************
3968 template< typename Type > // Data type of the matrix
3969 template< typename MT > // Type of the right-hand side sparse matrix
3971 {
3972  for( size_t i=0UL; i<(~rhs).rows(); ++i )
3973  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3974  v_[i+element->index()*mm_] -= element->value();
3975 }
3977 //*************************************************************************************************
3978 
3979 
3980 
3981 
3982 
3983 
3984 
3985 
3986 //=================================================================================================
3987 //
3988 // GLOBAL OPERATORS
3989 //
3990 //=================================================================================================
3991 
3992 //*************************************************************************************************
3995 template< typename Type, bool SO >
3996 inline bool isnan( const DynamicMatrix<Type,SO>& m );
3997 
3998 template< typename Type, bool SO >
3999 inline void reset( DynamicMatrix<Type,SO>& m );
4000 
4001 template< typename Type, bool SO >
4002 inline void clear( DynamicMatrix<Type,SO>& m );
4003 
4004 template< typename Type, bool SO >
4005 inline bool isDefault( const DynamicMatrix<Type,SO>& m );
4006 
4007 template< typename Type, bool SO >
4008 inline const DynamicMatrix<Type,SO> inv( const DynamicMatrix<Type,SO>& m );
4009 
4010 template< typename Type, bool SO >
4011 inline void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) /* throw() */;
4013 //*************************************************************************************************
4014 
4015 
4016 //*************************************************************************************************
4023 template< typename Type // Data type of the matrix
4024  , bool SO > // Storage order
4025 inline bool isnan( const DynamicMatrix<Type,SO>& m )
4026 {
4027  for( size_t i=0UL; i<m.rows(); ++i ) {
4028  for( size_t j=0UL; j<m.columns(); ++j )
4029  if( isnan( m(i,j) ) ) return true;
4030  }
4031  return false;
4032 }
4033 //*************************************************************************************************
4034 
4035 
4036 //*************************************************************************************************
4043 template< typename Type // Data type of the matrix
4044  , bool SO > // Storage order
4046 {
4047  m.reset();
4048 }
4049 //*************************************************************************************************
4050 
4051 
4052 //*************************************************************************************************
4059 template< typename Type // Data type of the matrix
4060  , bool SO > // Storage order
4062 {
4063  m.clear();
4064 }
4065 //*************************************************************************************************
4066 
4067 
4068 //*************************************************************************************************
4086 template< typename Type // Data type of the matrix
4087  , bool SO > // Storage order
4088 inline bool isDefault( const DynamicMatrix<Type,SO>& m )
4089 {
4090  if( SO == rowMajor ) {
4091  for( size_t i=0UL; i<m.rows(); ++i )
4092  for( size_t j=0UL; j<m.columns(); ++j )
4093  if( !isDefault( m(i,j) ) ) return false;
4094  }
4095  else {
4096  for( size_t j=0UL; j<m.columns(); ++j )
4097  for( size_t i=0UL; i<m.rows(); ++i )
4098  if( !isDefault( m(i,j) ) ) return false;
4099  }
4100 
4101  return true;
4102 }
4103 //*************************************************************************************************
4104 
4105 
4106 //*************************************************************************************************
4124 template< typename Type // Data type of the matrix
4125  , bool SO > // Storage order
4127 {
4129 
4130  return DynamicMatrix<Type,SO>();
4131 }
4132 //*************************************************************************************************
4133 
4134 
4135 //*************************************************************************************************
4144 template< typename Type // Data type of the matrix
4145  , bool SO > // Storage order
4146 inline void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) /* throw() */
4147 {
4148  a.swap( b );
4149 }
4150 //*************************************************************************************************
4151 
4152 
4153 
4154 
4155 //=================================================================================================
4156 //
4157 // ISRESIZABLE SPECIALIZATIONS
4158 //
4159 //=================================================================================================
4160 
4161 //*************************************************************************************************
4163 template< typename T, bool SO >
4164 struct IsResizable< DynamicMatrix<T,SO> > : public TrueType
4165 {
4166  enum { value = 1 };
4167  typedef TrueType Type;
4168 };
4169 
4170 template< typename T, bool SO >
4171 struct IsResizable< const DynamicMatrix<T,SO> > : public TrueType
4172 {
4173  enum { value = 1 };
4174  typedef TrueType Type;
4175 };
4176 
4177 template< typename T, bool SO >
4178 struct IsResizable< volatile DynamicMatrix<T,SO> > : public TrueType
4179 {
4180  enum { value = 1 };
4181  typedef TrueType Type;
4182 };
4183 
4184 template< typename T, bool SO >
4185 struct IsResizable< const volatile DynamicMatrix<T,SO> > : public TrueType
4186 {
4187  enum { value = 1 };
4188  typedef TrueType Type;
4189 };
4191 //*************************************************************************************************
4192 
4193 
4194 
4195 
4196 //=================================================================================================
4197 //
4198 // ADDTRAIT SPECIALIZATIONS
4199 //
4200 //=================================================================================================
4201 
4202 //*************************************************************************************************
4204 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4205 struct AddTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4206 {
4207  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4208 };
4209 
4210 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4211 struct AddTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4212 {
4213  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4214 };
4215 
4216 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4217 struct AddTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
4218 {
4219  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4220 };
4221 
4222 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4223 struct AddTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
4224 {
4225  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4226 };
4227 
4228 template< typename T1, bool SO, typename T2 >
4229 struct AddTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4230 {
4231  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4232 };
4233 
4234 template< typename T1, bool SO1, typename T2, bool SO2 >
4235 struct AddTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4236 {
4237  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4238 };
4240 //*************************************************************************************************
4241 
4242 
4243 
4244 
4245 //=================================================================================================
4246 //
4247 // SUBTRAIT SPECIALIZATIONS
4248 //
4249 //=================================================================================================
4250 
4251 //*************************************************************************************************
4253 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4254 struct SubTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4255 {
4256  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4257 };
4258 
4259 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4260 struct SubTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4261 {
4262  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4263 };
4264 
4265 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4266 struct SubTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
4267 {
4268  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4269 };
4270 
4271 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4272 struct SubTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
4273 {
4274  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4275 };
4276 
4277 template< typename T1, bool SO, typename T2 >
4278 struct SubTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4279 {
4280  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4281 };
4282 
4283 template< typename T1, bool SO1, typename T2, bool SO2 >
4284 struct SubTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4285 {
4286  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4287 };
4289 //*************************************************************************************************
4290 
4291 
4292 
4293 
4294 //=================================================================================================
4295 //
4296 // MULTTRAIT SPECIALIZATIONS
4297 //
4298 //=================================================================================================
4299 
4300 //*************************************************************************************************
4302 template< typename T1, bool SO, typename T2 >
4303 struct MultTrait< DynamicMatrix<T1,SO>, T2 >
4304 {
4305  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4307 };
4308 
4309 template< typename T1, typename T2, bool SO >
4310 struct MultTrait< T1, DynamicMatrix<T2,SO> >
4311 {
4312  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4314 };
4315 
4316 template< typename T1, bool SO, typename T2, size_t N >
4317 struct MultTrait< DynamicMatrix<T1,SO>, StaticVector<T2,N,false> >
4318 {
4319  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4320 };
4321 
4322 template< typename T1, size_t N, typename T2, bool SO >
4323 struct MultTrait< StaticVector<T1,N,true>, DynamicMatrix<T2,SO> >
4324 {
4325  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4326 };
4327 
4328 template< typename T1, bool SO, typename T2 >
4329 struct MultTrait< DynamicMatrix<T1,SO>, DynamicVector<T2,false> >
4330 {
4331  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4332 };
4333 
4334 template< typename T1, typename T2, bool SO >
4335 struct MultTrait< DynamicVector<T1,true>, DynamicMatrix<T2,SO> >
4336 {
4337  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4338 };
4339 
4340 template< typename T1, bool SO, typename T2 >
4341 struct MultTrait< DynamicMatrix<T1,SO>, CompressedVector<T2,false> >
4342 {
4343  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4344 };
4345 
4346 template< typename T1, typename T2, bool SO >
4347 struct MultTrait< CompressedVector<T1,true>, DynamicMatrix<T2,SO> >
4348 {
4349  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4350 };
4351 
4352 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4353 struct MultTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4354 {
4355  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4356 };
4357 
4358 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4359 struct MultTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
4360 {
4361  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4362 };
4363 
4364 template< typename T1, bool SO1, typename T2, bool SO2 >
4365 struct MultTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4366 {
4367  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4368 };
4370 //*************************************************************************************************
4371 
4372 
4373 
4374 
4375 //=================================================================================================
4376 //
4377 // DIVTRAIT SPECIALIZATIONS
4378 //
4379 //=================================================================================================
4380 
4381 //*************************************************************************************************
4383 template< typename T1, bool SO, typename T2 >
4384 struct DivTrait< DynamicMatrix<T1,SO>, T2 >
4385 {
4386  typedef DynamicMatrix< typename DivTrait<T1,T2>::Type , SO > Type;
4388 };
4390 //*************************************************************************************************
4391 
4392 
4393 
4394 
4395 //=================================================================================================
4396 //
4397 // MATHTRAIT SPECIALIZATIONS
4398 //
4399 //=================================================================================================
4400 
4401 //*************************************************************************************************
4403 template< typename T1, bool SO, typename T2 >
4404 struct MathTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4405 {
4406  typedef DynamicMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
4407  typedef DynamicMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
4408 };
4410 //*************************************************************************************************
4411 
4412 } // namespace blaze
4413 
4414 #endif