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/Forward.h>
34 #include <blaze/math/Functions.h>
35 #include <blaze/math/Intrinsics.h>
36 #include <blaze/math/shims/Equal.h>
38 #include <blaze/math/shims/IsNaN.h>
39 #include <blaze/math/shims/Reset.h>
49 #include <blaze/system/CacheSize.h>
50 #include <blaze/system/Restrict.h>
52 #include <blaze/util/Assert.h>
59 #include <blaze/util/DisableIf.h>
60 #include <blaze/util/EnableIf.h>
61 #include <blaze/util/Memory.h>
62 #include <blaze/util/mpl/If.h>
63 #include <blaze/util/Null.h>
64 #include <blaze/util/Template.h>
65 #include <blaze/util/Types.h>
71 #include <blaze/util/Unused.h>
72 
73 
74 namespace blaze {
75 
76 //=================================================================================================
77 //
78 // CLASS DEFINITION
79 //
80 //=================================================================================================
81 
82 //*************************************************************************************************
161 template< typename Type // Data type of the matrix
162  , bool SO = defaultStorageOrder > // Storage order
163 class DynamicMatrix : public DenseMatrix< DynamicMatrix<Type,SO>, SO >
164 {
165  private:
166  //**Type definitions****************************************************************************
168  //**********************************************************************************************
169 
170  public:
171  //**Type definitions****************************************************************************
173  typedef This ResultType;
176  typedef Type ElementType;
177  typedef const Type& ReturnType;
178  typedef typename IT::Type IntrinsicType;
179  typedef const This& CompositeType;
180  typedef Type& Reference;
181  typedef const Type& ConstReference;
182  typedef Type* Iterator;
183  typedef const Type* ConstIterator;
184  //**********************************************************************************************
185 
186  //**Compilation flags***************************************************************************
188 
192  enum { vectorizable = IsVectorizable<Type>::value };
193  //**********************************************************************************************
194 
195  //**Constructors********************************************************************************
198  explicit inline DynamicMatrix();
199  explicit inline DynamicMatrix( size_t m, size_t n );
200  explicit inline DynamicMatrix( size_t m, size_t n, Type init );
201  inline DynamicMatrix( const DynamicMatrix& m );
202  template< typename MT, bool SO2 > inline DynamicMatrix( const Matrix<MT,SO2>& m );
203 
204  template< typename Other, size_t M, size_t N >
205  inline DynamicMatrix( const Other (&rhs)[M][N] );
207  //**********************************************************************************************
208 
209  //**Destructor**********************************************************************************
212  inline ~DynamicMatrix();
214  //**********************************************************************************************
215 
216  //**Data access functions***********************************************************************
219  inline Reference operator()( size_t i, size_t j );
220  inline ConstReference operator()( size_t i, size_t j ) const;
221  inline Type* data ();
222  inline const Type* data () const;
223  inline Type* data ( size_t i );
224  inline const Type* data ( size_t i ) const;
225  inline Iterator begin ( size_t i );
226  inline ConstIterator begin ( size_t i ) const;
227  inline ConstIterator cbegin( size_t i ) const;
228  inline Iterator end ( size_t i );
229  inline ConstIterator end ( size_t i ) const;
230  inline ConstIterator cend ( size_t i ) const;
232  //**********************************************************************************************
233 
234  //**Assignment operators************************************************************************
237  template< typename Other, size_t M, size_t N >
238  inline DynamicMatrix& operator=( const Other (&rhs)[M][N] );
239 
240  inline DynamicMatrix& operator= ( Type set );
241  inline DynamicMatrix& operator= ( const DynamicMatrix& set );
242  template< typename MT, bool SO2 > inline DynamicMatrix& operator= ( const Matrix<MT,SO2>& rhs );
243  template< typename MT, bool SO2 > inline DynamicMatrix& operator+=( const Matrix<MT,SO2>& rhs );
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 
247  template< typename Other >
248  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
249  operator*=( Other rhs );
250 
251  template< typename Other >
252  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
253  operator/=( Other rhs );
255  //**********************************************************************************************
256 
257  //**Utility functions***************************************************************************
260  inline size_t rows() const;
261  inline size_t columns() const;
262  inline size_t spacing() const;
263  inline size_t capacity() const;
264  inline size_t capacity( size_t i ) const;
265  inline size_t nonZeros() const;
266  inline size_t nonZeros( size_t i ) const;
267  inline void reset();
268  inline void reset( size_t i );
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 &&
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 canAlias ( const Other* alias ) const;
323  template< typename Other > inline bool isAliased( const Other* alias ) const;
324  inline IntrinsicType get ( size_t i, size_t j ) const;
325 
326  template< typename MT >
327  inline typename DisableIf< VectorizedAssign<MT> >::Type
328  assign( const DenseMatrix<MT,SO>& rhs );
329 
330  template< typename MT >
331  inline typename EnableIf< VectorizedAssign<MT> >::Type
332  assign( const DenseMatrix<MT,SO>& rhs );
333 
334  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
335  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
336  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
337 
338  template< typename MT >
339  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
340  addAssign( const DenseMatrix<MT,SO>& rhs );
341 
342  template< typename MT >
343  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
344  addAssign( const DenseMatrix<MT,SO>& rhs );
345 
346  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
347  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
348  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
349 
350  template< typename MT >
351  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
352  subAssign( const DenseMatrix<MT,SO>& rhs );
353 
354  template< typename MT >
355  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
356  subAssign( const DenseMatrix<MT,SO>& rhs );
357 
358  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
359  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
360  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
362  //**********************************************************************************************
363 
364  private:
365  //**Utility functions***************************************************************************
368  inline size_t adjustColumns( size_t minColumns ) const;
370  //**********************************************************************************************
371 
372  //**Member variables****************************************************************************
375  size_t m_;
376  size_t n_;
377  size_t nn_;
378  size_t capacity_;
380 
390  //**********************************************************************************************
391 
392  //**Compile time checks*************************************************************************
399  //**********************************************************************************************
400 };
401 //*************************************************************************************************
402 
403 
404 
405 
406 //=================================================================================================
407 //
408 // CONSTRUCTORS
409 //
410 //=================================================================================================
411 
412 //*************************************************************************************************
415 template< typename Type // Data type of the matrix
416  , bool SO > // Storage order
418  : m_ ( 0UL ) // The current number of rows of the matrix
419  , n_ ( 0UL ) // The current number of columns of the matrix
420  , nn_ ( 0UL ) // The alignment adjusted number of columns
421  , capacity_( 0UL ) // The maximum capacity of the matrix
422  , v_ ( NULL ) // The matrix elements
423 {}
424 //*************************************************************************************************
425 
426 
427 //*************************************************************************************************
436 template< typename Type // Data type of the matrix
437  , bool SO > // Storage order
438 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n )
439  : m_ ( m ) // The current number of rows of the matrix
440  , n_ ( n ) // The current number of columns of the matrix
441  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
442  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
443  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
444 {
445  if( IsBuiltin<Type>::value ) {
446  for( size_t i=0UL; i<m_; ++i ) {
447  for( size_t j=n_; j<nn_; ++j )
448  v_[i*nn_+j] = Type();
449  }
450  }
451 }
452 //*************************************************************************************************
453 
454 
455 //*************************************************************************************************
464 template< typename Type // Data type of the matrix
465  , bool SO > // Storage order
466 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, Type init )
467  : m_ ( m ) // The current number of rows of the matrix
468  , n_ ( n ) // The current number of columns of the matrix
469  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
470  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
471  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
472 {
473  for( size_t i=0UL; i<m; ++i ) {
474  for( size_t j=0UL; j<n_; ++j )
475  v_[i*nn_+j] = init;
476 
477  if( IsBuiltin<Type>::value ) {
478  for( size_t j=n_; j<nn_; ++j )
479  v_[i*nn_+j] = Type();
480  }
481  }
482 }
483 //*************************************************************************************************
484 
485 
486 //*************************************************************************************************
494 template< typename Type // Data type of the matrix
495  , bool SO > // Storage order
497  : m_ ( m.m_ ) // The current number of rows of the matrix
498  , n_ ( m.n_ ) // The current number of columns of the matrix
499  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
500  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
501  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
502 {
503  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
504 
505  for( size_t i=0UL; i<capacity_; ++i )
506  v_[i] = m.v_[i];
507 }
508 //*************************************************************************************************
509 
510 
511 //*************************************************************************************************
516 template< typename Type // Data type of the matrix
517  , bool SO > // Storage order
518 template< typename MT // Type of the foreign matrix
519  , bool SO2 > // Storage order of the foreign matrix
521  : m_ ( (~m).rows() ) // The current number of rows of the matrix
522  , n_ ( (~m).columns() ) // The current number of columns of the matrix
523  , nn_ ( adjustColumns( n_ ) ) // The alignment adjusted number of columns
524  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
525  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
526 {
527  using blaze::assign;
528 
529  if( IsBuiltin<Type>::value ) {
530  for( size_t i=0UL; i<m_; ++i ) {
531  for( size_t j=( IsSparseMatrix<MT>::value )?( 0UL ):( n_ ); j<nn_; ++j )
532  v_[i*nn_+j] = Type();
533  }
534  }
535 
536  assign( *this, ~m );
537 }
538 //*************************************************************************************************
539 
540 
541 //*************************************************************************************************
559 template< typename Type // Data type of the matrix
560  , bool SO > // Storage order
561 template< typename Other // Data type of the initialization array
562  , size_t M // Number of rows of the initialization array
563  , size_t N > // Number of columns of the initialization array
564 inline DynamicMatrix<Type,SO>::DynamicMatrix( const Other (&rhs)[M][N] )
565  : m_ ( M ) // The current number of rows of the matrix
566  , n_ ( N ) // The current number of columns of the matrix
567  , nn_ ( adjustColumns( N ) ) // The alignment adjusted number of columns
568  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
569  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
570 {
571  for( size_t i=0UL; i<M; ++i ) {
572  for( size_t j=0UL; j<N; ++j )
573  v_[i*nn_+j] = rhs[i][j];
574 
575  if( IsBuiltin<Type>::value ) {
576  for( size_t j=N; j<nn_; ++j )
577  v_[i*nn_+j] = Type();
578  }
579  }
580 }
581 //*************************************************************************************************
582 
583 
584 
585 
586 //=================================================================================================
587 //
588 // DESTRUCTOR
589 //
590 //=================================================================================================
591 
592 //*************************************************************************************************
595 template< typename Type // Data type of the matrix
596  , bool SO > // Storage order
598 {
599  deallocate( v_ );
600 }
601 //*************************************************************************************************
602 
603 
604 
605 
606 //=================================================================================================
607 //
608 // DATA ACCESS FUNCTIONS
609 //
610 //=================================================================================================
611 
612 //*************************************************************************************************
619 template< typename Type // Data type of the matrix
620  , bool SO > // Storage order
621 inline typename DynamicMatrix<Type,SO>::Reference
623 {
624  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
625  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
626  return v_[i*nn_+j];
627 }
628 //*************************************************************************************************
629 
630 
631 //*************************************************************************************************
638 template< typename Type // Data type of the matrix
639  , bool SO > // Storage order
641  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) const
642 {
643  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
644  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
645  return v_[i*nn_+j];
646 }
647 //*************************************************************************************************
648 
649 
650 //*************************************************************************************************
655 template< typename Type // Data type of the matrix
656  , bool SO > // Storage order
658 {
659  return v_;
660 }
661 //*************************************************************************************************
662 
663 
664 //*************************************************************************************************
669 template< typename Type // Data type of the matrix
670  , bool SO > // Storage order
671 inline const Type* DynamicMatrix<Type,SO>::data() const
672 {
673  return v_;
674 }
675 //*************************************************************************************************
676 
677 
678 //*************************************************************************************************
684 template< typename Type // Data type of the matrix
685  , bool SO > // Storage order
686 inline Type* DynamicMatrix<Type,SO>::data( size_t i )
687 {
688  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
689  return v_ + i*nn_;
690 }
691 //*************************************************************************************************
692 
693 
694 //*************************************************************************************************
700 template< typename Type // Data type of the matrix
701  , bool SO > // Storage order
702 inline const Type* DynamicMatrix<Type,SO>::data( size_t i ) const
703 {
704  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
705  return v_ + i*nn_;
706 }
707 //*************************************************************************************************
708 
709 
710 //*************************************************************************************************
721 template< typename Type // Data type of the matrix
722  , bool SO > // Storage order
723 inline typename DynamicMatrix<Type,SO>::Iterator
725 {
726  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
727  return v_ + i*nn_;
728 }
729 //*************************************************************************************************
730 
731 
732 //*************************************************************************************************
743 template< typename Type // Data type of the matrix
744  , bool SO > // Storage order
747 {
748  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
749  return v_ + i*nn_;
750 }
751 //*************************************************************************************************
752 
753 
754 //*************************************************************************************************
765 template< typename Type // Data type of the matrix
766  , bool SO > // Storage order
769 {
770  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
771  return v_ + i*nn_;
772 }
773 //*************************************************************************************************
774 
775 
776 //*************************************************************************************************
787 template< typename Type // Data type of the matrix
788  , bool SO > // Storage order
789 inline typename DynamicMatrix<Type,SO>::Iterator
791 {
792  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
793  return v_ + i*nn_ + n_;
794 }
795 //*************************************************************************************************
796 
797 
798 //*************************************************************************************************
809 template< typename Type // Data type of the matrix
810  , bool SO > // Storage order
812  DynamicMatrix<Type,SO>::end( size_t i ) const
813 {
814  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
815  return v_ + i*nn_ + n_;
816 }
817 //*************************************************************************************************
818 
819 
820 //*************************************************************************************************
831 template< typename Type // Data type of the matrix
832  , bool SO > // Storage order
835 {
836  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
837  return v_ + i*nn_ + n_;
838 }
839 //*************************************************************************************************
840 
841 
842 
843 
844 //=================================================================================================
845 //
846 // ASSIGNMENT OPERATORS
847 //
848 //=================================================================================================
849 
850 //*************************************************************************************************
869 template< typename Type // Data type of the matrix
870  , bool SO > // Storage order
871 template< typename Other // Data type of the initialization array
872  , size_t M // Number of rows of the initialization array
873  , size_t N > // Number of columns of the initialization array
875 {
876  resize( M, N, false );
877 
878  for( size_t i=0UL; i<M; ++i )
879  for( size_t j=0UL; j<N; ++j )
880  v_[i*nn_+j] = rhs[i][j];
881 
882  return *this;
883 }
884 //*************************************************************************************************
885 
886 
887 //*************************************************************************************************
893 template< typename Type // Data type of the matrix
894  , bool SO > // Storage order
896 {
897  for( size_t i=0UL; i<m_; ++i )
898  for( size_t j=0UL; j<n_; ++j )
899  v_[i*nn_+j] = rhs;
900 
901  return *this;
902 }
903 //*************************************************************************************************
904 
905 
906 //*************************************************************************************************
915 template< typename Type // Data type of the matrix
916  , bool SO > // Storage order
918 {
919  if( &rhs == this ) return *this;
920 
921  resize( rhs.m_, rhs.n_, false );
922 
923  for( size_t i=0UL; i<m_; ++i )
924  for( size_t j=0UL; j<n_; ++j )
925  v_[i*nn_+j] = rhs(i,j);
926 
927  return *this;
928 }
929 //*************************************************************************************************
930 
931 
932 //*************************************************************************************************
941 template< typename Type // Data type of the matrix
942  , bool SO > // Storage order
943 template< typename MT // Type of the right-hand side matrix
944  , bool SO2 > // Storage order of the right-hand side matrix
946 {
947  using blaze::assign;
948 
949  if( (~rhs).canAlias( this ) ) {
950  DynamicMatrix tmp( ~rhs );
951  swap( tmp );
952  }
953  else {
954  resize( (~rhs).rows(), (~rhs).columns(), false );
956  reset();
957  assign( *this, ~rhs );
958  }
959 
960  return *this;
961 }
962 //*************************************************************************************************
963 
964 
965 //*************************************************************************************************
975 template< typename Type // Data type of the matrix
976  , bool SO > // Storage order
977 template< typename MT // Type of the right-hand side matrix
978  , bool SO2 > // Storage order of the right-hand side matrix
980 {
981  using blaze::addAssign;
982 
983  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
984  throw std::invalid_argument( "Matrix sizes do not match" );
985 
986  if( (~rhs).canAlias( this ) ) {
987  typename MT::ResultType tmp( ~rhs );
988  addAssign( *this, tmp );
989  }
990  else {
991  addAssign( *this, ~rhs );
992  }
993 
994  return *this;
995 }
996 //*************************************************************************************************
997 
998 
999 //*************************************************************************************************
1009 template< typename Type // Data type of the matrix
1010  , bool SO > // Storage order
1011 template< typename MT // Type of the right-hand side matrix
1012  , bool SO2 > // Storage order of the right-hand side matrix
1014 {
1015  using blaze::subAssign;
1016 
1017  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
1018  throw std::invalid_argument( "Matrix sizes do not match" );
1019 
1020  if( (~rhs).canAlias( this ) ) {
1021  typename MT::ResultType tmp( ~rhs );
1022  subAssign( *this, tmp );
1023  }
1024  else {
1025  subAssign( *this, ~rhs );
1026  }
1027 
1028  return *this;
1029 }
1030 //*************************************************************************************************
1031 
1032 
1033 //*************************************************************************************************
1043 template< typename Type // Data type of the matrix
1044  , bool SO > // Storage order
1045 template< typename MT // Type of the right-hand side matrix
1046  , bool SO2 > // Storage order of the right-hand side matrix
1048 {
1049  if( (~rhs).rows() != n_ )
1050  throw std::invalid_argument( "Matrix sizes do not match" );
1051 
1052  DynamicMatrix tmp( *this * (~rhs) );
1053  swap( tmp );
1054 
1055  return *this;
1056 }
1057 //*************************************************************************************************
1058 
1059 
1060 //*************************************************************************************************
1067 template< typename Type // Data type of the matrix
1068  , bool SO > // Storage order
1069 template< typename Other > // Data type of the right-hand side scalar
1070 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,SO> >::Type&
1072 {
1073  return operator=( (*this) * rhs );
1074 }
1075 //*************************************************************************************************
1076 
1077 
1078 //*************************************************************************************************
1085 template< typename Type // Data type of the matrix
1086  , bool SO > // Storage order
1087 template< typename Other > // Data type of the right-hand side scalar
1088 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,SO> >::Type&
1090 {
1091  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1092 
1093  return operator=( (*this) / rhs );
1094 }
1095 //*************************************************************************************************
1096 
1097 
1098 
1099 
1100 //=================================================================================================
1101 //
1102 // UTILITY FUNCTIONS
1103 //
1104 //=================================================================================================
1105 
1106 //*************************************************************************************************
1111 template< typename Type // Data type of the matrix
1112  , bool SO > // Storage order
1113 inline size_t DynamicMatrix<Type,SO>::rows() const
1114 {
1115  return m_;
1116 }
1117 //*************************************************************************************************
1118 
1119 
1120 //*************************************************************************************************
1125 template< typename Type // Data type of the matrix
1126  , bool SO > // Storage order
1127 inline size_t DynamicMatrix<Type,SO>::columns() const
1128 {
1129  return n_;
1130 }
1131 //*************************************************************************************************
1132 
1133 
1134 //*************************************************************************************************
1142 template< typename Type // Data type of the matrix
1143  , bool SO > // Storage order
1144 inline size_t DynamicMatrix<Type,SO>::spacing() const
1145 {
1146  return nn_;
1147 }
1148 //*************************************************************************************************
1149 
1150 
1151 //*************************************************************************************************
1156 template< typename Type // Data type of the matrix
1157  , bool SO > // Storage order
1159 {
1160  return capacity_;
1161 }
1162 //*************************************************************************************************
1163 
1164 
1165 //*************************************************************************************************
1176 template< typename Type // Data type of the sparse matrix
1177  , bool SO > // Storage order
1178 inline size_t DynamicMatrix<Type,SO>::capacity( size_t i ) const
1179 {
1180  UNUSED_PARAMETER( i );
1181  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1182  return nn_;
1183 }
1184 //*************************************************************************************************
1185 
1186 
1187 //*************************************************************************************************
1192 template< typename Type // Data type of the matrix
1193  , bool SO > // Storage order
1195 {
1196  size_t nonzeros( 0UL );
1197 
1198  for( size_t i=0UL; i<m_; ++i )
1199  for( size_t j=0UL; j<n_; ++j )
1200  if( !isDefault( v_[i*nn_+j] ) )
1201  ++nonzeros;
1202 
1203  return nonzeros;
1204 }
1205 //*************************************************************************************************
1206 
1207 
1208 //*************************************************************************************************
1214 template< typename Type // Data type of the matrix
1215  , bool SO > // Storage order
1216 inline size_t DynamicMatrix<Type,SO>::nonZeros( size_t i ) const
1217 {
1218  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1219 
1220  const size_t jend( (i+1UL)*nn_ );
1221  size_t nonzeros( 0UL );
1222 
1223  for( size_t j=i*nn_; j<jend; ++j )
1224  if( !isDefault( v_[j] ) )
1225  ++nonzeros;
1226 
1227  return nonzeros;
1228 }
1229 //*************************************************************************************************
1230 
1231 
1232 //*************************************************************************************************
1237 template< typename Type // Data type of the matrix
1238  , bool SO > // Storage order
1240 {
1241  using blaze::reset;
1242 
1243  for( size_t i=0UL; i<m_; ++i )
1244  for( size_t j=0UL; j<n_; ++j )
1245  reset( v_[i*nn_+j] );
1246 }
1247 //*************************************************************************************************
1248 
1249 
1250 //*************************************************************************************************
1261 template< typename Type // Data type of the sparse matrix
1262  , bool SO > // Storage order
1263 inline void DynamicMatrix<Type,SO>::reset( size_t i )
1264 {
1265  using blaze::reset;
1266 
1267  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1268  for( size_t j=0UL; j<n_; ++j )
1269  reset( v_[i*nn_+j] );
1270 }
1271 //*************************************************************************************************
1272 
1273 
1274 //*************************************************************************************************
1281 template< typename Type // Data type of the matrix
1282  , bool SO > // Storage order
1284 {
1285  m_ = 0UL;
1286  n_ = 0UL;
1287  nn_ = 0UL;
1288 }
1289 //*************************************************************************************************
1290 
1291 
1292 //*************************************************************************************************
1324 template< typename Type // Data type of the matrix
1325  , bool SO > // Storage order
1326 void DynamicMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1327 {
1328  using blaze::min;
1329 
1330  if( m == m_ && n == n_ ) return;
1331 
1332  const size_t nn( adjustColumns( n ) );
1333 
1334  if( preserve )
1335  {
1336  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1337  const size_t min_m( min( m, m_ ) );
1338  const size_t min_n( min( n, n_ ) );
1339 
1340  for( size_t i=0UL; i<min_m; ++i )
1341  for( size_t j=0UL; j<min_n; ++j )
1342  v[i*nn+j] = v_[i*nn_+j];
1343 
1344  if( IsBuiltin<Type>::value ) {
1345  for( size_t i=0UL; i<m; ++i )
1346  for( size_t j=n; j<nn; ++j )
1347  v[i*nn+j] = Type();
1348  }
1349 
1350  std::swap( v_, v );
1351  deallocate( v );
1352  capacity_ = m*nn;
1353  }
1354  else if( m*nn > capacity_ ) {
1355  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1356 
1357  if( IsBuiltin<Type>::value ) {
1358  for( size_t i=0UL; i<m; ++i )
1359  for( size_t j=n; j<nn; ++j )
1360  v[i*nn+j] = Type();
1361  }
1362 
1363  std::swap( v_, v );
1364  deallocate( v );
1365  capacity_ = m*nn;
1366  }
1367 
1368  m_ = m;
1369  n_ = n;
1370  nn_ = nn;
1371 }
1372 //*************************************************************************************************
1373 
1374 
1375 //*************************************************************************************************
1389 template< typename Type // Data type of the matrix
1390  , bool SO > // Storage order
1391 inline void DynamicMatrix<Type,SO>::extend( size_t m, size_t n, bool preserve )
1392 {
1393  resize( m_+m, n_+n, preserve );
1394 }
1395 //*************************************************************************************************
1396 
1397 
1398 //*************************************************************************************************
1407 template< typename Type // Data type of the matrix
1408  , bool SO > // Storage order
1409 inline void DynamicMatrix<Type,SO>::reserve( size_t elements )
1410 {
1411  if( elements > capacity_ )
1412  {
1413  // Allocating a new array
1414  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
1415 
1416  // Initializing the new array
1417  std::copy( v_, v_+capacity_, tmp );
1418 
1419  if( IsBuiltin<Type>::value ) {
1420  for( size_t i=capacity_; i<elements; ++i )
1421  tmp[i] = Type();
1422  }
1423 
1424  // Replacing the old array
1425  std::swap( tmp, v_ );
1426  deallocate( tmp );
1427  capacity_ = elements;
1428  }
1429 }
1430 //*************************************************************************************************
1431 
1432 
1433 //*************************************************************************************************
1438 template< typename Type // Data type of the matrix
1439  , bool SO > // Storage order
1441 {
1442  DynamicMatrix tmp( trans(*this) );
1443  swap( tmp );
1444  return *this;
1445 }
1446 //*************************************************************************************************
1447 
1448 
1449 //*************************************************************************************************
1457 template< typename Type // Data type of the matrix
1458  , bool SO > // Storage order
1460 {
1462 
1463  return *this;
1464 }
1465 //*************************************************************************************************
1466 
1467 
1468 //*************************************************************************************************
1485 template< typename Type // Data type of the matrix
1486  , bool SO > // Storage order
1488 {
1489  if( m_ != n_ ) return false;
1490 
1491  for( size_t i=1UL; i<m_; ++i ) {
1492  for( size_t j=0UL; j<i; ++j ) {
1493  if( !isDefault( v_[i*nn_+j] ) || !isDefault( v_[j*nn_+i] ) )
1494  return false;
1495  }
1496  }
1497 
1498  return true;
1499 }
1500 //*************************************************************************************************
1501 
1502 
1503 //*************************************************************************************************
1508 template< typename Type // Data type of the matrix
1509  , bool SO > // Storage order
1511 {
1512  if( m_ != n_ ) return false;
1513 
1514  for( size_t i=1UL; i<m_; ++i ) {
1515  for( size_t j=0UL; j<i; ++j ) {
1516  if( !equal( v_[i*nn_+j], v_[j*nn_+i] ) )
1517  return false;
1518  }
1519  }
1520 
1521  return true;
1522 }
1523 //*************************************************************************************************
1524 
1525 
1526 //*************************************************************************************************
1532 template< typename Type // Data type of the matrix
1533  , bool SO > // Storage order
1534 template< typename Other > // Data type of the scalar value
1536 {
1537  for( size_t i=0UL; i<m_; ++i )
1538  for( size_t j=0UL; j<n_; ++j )
1539  v_[i*nn_+j] *= scalar;
1540 
1541  return *this;
1542 }
1543 //*************************************************************************************************
1544 
1545 
1546 //*************************************************************************************************
1553 template< typename Type // Data type of the matrix
1554  , bool SO > // Storage order
1555 inline void DynamicMatrix<Type,SO>::swap( DynamicMatrix& m ) /* throw() */
1556 {
1557  std::swap( m_ , m.m_ );
1558  std::swap( n_ , m.n_ );
1559  std::swap( nn_, m.nn_ );
1560  std::swap( capacity_, m.capacity_ );
1561  std::swap( v_ , m.v_ );
1562 }
1563 //*************************************************************************************************
1564 
1565 
1566 //*************************************************************************************************
1572 template< typename Type // Data type of the matrix
1573  , bool SO > // Storage order
1574 inline size_t DynamicMatrix<Type,SO>::adjustColumns( size_t minColumns ) const
1575 {
1577  return minColumns + ( IT::size - ( minColumns % IT::size ) ) % IT::size;
1578  else return minColumns;
1579 }
1580 //*************************************************************************************************
1581 
1582 
1583 
1584 
1585 //=================================================================================================
1586 //
1587 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1588 //
1589 //=================================================================================================
1590 
1591 //*************************************************************************************************
1601 template< typename Type // Data type of the matrix
1602  , bool SO > // Storage order
1603 template< typename Other > // Data type of the foreign expression
1604 inline bool DynamicMatrix<Type,SO>::canAlias( const Other* alias ) const
1605 {
1606  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1607 }
1608 //*************************************************************************************************
1609 
1610 
1611 //*************************************************************************************************
1621 template< typename Type // Data type of the matrix
1622  , bool SO > // Storage order
1623 template< typename Other > // Data type of the foreign expression
1624 inline bool DynamicMatrix<Type,SO>::isAliased( const Other* alias ) const
1625 {
1626  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1627 }
1628 //*************************************************************************************************
1629 
1630 
1631 //*************************************************************************************************
1643 template< typename Type // Data type of the matrix
1644  , bool SO > // Storage order
1646  DynamicMatrix<Type,SO>::get( size_t i, size_t j ) const
1647 {
1649 
1650  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
1651  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
1652  BLAZE_INTERNAL_ASSERT( j + IT::size <= nn_, "Invalid column access index" );
1653  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
1654 
1655  return load( &v_[i*nn_+j] );
1656 }
1657 //*************************************************************************************************
1658 
1659 
1660 //*************************************************************************************************
1671 template< typename Type // Data type of the matrix
1672  , bool SO > // Storage order
1673 template< typename MT > // Type of the right-hand side dense matrix
1674 inline typename DisableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
1676 {
1677  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1678  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1679 
1680  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == ( n_ & size_t(-2) ), "Invalid end calculation" );
1681  const size_t jend( n_ & size_t(-2) );
1682 
1683  for( size_t i=0UL; i<m_; ++i ) {
1684  for( size_t j=0UL; j<jend; j+=2UL ) {
1685  v_[i*nn_+j ] = (~rhs)(i,j );
1686  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
1687  }
1688  if( jend < n_ ) {
1689  v_[i*nn_+jend] = (~rhs)(i,jend);
1690  }
1691  }
1692 }
1693 //*************************************************************************************************
1694 
1695 
1696 //*************************************************************************************************
1707 template< typename Type // Data type of the matrix
1708  , bool SO > // Storage order
1709 template< typename MT > // Type of the right-hand side dense matrix
1710 inline typename EnableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
1712 {
1713  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1714  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1715 
1717 
1718  if( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
1719  {
1720  for( size_t i=0UL; i<m_; ++i )
1721  for( size_t j=0UL; j<n_; j+=IT::size )
1722  stream( &v_[i*nn_+j], (~rhs).get(i,j) );
1723  }
1724  else
1725  {
1726  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == ( n_ & size_t(-IT::size*4) ), "Invalid end calculation" );
1727  const size_t jend( n_ & size_t(-IT::size*4) );
1728 
1729  for( size_t i=0UL; i<m_; ++i ) {
1730  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1731  store( &v_[i*nn_+j ], (~rhs).get(i,j ) );
1732  store( &v_[i*nn_+j+IT::size ], (~rhs).get(i,j+IT::size ) );
1733  store( &v_[i*nn_+j+IT::size*2UL], (~rhs).get(i,j+IT::size*2UL) );
1734  store( &v_[i*nn_+j+IT::size*3UL], (~rhs).get(i,j+IT::size*3UL) );
1735  }
1736  for( size_t j=jend; j<n_; j+=IT::size ) {
1737  store( &v_[i*nn_+j], (~rhs).get(i,j) );
1738  }
1739  }
1740  }
1741 }
1742 //*************************************************************************************************
1743 
1744 
1745 //*************************************************************************************************
1756 template< typename Type // Data type of the matrix
1757  , bool SO > // Storage order
1758 template< typename MT > // Type of the right-hand side dense matrix
1760 {
1761  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1762  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1763 
1764  const size_t block( 16UL );
1765 
1766  for( size_t ii=0UL; ii<m_; ii+=block ) {
1767  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
1768  for( size_t jj=0UL; jj<n_; jj+=block ) {
1769  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
1770  for( size_t i=ii; i<iend; ++i ) {
1771  for( size_t j=jj; j<jend; ++j ) {
1772  v_[i*nn_+j] = (~rhs)(i,j);
1773  }
1774  }
1775  }
1776  }
1777 }
1778 //*************************************************************************************************
1779 
1780 
1781 //*************************************************************************************************
1792 template< typename Type // Data type of the matrix
1793  , bool SO > // Storage order
1794 template< typename MT > // Type of the right-hand side sparse matrix
1796 {
1797  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1798  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1799 
1800  for( size_t i=0UL; i<m_; ++i )
1801  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1802  v_[i*nn_+element->index()] = element->value();
1803 }
1804 //*************************************************************************************************
1805 
1806 
1807 //*************************************************************************************************
1818 template< typename Type // Data type of the matrix
1819  , bool SO > // Storage order
1820 template< typename MT > // Type of the right-hand side sparse matrix
1822 {
1823  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1824  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1825 
1826  for( size_t j=0UL; j<n_; ++j )
1827  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1828  v_[element->index()*nn_+j] = element->value();
1829 }
1830 //*************************************************************************************************
1831 
1832 
1833 //*************************************************************************************************
1844 template< typename Type // Data type of the matrix
1845  , bool SO > // Storage order
1846 template< typename MT > // Type of the right-hand side dense matrix
1847 inline typename DisableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
1849 {
1850  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1851  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1852 
1853  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == ( n_ & size_t(-2) ), "Invalid end calculation" );
1854  const size_t jend( n_ & size_t(-2) );
1855 
1856  for( size_t i=0UL; i<m_; ++i ) {
1857  for( size_t j=0UL; j<jend; j+=2UL ) {
1858  v_[i*nn_+j ] += (~rhs)(i,j );
1859  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
1860  }
1861  if( jend < n_ ) {
1862  v_[i*nn_+jend] += (~rhs)(i,jend);
1863  }
1864  }
1865 }
1866 //*************************************************************************************************
1867 
1868 
1869 //*************************************************************************************************
1880 template< typename Type // Data type of the matrix
1881  , bool SO > // Storage order
1882 template< typename MT > // Type of the right-hand side dense matrix
1883 inline typename EnableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
1885 {
1886  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1887  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1888 
1890 
1891  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == ( n_ & size_t(-IT::size*4) ), "Invalid end calculation" );
1892  const size_t jend( n_ & size_t(-IT::size*4) );
1893 
1894  for( size_t i=0UL; i<m_; ++i ) {
1895  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1896  store( &v_[i*nn_+j ], load( &v_[i*nn_+j ] ) + (~rhs).get(i,j ) );
1897  store( &v_[i*nn_+j+IT::size ], load( &v_[i*nn_+j+IT::size ] ) + (~rhs).get(i,j+IT::size ) );
1898  store( &v_[i*nn_+j+IT::size*2UL], load( &v_[i*nn_+j+IT::size*2UL] ) + (~rhs).get(i,j+IT::size*2UL) );
1899  store( &v_[i*nn_+j+IT::size*3UL], load( &v_[i*nn_+j+IT::size*3UL] ) + (~rhs).get(i,j+IT::size*3UL) );
1900  }
1901  for( size_t j=jend; j<n_; j+=IT::size ) {
1902  store( &v_[i*nn_+j], load( &v_[i*nn_+j] ) + (~rhs).get(i,j) );
1903  }
1904  }
1905 }
1906 //*************************************************************************************************
1907 
1908 
1909 //*************************************************************************************************
1920 template< typename Type // Data type of the matrix
1921  , bool SO > // Storage order
1922 template< typename MT > // Type of the right-hand side dense matrix
1924 {
1925  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1926  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1927 
1928  const size_t block( 16UL );
1929 
1930  for( size_t ii=0UL; ii<m_; ii+=block ) {
1931  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
1932  for( size_t jj=0UL; jj<n_; jj+=block ) {
1933  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
1934  for( size_t i=ii; i<iend; ++i ) {
1935  for( size_t j=jj; j<jend; ++j ) {
1936  v_[i*nn_+j] += (~rhs)(i,j);
1937  }
1938  }
1939  }
1940  }
1941 }
1942 //*************************************************************************************************
1943 
1944 
1945 //*************************************************************************************************
1956 template< typename Type // Data type of the matrix
1957  , bool SO > // Storage order
1958 template< typename MT > // Type of the right-hand side sparse matrix
1960 {
1961  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1962  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1963 
1964  for( size_t i=0UL; i<m_; ++i )
1965  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1966  v_[i*nn_+element->index()] += element->value();
1967 }
1968 //*************************************************************************************************
1969 
1970 
1971 //*************************************************************************************************
1982 template< typename Type // Data type of the matrix
1983  , bool SO > // Storage order
1984 template< typename MT > // Type of the right-hand side sparse matrix
1986 {
1987  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1988  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1989 
1990  for( size_t j=0UL; j<n_; ++j )
1991  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1992  v_[element->index()*nn_+j] += element->value();
1993 }
1994 //*************************************************************************************************
1995 
1996 
1997 //*************************************************************************************************
2008 template< typename Type // Data type of the matrix
2009  , bool SO > // Storage order
2010 template< typename MT > // Type of the right-hand side dense matrix
2011 inline typename DisableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2013 {
2014  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2015  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2016 
2017  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == ( n_ & size_t(-2) ), "Invalid end calculation" );
2018  const size_t jend( n_ & size_t(-2) );
2019 
2020  for( size_t i=0UL; i<m_; ++i ) {
2021  for( size_t j=0UL; j<jend; j+=2UL ) {
2022  v_[i*nn_+j ] -= (~rhs)(i,j );
2023  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
2024  }
2025  if( jend < n_ ) {
2026  v_[i*nn_+jend] -= (~rhs)(i,jend);
2027  }
2028  }
2029 }
2030 //*************************************************************************************************
2031 
2032 
2033 //*************************************************************************************************
2044 template< typename Type // Data type of the matrix
2045  , bool SO > // Storage order
2046 template< typename MT > // Type of the right-hand side dense matrix
2047 inline typename EnableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2049 {
2050  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2051  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2052 
2054 
2055  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == ( n_ & size_t(-IT::size*4) ), "Invalid end calculation" );
2056  const size_t jend( n_ & size_t(-IT::size*4) );
2057 
2058  for( size_t i=0UL; i<m_; ++i ) {
2059  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2060  store( &v_[i*nn_+j ], load( &v_[i*nn_+j ] ) - (~rhs).get(i,j ) );
2061  store( &v_[i*nn_+j+IT::size ], load( &v_[i*nn_+j+IT::size ] ) - (~rhs).get(i,j+IT::size ) );
2062  store( &v_[i*nn_+j+IT::size*2UL], load( &v_[i*nn_+j+IT::size*2UL] ) - (~rhs).get(i,j+IT::size*2UL) );
2063  store( &v_[i*nn_+j+IT::size*3UL], load( &v_[i*nn_+j+IT::size*3UL] ) - (~rhs).get(i,j+IT::size*3UL) );
2064  }
2065  for( size_t j=jend; j<n_; j+=IT::size ) {
2066  store( &v_[i*nn_+j], load( &v_[i*nn_+j] ) - (~rhs).get(i,j) );
2067  }
2068  }
2069 }
2070 //*************************************************************************************************
2071 
2072 
2073 //*************************************************************************************************
2084 template< typename Type // Data type of the matrix
2085  , bool SO > // Storage order
2086 template< typename MT > // Type of the right-hand side dense matrix
2088 {
2089  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2090  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2091 
2092  const size_t block( 16UL );
2093 
2094  for( size_t ii=0UL; ii<m_; ii+=block ) {
2095  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2096  for( size_t jj=0UL; jj<n_; jj+=block ) {
2097  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2098  for( size_t i=ii; i<iend; ++i ) {
2099  for( size_t j=jj; j<jend; ++j ) {
2100  v_[i*nn_+j] -= (~rhs)(i,j);
2101  }
2102  }
2103  }
2104  }
2105 }
2106 //*************************************************************************************************
2107 
2108 
2109 //*************************************************************************************************
2120 template< typename Type // Data type of the matrix
2121  , bool SO > // Storage order
2122 template< typename MT > // Type of the right-hand side sparse matrix
2124 {
2125  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2126  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2127 
2128  for( size_t i=0UL; i<m_; ++i )
2129  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2130  v_[i*nn_+element->index()] -= element->value();
2131 }
2132 //*************************************************************************************************
2133 
2134 
2135 //*************************************************************************************************
2146 template< typename Type // Data type of the matrix
2147  , bool SO > // Storage order
2148 template< typename MT > // Type of the right-hand side sparse matrix
2150 {
2151  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2152  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2153 
2154  for( size_t j=0UL; j<n_; ++j )
2155  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2156  v_[element->index()*nn_+j] -= element->value();
2157 }
2158 //*************************************************************************************************
2159 
2160 
2161 
2162 
2163 
2164 
2165 
2166 
2167 //=================================================================================================
2168 //
2169 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2170 //
2171 //=================================================================================================
2172 
2173 //*************************************************************************************************
2181 template< typename Type > // Data type of the matrix
2182 class DynamicMatrix<Type,true> : public DenseMatrix< DynamicMatrix<Type,true>, true >
2183 {
2184  private:
2185  //**Type definitions****************************************************************************
2186  typedef IntrinsicTrait<Type> IT;
2187  //**********************************************************************************************
2188 
2189  public:
2190  //**Type definitions****************************************************************************
2191  typedef DynamicMatrix<Type,true> This;
2192  typedef This ResultType;
2195  typedef Type ElementType;
2196  typedef const Type& ReturnType;
2197  typedef typename IT::Type IntrinsicType;
2198  typedef const This& CompositeType;
2199  typedef Type& Reference;
2200  typedef const Type& ConstReference;
2201  typedef Type* Iterator;
2202  typedef const Type* ConstIterator;
2203  //**********************************************************************************************
2204 
2205  //**Compilation flags***************************************************************************
2207 
2211  enum { vectorizable = IsVectorizable<Type>::value };
2212  //**********************************************************************************************
2213 
2214  //**Constructors********************************************************************************
2217  explicit inline DynamicMatrix();
2218  explicit inline DynamicMatrix( size_t m, size_t n );
2219  explicit inline DynamicMatrix( size_t m, size_t n, Type init );
2220  inline DynamicMatrix( const DynamicMatrix& m );
2221  template< typename MT, bool SO > inline DynamicMatrix( const Matrix<MT,SO>& m );
2222 
2223  template< typename Other, size_t M, size_t N >
2224  inline DynamicMatrix( const Other (&rhs)[M][N] );
2226  //**********************************************************************************************
2227 
2228  //**Destructor**********************************************************************************
2231  inline ~DynamicMatrix();
2233  //**********************************************************************************************
2234 
2235  //**Data access functions***********************************************************************
2238  inline Reference operator()( size_t i, size_t j );
2239  inline ConstReference operator()( size_t i, size_t j ) const;
2240  inline Type* data ();
2241  inline const Type* data () const;
2242  inline Type* data ( size_t j );
2243  inline const Type* data ( size_t j ) const;
2244  inline Iterator begin ( size_t j );
2245  inline ConstIterator begin ( size_t j ) const;
2246  inline ConstIterator cbegin( size_t j ) const;
2247  inline Iterator end ( size_t j );
2248  inline ConstIterator end ( size_t j ) const;
2249  inline ConstIterator cend ( size_t j ) const;
2251  //**********************************************************************************************
2252 
2253  //**Assignment operators************************************************************************
2256  template< typename Other, size_t M, size_t N >
2257  inline DynamicMatrix& operator=( const Other (&rhs)[M][N] );
2258 
2259  inline DynamicMatrix& operator= ( Type set );
2260  inline DynamicMatrix& operator= ( const DynamicMatrix& set );
2261  template< typename MT, bool SO > inline DynamicMatrix& operator= ( const Matrix<MT,SO>& rhs );
2262  template< typename MT, bool SO > inline DynamicMatrix& operator+=( const Matrix<MT,SO>& rhs );
2263  template< typename MT, bool SO > inline DynamicMatrix& operator-=( const Matrix<MT,SO>& rhs );
2264  template< typename MT, bool SO > inline DynamicMatrix& operator*=( const Matrix<MT,SO>& rhs );
2265 
2266  template< typename Other >
2267  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
2268  operator*=( Other rhs );
2269 
2270  template< typename Other >
2271  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
2272  operator/=( Other rhs );
2274  //**********************************************************************************************
2275 
2276  //**Utility functions***************************************************************************
2279  inline size_t rows() const;
2280  inline size_t columns() const;
2281  inline size_t spacing() const;
2282  inline size_t capacity() const;
2283  inline size_t capacity( size_t j ) const;
2284  inline size_t nonZeros() const;
2285  inline size_t nonZeros( size_t j ) const;
2286  inline void reset();
2287  inline void reset( size_t j );
2288  inline void clear();
2289  void resize ( size_t m, size_t n, bool preserve=true );
2290  inline void extend ( size_t m, size_t n, bool preserve=true );
2291  inline void reserve( size_t elements );
2292  inline DynamicMatrix& transpose();
2293  inline DynamicMatrix& invert();
2294  inline bool isDiagonal() const;
2295  inline bool isSymmetric() const;
2296  template< typename Other > inline DynamicMatrix& scale( Other scalar );
2297  inline void swap( DynamicMatrix& m ) /* throw() */;
2299  //**********************************************************************************************
2300 
2301  private:
2302  //**********************************************************************************************
2304  template< typename MT >
2305  struct VectorizedAssign {
2306  enum { value = vectorizable && MT::vectorizable &&
2307  IsSame<Type,typename MT::ElementType>::value };
2308  };
2309  //**********************************************************************************************
2310 
2311  //**********************************************************************************************
2313  template< typename MT >
2314  struct VectorizedAddAssign {
2315  enum { value = vectorizable && MT::vectorizable &&
2316  IsSame<Type,typename MT::ElementType>::value &&
2317  IntrinsicTrait<Type>::addition };
2318  };
2319  //**********************************************************************************************
2320 
2321  //**********************************************************************************************
2323  template< typename MT >
2324  struct VectorizedSubAssign {
2325  enum { value = vectorizable && MT::vectorizable &&
2326  IsSame<Type,typename MT::ElementType>::value &&
2327  IntrinsicTrait<Type>::subtraction };
2328  };
2329  //**********************************************************************************************
2330 
2331  public:
2332  //**Expression template evaluation functions****************************************************
2335  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2336  template< typename Other > inline bool isAliased( const Other* alias ) const;
2337  inline IntrinsicType get ( size_t i, size_t j ) const;
2338 
2339  template< typename MT >
2340  inline typename DisableIf< VectorizedAssign<MT> >::Type
2341  assign( const DenseMatrix<MT,true>& rhs );
2342 
2343  template< typename MT >
2344  inline typename EnableIf< VectorizedAssign<MT> >::Type
2345  assign( const DenseMatrix<MT,true>& rhs );
2346 
2347  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
2348  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
2349  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
2350 
2351  template< typename MT >
2352  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
2353  addAssign( const DenseMatrix<MT,true>& rhs );
2354 
2355  template< typename MT >
2356  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
2357  addAssign( const DenseMatrix<MT,true>& rhs );
2358 
2359  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
2360  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
2361  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
2362 
2363  template< typename MT >
2364  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
2365  subAssign ( const DenseMatrix<MT,true>& rhs );
2366 
2367  template< typename MT >
2368  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
2369  subAssign ( const DenseMatrix<MT,true>& rhs );
2370 
2371  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
2372  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
2373  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
2375  //**********************************************************************************************
2376 
2377  private:
2378  //**Utility functions***************************************************************************
2381  inline size_t adjustRows( size_t minRows ) const;
2383  //**********************************************************************************************
2384 
2385  //**Member variables****************************************************************************
2388  size_t m_;
2389  size_t mm_;
2390  size_t n_;
2391  size_t capacity_;
2392  Type* BLAZE_RESTRICT v_;
2393 
2403  //**********************************************************************************************
2404 
2405  //**Compile time checks*************************************************************************
2410  //**********************************************************************************************
2411 };
2413 //*************************************************************************************************
2414 
2415 
2416 
2417 
2418 //=================================================================================================
2419 //
2420 // CONSTRUCTORS
2421 //
2422 //=================================================================================================
2423 
2424 //*************************************************************************************************
2428 template< typename Type > // Data type of the matrix
2430  : m_ ( 0UL ) // The current number of rows of the matrix
2431  , mm_ ( 0UL ) // The alignment adjusted number of rows
2432  , n_ ( 0UL ) // The current number of columns of the matrix
2433  , capacity_( 0UL ) // The maximum capacity of the matrix
2434  , v_ ( NULL ) // The matrix elements
2435 {}
2437 //*************************************************************************************************
2438 
2439 
2440 //*************************************************************************************************
2450 template< typename Type > // Data type of the matrix
2451 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n )
2452  : m_ ( m ) // The current number of rows of the matrix
2453  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
2454  , n_ ( n ) // The current number of columns of the matrix
2455  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2456  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2457 {
2458  if( IsBuiltin<Type>::value ) {
2459  for( size_t j=0UL; j<n_; ++j )
2460  for( size_t i=m_; i<mm_; ++i ) {
2461  v_[i+j*mm_] = Type();
2462  }
2463  }
2464 }
2466 //*************************************************************************************************
2467 
2468 
2469 //*************************************************************************************************
2479 template< typename Type > // Data type of the matrix
2480 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, Type init )
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_] = init;
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 //*************************************************************************************************
2510 template< typename Type > // Data type of the matrix
2511 inline DynamicMatrix<Type,true>::DynamicMatrix( const DynamicMatrix& m )
2512  : m_ ( m.m_ ) // The current number of rows of the matrix
2513  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
2514  , n_ ( m.n_ ) // The current number of columns of the matrix
2515  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2516  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2517 {
2518  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
2519 
2520  for( size_t i=0UL; i<capacity_; ++i )
2521  v_[i] = m.v_[i];
2522 }
2524 //*************************************************************************************************
2525 
2526 
2527 //*************************************************************************************************
2533 template< typename Type > // Data type of the matrix
2534 template< typename MT // Type of the foreign matrix
2535  , bool SO > // Storage order of the foreign matrix
2536 inline DynamicMatrix<Type,true>::DynamicMatrix( const Matrix<MT,SO>& m )
2537  : m_ ( (~m).rows() ) // The current number of rows of the matrix
2538  , mm_ ( adjustRows( m_ ) ) // The alignment adjusted number of rows
2539  , n_ ( (~m).columns() ) // The current number of columns of the matrix
2540  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2541  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2542 {
2543  using blaze::assign;
2544 
2545  if( IsBuiltin<Type>::value ) {
2546  for( size_t j=0UL; j<n_; ++j )
2547  for( size_t i=( IsSparseMatrix<MT>::value )?( 0UL ):( m_ ); i<mm_; ++i ) {
2548  v_[i+j*mm_] = Type();
2549  }
2550  }
2551 
2552  assign( *this, ~m );
2553 }
2555 //*************************************************************************************************
2556 
2557 
2558 //*************************************************************************************************
2579 template< typename Type > // Data type of the matrix
2580 template< typename Other // Data type of the initialization array
2581  , size_t M // Number of rows of the initialization array
2582  , size_t N > // Number of columns of the initialization array
2583 inline DynamicMatrix<Type,true>::DynamicMatrix( const Other (&rhs)[M][N] )
2584  : m_ ( M ) // The current number of rows of the matrix
2585  , mm_ ( adjustRows( M ) ) // The alignment adjusted number of rows
2586  , n_ ( N ) // The current number of columns of the matrix
2587  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2588  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2589 {
2590  for( size_t j=0UL; j<N; ++j ) {
2591  for( size_t i=0UL; i<M; ++i )
2592  v_[i+j*mm_] = rhs[i][j];
2593 
2594  if( IsBuiltin<Type>::value ) {
2595  for( size_t i=M; i<mm_; ++i )
2596  v_[i+j*mm_] = Type();
2597  }
2598  }
2599 }
2601 //*************************************************************************************************
2602 
2603 
2604 
2605 
2606 //=================================================================================================
2607 //
2608 // DESTRUCTOR
2609 //
2610 //=================================================================================================
2611 
2612 //*************************************************************************************************
2616 template< typename Type > // Data type of the matrix
2618 {
2619  deallocate( v_ );
2620 }
2622 //*************************************************************************************************
2623 
2624 
2625 
2626 
2627 //=================================================================================================
2628 //
2629 // DATA ACCESS FUNCTIONS
2630 //
2631 //=================================================================================================
2632 
2633 //*************************************************************************************************
2641 template< typename Type > // Data type of the matrix
2642 inline typename DynamicMatrix<Type,true>::Reference
2643  DynamicMatrix<Type,true>::operator()( size_t i, size_t j )
2644 {
2645  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
2646  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
2647  return v_[i+j*mm_];
2648 }
2650 //*************************************************************************************************
2651 
2652 
2653 //*************************************************************************************************
2661 template< typename Type > // Data type of the matrix
2662 inline typename DynamicMatrix<Type,true>::ConstReference
2663  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) const
2664 {
2665  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
2666  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
2667  return v_[i+j*mm_];
2668 }
2670 //*************************************************************************************************
2671 
2672 
2673 //*************************************************************************************************
2679 template< typename Type > // Data type of the matrix
2680 inline Type* DynamicMatrix<Type,true>::data()
2681 {
2682  return v_;
2683 }
2685 //*************************************************************************************************
2686 
2687 
2688 //*************************************************************************************************
2694 template< typename Type > // Data type of the matrix
2695 inline const Type* DynamicMatrix<Type,true>::data() const
2696 {
2697  return v_;
2698 }
2700 //*************************************************************************************************
2701 
2702 
2703 //*************************************************************************************************
2710 template< typename Type > // Data type of the matrix
2711 inline Type* DynamicMatrix<Type,true>::data( size_t j )
2712 {
2713  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2714  return v_ + j*mm_;
2715 }
2717 //*************************************************************************************************
2718 
2719 
2720 //*************************************************************************************************
2727 template< typename Type > // Data type of the matrix
2728 inline const Type* DynamicMatrix<Type,true>::data( size_t j ) const
2729 {
2730  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2731  return v_ + j*mm_;
2732 }
2734 //*************************************************************************************************
2735 
2736 
2737 //*************************************************************************************************
2744 template< typename Type > // Data type of the matrix
2745 inline typename DynamicMatrix<Type,true>::Iterator
2747 {
2748  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2749  return v_ + j*mm_;
2750 }
2752 //*************************************************************************************************
2753 
2754 
2755 //*************************************************************************************************
2762 template< typename Type > // Data type of the matrix
2763 inline typename DynamicMatrix<Type,true>::ConstIterator
2764  DynamicMatrix<Type,true>::begin( size_t j ) const
2765 {
2766  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2767  return v_ + j*mm_;
2768 }
2770 //*************************************************************************************************
2771 
2772 
2773 //*************************************************************************************************
2780 template< typename Type > // Data type of the matrix
2781 inline typename DynamicMatrix<Type,true>::ConstIterator
2782  DynamicMatrix<Type,true>::cbegin( size_t j ) const
2783 {
2784  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2785  return v_ + j*mm_;
2786 }
2788 //*************************************************************************************************
2789 
2790 
2791 //*************************************************************************************************
2798 template< typename Type > // Data type of the matrix
2799 inline typename DynamicMatrix<Type,true>::Iterator
2800  DynamicMatrix<Type,true>::end( size_t j )
2801 {
2802  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2803  return v_ + j*mm_ + m_;
2804 }
2806 //*************************************************************************************************
2807 
2808 
2809 //*************************************************************************************************
2816 template< typename Type > // Data type of the matrix
2817 inline typename DynamicMatrix<Type,true>::ConstIterator
2818  DynamicMatrix<Type,true>::end( size_t j ) const
2819 {
2820  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2821  return v_ + j*mm_ + m_;
2822 }
2824 //*************************************************************************************************
2825 
2826 
2827 //*************************************************************************************************
2834 template< typename Type > // Data type of the matrix
2835 inline typename DynamicMatrix<Type,true>::ConstIterator
2836  DynamicMatrix<Type,true>::cend( size_t j ) const
2837 {
2838  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2839  return v_ + j*mm_ + m_;
2840 }
2842 //*************************************************************************************************
2843 
2844 
2845 
2846 
2847 //=================================================================================================
2848 //
2849 // ASSIGNMENT OPERATORS
2850 //
2851 //=================================================================================================
2852 
2853 //*************************************************************************************************
2873 template< typename Type > // Data type of the matrix
2874 template< typename Other // Data type of the initialization array
2875  , size_t M // Number of rows of the initialization array
2876  , size_t N > // Number of columns of the initialization array
2877 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Other (&rhs)[M][N] )
2878 {
2879  resize( M, N, false );
2880 
2881  for( size_t j=0UL; j<N; ++j )
2882  for( size_t i=0UL; i<M; ++i )
2883  v_[i+j*mm_] = rhs[i][j];
2884 
2885  return *this;
2886 }
2888 //*************************************************************************************************
2889 
2890 
2891 //*************************************************************************************************
2898 template< typename Type > // Data type of the matrix
2899 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( Type rhs )
2900 {
2901  for( size_t j=0UL; j<n_; ++j )
2902  for( size_t i=0UL; i<m_; ++i )
2903  v_[i+j*mm_] = rhs;
2904 
2905  return *this;
2906 }
2908 //*************************************************************************************************
2909 
2910 
2911 //*************************************************************************************************
2921 template< typename Type > // Data type of the matrix
2922 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const DynamicMatrix& rhs )
2923 {
2924  if( &rhs == this ) return *this;
2925 
2926  resize( rhs.m_, rhs.n_, false );
2927 
2928  for( size_t j=0UL; j<n_; ++j )
2929  for( size_t i=0UL; i<m_; ++i )
2930  v_[i+j*mm_] = rhs(i,j);
2931 
2932  return *this;
2933 }
2935 //*************************************************************************************************
2936 
2937 
2938 //*************************************************************************************************
2948 template< typename Type > // Data type of the matrix
2949 template< typename MT // Type of the right-hand side matrix
2950  , bool SO > // Storage order of the right-hand side matrix
2951 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Matrix<MT,SO>& rhs )
2952 {
2953  using blaze::assign;
2954 
2955  if( (~rhs).canAlias( this ) ) {
2956  DynamicMatrix tmp( ~rhs );
2957  swap( tmp );
2958  }
2959  else {
2960  resize( (~rhs).rows(), (~rhs).columns(), false );
2961  if( IsSparseMatrix<MT>::value )
2962  reset();
2963  assign( *this, ~rhs );
2964  }
2965 
2966  return *this;
2967 }
2969 //*************************************************************************************************
2970 
2971 
2972 //*************************************************************************************************
2983 template< typename Type > // Data type of the matrix
2984 template< typename MT // Type of the right-hand side matrix
2985  , bool SO > // Storage order of the right-hand side matrix
2986 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
2987 {
2988  using blaze::addAssign;
2989 
2990  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
2991  throw std::invalid_argument( "Matrix sizes do not match" );
2992 
2993  if( (~rhs).canAlias( this ) ) {
2994  typename MT::ResultType tmp( ~rhs );
2995  addAssign( *this, tmp );
2996  }
2997  else {
2998  addAssign( *this, ~rhs );
2999  }
3000 
3001  return *this;
3002 }
3004 //*************************************************************************************************
3005 
3006 
3007 //*************************************************************************************************
3018 template< typename Type > // Data type of the matrix
3019 template< typename MT // Type of the right-hand side matrix
3020  , bool SO > // Storage order of the right-hand side matrix
3021 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
3022 {
3023  using blaze::subAssign;
3024 
3025  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3026  throw std::invalid_argument( "Matrix sizes do not match" );
3027 
3028  if( (~rhs).canAlias( this ) ) {
3029  typename MT::ResultType tmp( ~rhs );
3030  subAssign( *this, tmp );
3031  }
3032  else {
3033  subAssign( *this, ~rhs );
3034  }
3035 
3036  return *this;
3037 }
3039 //*************************************************************************************************
3040 
3041 
3042 //*************************************************************************************************
3053 template< typename Type > // Data type of the matrix
3054 template< typename MT // Type of the right-hand side matrix
3055  , bool SO > // Storage order of the right-hand side matrix
3056 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
3057 {
3058  if( (~rhs).rows() != n_ )
3059  throw std::invalid_argument( "Matrix sizes do not match" );
3060 
3061  DynamicMatrix tmp( *this * (~rhs) );
3062  swap( tmp );
3063 
3064  return *this;
3065 }
3067 //*************************************************************************************************
3068 
3069 
3070 //*************************************************************************************************
3078 template< typename Type > // Data type of the matrix
3079 template< typename Other > // Data type of the right-hand side scalar
3080 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,true> >::Type&
3081  DynamicMatrix<Type,true>::operator*=( Other rhs )
3082 {
3083  return operator=( (*this) * rhs );
3084 }
3086 //*************************************************************************************************
3087 
3088 
3089 //*************************************************************************************************
3097 template< typename Type > // Data type of the matrix
3098 template< typename Other > // Data type of the right-hand side scalar
3099 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,true> >::Type&
3100  DynamicMatrix<Type,true>::operator/=( Other rhs )
3101 {
3102  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3103 
3104  return operator=( (*this) / rhs );
3105 }
3107 //*************************************************************************************************
3108 
3109 
3110 
3111 
3112 //=================================================================================================
3113 //
3114 // UTILITY FUNCTIONS
3115 //
3116 //=================================================================================================
3117 
3118 //*************************************************************************************************
3124 template< typename Type > // Data type of the matrix
3125 inline size_t DynamicMatrix<Type,true>::rows() const
3126 {
3127  return m_;
3128 }
3130 //*************************************************************************************************
3131 
3132 
3133 //*************************************************************************************************
3139 template< typename Type > // Data type of the matrix
3140 inline size_t DynamicMatrix<Type,true>::columns() const
3141 {
3142  return n_;
3143 }
3145 //*************************************************************************************************
3146 
3147 
3148 //*************************************************************************************************
3157 template< typename Type > // Data type of the matrix
3158 inline size_t DynamicMatrix<Type,true>::spacing() const
3159 {
3160  return mm_;
3161 }
3163 //*************************************************************************************************
3164 
3165 
3166 //*************************************************************************************************
3172 template< typename Type > // Data type of the matrix
3173 inline size_t DynamicMatrix<Type,true>::capacity() const
3174 {
3175  return capacity_;
3176 }
3178 //*************************************************************************************************
3179 
3180 
3181 //*************************************************************************************************
3188 template< typename Type > // Data type of the sparse matrix
3189 inline size_t DynamicMatrix<Type,true>::capacity( size_t j ) const
3190 {
3191  UNUSED_PARAMETER( j );
3192  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3193  return mm_;
3194 }
3196 //*************************************************************************************************
3197 
3198 
3199 //*************************************************************************************************
3205 template< typename Type > // Data type of the matrix
3206 inline size_t DynamicMatrix<Type,true>::nonZeros() const
3207 {
3208  size_t nonzeros( 0UL );
3209 
3210  for( size_t j=0UL; j<n_; ++j )
3211  for( size_t i=0UL; i<m_; ++i )
3212  if( !isDefault( v_[i+j*mm_] ) )
3213  ++nonzeros;
3214 
3215  return nonzeros;
3216 }
3218 //*************************************************************************************************
3219 
3220 
3221 //*************************************************************************************************
3228 template< typename Type > // Data type of the matrix
3229 inline size_t DynamicMatrix<Type,true>::nonZeros( size_t j ) const
3230 {
3231  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3232 
3233  const size_t iend( (j+1UL)*mm_ );
3234  size_t nonzeros( 0UL );
3235 
3236  for( size_t i=j*mm_; i<iend; ++i )
3237  if( !isDefault( v_[i] ) )
3238  ++nonzeros;
3239 
3240  return nonzeros;
3241 }
3243 //*************************************************************************************************
3244 
3245 
3246 //*************************************************************************************************
3252 template< typename Type > // Data type of the matrix
3253 inline void DynamicMatrix<Type,true>::reset()
3254 {
3255  using blaze::reset;
3256 
3257  for( size_t j=0UL; j<n_; ++j )
3258  for( size_t i=0UL; i<m_; ++i )
3259  reset( v_[i+j*mm_] );
3260 }
3262 //*************************************************************************************************
3263 
3264 
3265 //*************************************************************************************************
3275 template< typename Type > // Data type of the sparse matrix
3276 inline void DynamicMatrix<Type,true>::reset( size_t j )
3277 {
3278  using blaze::reset;
3279 
3280  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3281  for( size_t i=0UL; i<m_; ++i )
3282  reset( v_[i+j*mm_] );
3283 }
3285 //*************************************************************************************************
3286 
3287 
3288 //*************************************************************************************************
3296 template< typename Type > // Data type of the matrix
3297 inline void DynamicMatrix<Type,true>::clear()
3298 {
3299  m_ = 0UL;
3300  mm_ = 0UL;
3301  n_ = 0UL;
3302 }
3304 //*************************************************************************************************
3305 
3306 
3307 //*************************************************************************************************
3340 template< typename Type > // Data type of the matrix
3341 void DynamicMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3342 {
3343  using blaze::min;
3344 
3345  if( m == m_ && n == n_ ) return;
3346 
3347  const size_t mm( adjustRows( m ) );
3348 
3349  if( preserve )
3350  {
3351  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
3352  const size_t min_m( min( m, m_ ) );
3353  const size_t min_n( min( n, n_ ) );
3354 
3355  for( size_t j=0UL; j<min_n; ++j )
3356  for( size_t i=0UL; i<min_m; ++i )
3357  v[i+j*mm] = v_[i+j*mm_];
3358 
3359  if( IsBuiltin<Type>::value ) {
3360  for( size_t j=0UL; j<n; ++j )
3361  for( size_t i=m; i<mm; ++i )
3362  v[i+j*mm] = Type();
3363  }
3364 
3365  std::swap( v_, v );
3366  deallocate( v );
3367  capacity_ = mm*n;
3368  }
3369  else if( mm*n > capacity_ ) {
3370  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
3371 
3372  if( IsBuiltin<Type>::value ) {
3373  for( size_t j=0UL; j<n; ++j )
3374  for( size_t i=m; i<mm; ++i )
3375  v[i+j*mm] = Type();
3376  }
3377 
3378  std::swap( v_, v );
3379  deallocate( v );
3380  capacity_ = mm*n;
3381  }
3382 
3383  m_ = m;
3384  mm_ = mm;
3385  n_ = n;
3386 }
3388 //*************************************************************************************************
3389 
3390 
3391 //*************************************************************************************************
3406 template< typename Type > // Data type of the matrix
3407 inline void DynamicMatrix<Type,true>::extend( size_t m, size_t n, bool preserve )
3408 {
3409  resize( m_+m, n_+n, preserve );
3410 }
3412 //*************************************************************************************************
3413 
3414 
3415 //*************************************************************************************************
3425 template< typename Type > // Data type of the matrix
3426 inline void DynamicMatrix<Type,true>::reserve( size_t elements )
3427 {
3428  if( elements > capacity_ )
3429  {
3430  // Allocating a new array
3431  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
3432 
3433  // Initializing the new array
3434  std::copy( v_, v_+capacity_, tmp );
3435 
3436  if( IsBuiltin<Type>::value ) {
3437  for( size_t i=capacity_; i<elements; ++i )
3438  tmp[i] = Type();
3439  }
3440 
3441  // Replacing the old array
3442  std::swap( tmp, v_ );
3443  deallocate( tmp );
3444  capacity_ = elements;
3445  }
3446 }
3448 //*************************************************************************************************
3449 
3450 
3451 //*************************************************************************************************
3457 template< typename Type > // Data type of the matrix
3458 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::transpose()
3459 {
3460  DynamicMatrix tmp( trans(*this) );
3461  swap( tmp );
3462  return *this;
3463 }
3465 //*************************************************************************************************
3466 
3467 
3468 //*************************************************************************************************
3477 template< typename Type > // Data type of the matrix
3478 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::invert()
3479 {
3481 
3482  return *this;
3483 }
3485 //*************************************************************************************************
3486 
3487 
3488 //*************************************************************************************************
3506 template< typename Type > // Data type of the matrix
3507 inline bool DynamicMatrix<Type,true>::isDiagonal() const
3508 {
3509  if( m_ != n_ ) return false;
3510 
3511  for( size_t j=1UL; j<n_; ++j ) {
3512  for( size_t i=0UL; i<j; ++i ) {
3513  if( !isDefault( v_[i+j*mm_] ) || !isDefault( v_[j+i*mm_] ) )
3514  return false;
3515  }
3516  }
3517 
3518  return true;
3519 }
3521 //*************************************************************************************************
3522 
3523 
3524 //*************************************************************************************************
3530 template< typename Type > // Data type of the matrix
3531 inline bool DynamicMatrix<Type,true>::isSymmetric() const
3532 {
3533  if( m_ != n_ ) return false;
3534 
3535  for( size_t j=1UL; j<n_; ++j ) {
3536  for( size_t i=0UL; i<j; ++i ) {
3537  if( !equal( v_[i+j*mm_], v_[j+i*mm_] ) )
3538  return false;
3539  }
3540  }
3541 
3542  return true;
3543 }
3545 //*************************************************************************************************
3546 
3547 
3548 //*************************************************************************************************
3555 template< typename Type > // Data type of the matrix
3556 template< typename Other > // Data type of the scalar value
3557 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::scale( Other scalar )
3558 {
3559  for( size_t j=0UL; j<n_; ++j )
3560  for( size_t i=0UL; i<m_; ++i )
3561  v_[i+j*mm_] *= scalar;
3562 
3563  return *this;
3564 }
3566 //*************************************************************************************************
3567 
3568 
3569 //*************************************************************************************************
3577 template< typename Type > // Data type of the matrix
3578 inline void DynamicMatrix<Type,true>::swap( DynamicMatrix& m ) /* throw() */
3579 {
3580  std::swap( m_ , m.m_ );
3581  std::swap( mm_, m.mm_ );
3582  std::swap( n_ , m.n_ );
3583  std::swap( capacity_, m.capacity_ );
3584  std::swap( v_ , m.v_ );
3585 }
3587 //*************************************************************************************************
3588 
3589 
3590 //*************************************************************************************************
3597 template< typename Type > // Data type of the matrix
3598 inline size_t DynamicMatrix<Type,true>::adjustRows( size_t minRows ) const
3599 {
3600  if( IsBuiltin<Type>::value )
3601  return minRows + ( IT::size - ( minRows % IT::size ) ) % IT::size;
3602  else return minRows;
3603 }
3605 //*************************************************************************************************
3606 
3607 
3608 
3609 
3610 //=================================================================================================
3611 //
3612 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3613 //
3614 //=================================================================================================
3615 
3616 //*************************************************************************************************
3627 template< typename Type > // Data type of the matrix
3628 template< typename Other > // Data type of the foreign expression
3629 inline bool DynamicMatrix<Type,true>::canAlias( const Other* alias ) const
3630 {
3631  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3632 }
3634 //*************************************************************************************************
3635 
3636 
3637 //*************************************************************************************************
3648 template< typename Type > // Data type of the matrix
3649 template< typename Other > // Data type of the foreign expression
3650 inline bool DynamicMatrix<Type,true>::isAliased( const Other* alias ) const
3651 {
3652  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3653 }
3655 //*************************************************************************************************
3656 
3657 
3658 //*************************************************************************************************
3671 template< typename Type > // Data type of the matrix
3672 inline typename DynamicMatrix<Type,true>::IntrinsicType
3673  DynamicMatrix<Type,true>::get( size_t i, size_t j ) const
3674 {
3676 
3677  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
3678  BLAZE_INTERNAL_ASSERT( i + IT::size <= mm_, "Invalid row access index" );
3679  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
3680  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
3681 
3682  return load( &v_[i+j*mm_] );
3683 }
3685 //*************************************************************************************************
3686 
3687 
3688 //*************************************************************************************************
3700 template< typename Type > // Data type of the matrix
3701 template< typename MT > // Type of the right-hand side dense matrix
3702 inline typename DisableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
3703  DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
3704 {
3705  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3706  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3707 
3708  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ( m_ & size_t(-2) ), "Invalid end calculation" );
3709  const size_t iend( m_ & size_t(-2) );
3710 
3711  for( size_t j=0UL; j<n_; ++j ) {
3712  for( size_t i=0UL; i<iend; i+=2UL ) {
3713  v_[i +j*mm_] = (~rhs)(i ,j);
3714  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
3715  }
3716  if( iend < m_ ) {
3717  v_[iend+j*mm_] = (~rhs)(iend,j);
3718  }
3719  }
3720 }
3722 //*************************************************************************************************
3723 
3724 
3725 //*************************************************************************************************
3737 template< typename Type > // Data type of the matrix
3738 template< typename MT > // Type of the right-hand side dense matrix
3739 inline typename EnableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
3740  DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
3741 {
3742  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3743  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3744 
3746 
3747  if( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
3748  {
3749  for( size_t j=0UL; j<n_; ++j )
3750  for( size_t i=0UL; i<m_; i+=IT::size )
3751  stream( &v_[i+j*mm_], (~rhs).get(i,j) );
3752  }
3753  else
3754  {
3755  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ( m_ & size_t(-IT::size*4) ), "Invalid end calculation" );
3756  const size_t iend( m_ & size_t(-IT::size*4) );
3757 
3758  for( size_t j=0UL; j<n_; ++j ) {
3759  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3760  store( &v_[i+j*mm_ ], (~rhs).get(i ,j) );
3761  store( &v_[i+j*mm_+IT::size ], (~rhs).get(i+IT::size ,j) );
3762  store( &v_[i+j*mm_+IT::size*2UL], (~rhs).get(i+IT::size*2UL,j) );
3763  store( &v_[i+j*mm_+IT::size*3UL], (~rhs).get(i+IT::size*3UL,j) );
3764  }
3765  for( size_t i=iend; i<m_; i+=IT::size ) {
3766  store( &v_[i+j*mm_], (~rhs).get(i,j) );
3767  }
3768  }
3769  }
3770 }
3772 //*************************************************************************************************
3773 
3774 
3775 //*************************************************************************************************
3787 template< typename Type > // Data type of the matrix
3788 template< typename MT > // Type of the right-hand side dense matrix
3789 inline void DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,false>& rhs )
3790 {
3791  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3792  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3793 
3794  const size_t block( 16UL );
3795 
3796  for( size_t jj=0UL; jj<n_; jj+=block ) {
3797  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3798  for( size_t ii=0UL; ii<m_; ii+=block ) {
3799  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3800  for( size_t j=jj; j<jend; ++j ) {
3801  for( size_t i=ii; i<iend; ++i ) {
3802  v_[i+j*mm_] = (~rhs)(i,j);
3803  }
3804  }
3805  }
3806  }
3807 }
3809 //*************************************************************************************************
3810 
3811 
3812 //*************************************************************************************************
3824 template< typename Type > // Data type of the matrix
3825 template< typename MT > // Type of the right-hand side sparse matrix
3826 inline void DynamicMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
3827 {
3828  for( size_t j=0UL; j<(~rhs).columns(); ++j )
3829  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3830  v_[element->index()+j*mm_] = element->value();
3831 }
3833 //*************************************************************************************************
3834 
3835 
3836 //*************************************************************************************************
3848 template< typename Type > // Data type of the matrix
3849 template< typename MT > // Type of the right-hand side sparse matrix
3850 inline void DynamicMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
3851 {
3852  for( size_t i=0UL; i<(~rhs).rows(); ++i )
3853  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3854  v_[i+element->index()*mm_] = element->value();
3855 }
3857 //*************************************************************************************************
3858 
3859 
3860 //*************************************************************************************************
3872 template< typename Type > // Data type of the matrix
3873 template< typename MT > // Type of the right-hand side dense matrix
3874 inline typename DisableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
3875  DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
3876 {
3877  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3878  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3879 
3880  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ( m_ & size_t(-2) ), "Invalid end calculation" );
3881  const size_t iend( m_ & size_t(-2) );
3882 
3883  for( size_t j=0UL; j<n_; ++j ) {
3884  for( size_t i=0UL; i<iend; i+=2UL ) {
3885  v_[i +j*mm_] += (~rhs)(i ,j);
3886  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
3887  }
3888  if( iend < m_ ) {
3889  v_[iend+j*mm_] += (~rhs)(iend,j);
3890  }
3891  }
3892 }
3894 //*************************************************************************************************
3895 
3896 
3897 //*************************************************************************************************
3909 template< typename Type > // Data type of the matrix
3910 template< typename MT > // Type of the right-hand side dense matrix
3911 inline typename EnableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
3912  DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
3913 {
3914  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3915  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3916 
3918 
3919  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ( m_ & size_t(-IT::size*4) ), "Invalid end calculation" );
3920  const size_t iend( m_ & size_t(-IT::size*4) );
3921 
3922  for( size_t j=0UL; j<n_; ++j ) {
3923  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3924  store( &v_[i+j*mm_ ], load( &v_[i+j*mm_ ] ) + (~rhs).get(i ,j) );
3925  store( &v_[i+j*mm_+IT::size ], load( &v_[i+j*mm_+IT::size ] ) + (~rhs).get(i+IT::size ,j) );
3926  store( &v_[i+j*mm_+IT::size*2UL], load( &v_[i+j*mm_+IT::size*2UL] ) + (~rhs).get(i+IT::size*2UL,j) );
3927  store( &v_[i+j*mm_+IT::size*3UL], load( &v_[i+j*mm_+IT::size*3UL] ) + (~rhs).get(i+IT::size*3UL,j) );
3928  }
3929  for( size_t i=iend; i<m_; i+=IT::size ) {
3930  store( &v_[i+j*mm_], load( &v_[i+j*mm_] ) + (~rhs).get(i,j) );
3931  }
3932  }
3933 }
3935 //*************************************************************************************************
3936 
3937 
3938 //*************************************************************************************************
3950 template< typename Type > // Data type of the matrix
3951 template< typename MT > // Type of the right-hand side dense matrix
3952 inline void DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,false>& rhs )
3953 {
3954  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3955  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3956 
3957  const size_t block( 16UL );
3958 
3959  for( size_t jj=0UL; jj<n_; jj+=block ) {
3960  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3961  for( size_t ii=0UL; ii<m_; ii+=block ) {
3962  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3963  for( size_t j=jj; j<jend; ++j ) {
3964  for( size_t i=ii; i<iend; ++i ) {
3965  v_[i+j*mm_] += (~rhs)(i,j);
3966  }
3967  }
3968  }
3969  }
3970 }
3972 //*************************************************************************************************
3973 
3974 
3975 //*************************************************************************************************
3987 template< typename Type > // Data type of the matrix
3988 template< typename MT > // Type of the right-hand side sparse matrix
3989 inline void DynamicMatrix<Type,true>::addAssign( const SparseMatrix<MT,true>& rhs )
3990 {
3991  for( size_t j=0UL; j<(~rhs).columns(); ++j )
3992  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3993  v_[element->index()+j*mm_] += element->value();
3994 }
3996 //*************************************************************************************************
3997 
3998 
3999 //*************************************************************************************************
4011 template< typename Type > // Data type of the matrix
4012 template< typename MT > // Type of the right-hand side sparse matrix
4013 inline void DynamicMatrix<Type,true>::addAssign( const SparseMatrix<MT,false>& rhs )
4014 {
4015  for( size_t i=0UL; i<(~rhs).rows(); ++i )
4016  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4017  v_[i+element->index()*mm_] += element->value();
4018 }
4020 //*************************************************************************************************
4021 
4022 
4023 //*************************************************************************************************
4035 template< typename Type > // Data type of the matrix
4036 template< typename MT > // Type of the right-hand side dense matrix
4037 inline typename DisableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
4038  DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
4039 {
4040  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4041  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4042 
4043  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ( m_ & size_t(-2) ), "Invalid end calculation" );
4044  const size_t iend( m_ & size_t(-2) );
4045 
4046  for( size_t j=0UL; j<n_; ++j ) {
4047  for( size_t i=0UL; i<iend; i+=2UL ) {
4048  v_[i +j*mm_] -= (~rhs)(i ,j);
4049  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
4050  }
4051  if( iend < m_ ) {
4052  v_[iend+j*mm_] -= (~rhs)(iend,j);
4053  }
4054  }
4055 }
4057 //*************************************************************************************************
4058 
4059 
4060 //*************************************************************************************************
4073 template< typename Type > // Data type of the matrix
4074 template< typename MT > // Type of the right-hand side dense matrix
4075 inline typename EnableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
4076  DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
4077 {
4078  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4079  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4080 
4082 
4083  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ( m_ & size_t(-IT::size*4) ), "Invalid end calculation" );
4084  const size_t iend( m_ & size_t(-IT::size*4) );
4085 
4086  for( size_t j=0UL; j<n_; ++j ) {
4087  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4088  store( &v_[i+j*mm_ ], load( &v_[i+j*mm_ ] ) - (~rhs).get(i ,j) );
4089  store( &v_[i+j*mm_+IT::size ], load( &v_[i+j*mm_+IT::size ] ) - (~rhs).get(i+IT::size ,j) );
4090  store( &v_[i+j*mm_+IT::size*2UL], load( &v_[i+j*mm_+IT::size*2UL] ) - (~rhs).get(i+IT::size*2UL,j) );
4091  store( &v_[i+j*mm_+IT::size*3UL], load( &v_[i+j*mm_+IT::size*3UL] ) - (~rhs).get(i+IT::size*3UL,j) );
4092  }
4093  for( size_t i=iend; i<m_; i+=IT::size ) {
4094  store( &v_[i+j*mm_], load( &v_[i+j*mm_] ) - (~rhs).get(i,j) );
4095  }
4096  }
4097 }
4099 //*************************************************************************************************
4100 
4101 
4102 //*************************************************************************************************
4114 template< typename Type > // Data type of the matrix
4115 template< typename MT > // Type of the right-hand side dense matrix
4116 inline void DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,false>& rhs )
4117 {
4118  const size_t block( 16UL );
4119 
4120  for( size_t jj=0UL; jj<n_; jj+=block ) {
4121  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4122  for( size_t ii=0UL; ii<m_; ii+=block ) {
4123  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4124  for( size_t j=jj; j<jend; ++j ) {
4125  for( size_t i=ii; i<iend; ++i ) {
4126  v_[i+j*mm_] -= (~rhs)(i,j);
4127  }
4128  }
4129  }
4130  }
4131 }
4133 //*************************************************************************************************
4134 
4135 
4136 //*************************************************************************************************
4148 template< typename Type > // Data type of the matrix
4149 template< typename MT > // Type of the right-hand side sparse matrix
4150 inline void DynamicMatrix<Type,true>::subAssign( const SparseMatrix<MT,true>& rhs )
4151 {
4152  for( size_t j=0UL; j<(~rhs).columns(); ++j )
4153  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4154  v_[element->index()+j*mm_] -= element->value();
4155 }
4157 //*************************************************************************************************
4158 
4159 
4160 //*************************************************************************************************
4172 template< typename Type > // Data type of the matrix
4173 template< typename MT > // Type of the right-hand side sparse matrix
4174 inline void DynamicMatrix<Type,true>::subAssign( const SparseMatrix<MT,false>& rhs )
4175 {
4176  for( size_t i=0UL; i<(~rhs).rows(); ++i )
4177  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4178  v_[i+element->index()*mm_] -= element->value();
4179 }
4181 //*************************************************************************************************
4182 
4183 
4184 
4185 
4186 
4187 
4188 
4189 
4190 //=================================================================================================
4191 //
4192 // DYNAMICMATRIX OPERATORS
4193 //
4194 //=================================================================================================
4195 
4196 //*************************************************************************************************
4199 template< typename Type, bool SO >
4200 inline bool isnan( const DynamicMatrix<Type,SO>& m );
4201 
4202 template< typename Type, bool SO >
4203 inline void reset( DynamicMatrix<Type,SO>& m );
4204 
4205 template< typename Type, bool SO >
4206 inline void clear( DynamicMatrix<Type,SO>& m );
4207 
4208 template< typename Type, bool SO >
4209 inline bool isDefault( const DynamicMatrix<Type,SO>& m );
4210 
4211 template< typename Type, bool SO >
4212 inline const DynamicMatrix<Type,SO> inv( const DynamicMatrix<Type,SO>& m );
4213 
4214 template< typename Type, bool SO >
4215 inline void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) /* throw() */;
4217 //*************************************************************************************************
4218 
4219 
4220 //*************************************************************************************************
4227 template< typename Type // Data type of the matrix
4228  , bool SO > // Storage order
4229 inline bool isnan( const DynamicMatrix<Type,SO>& m )
4230 {
4231  for( size_t i=0UL; i<m.rows(); ++i ) {
4232  for( size_t j=0UL; j<m.columns(); ++j )
4233  if( isnan( m(i,j) ) ) return true;
4234  }
4235  return false;
4236 }
4237 //*************************************************************************************************
4238 
4239 
4240 //*************************************************************************************************
4247 template< typename Type // Data type of the matrix
4248  , bool SO > // Storage order
4250 {
4251  m.reset();
4252 }
4253 //*************************************************************************************************
4254 
4255 
4256 //*************************************************************************************************
4263 template< typename Type // Data type of the matrix
4264  , bool SO > // Storage order
4266 {
4267  m.clear();
4268 }
4269 //*************************************************************************************************
4270 
4271 
4272 //*************************************************************************************************
4290 template< typename Type // Data type of the matrix
4291  , bool SO > // Storage order
4292 inline bool isDefault( const DynamicMatrix<Type,SO>& m )
4293 {
4294  if( SO == rowMajor ) {
4295  for( size_t i=0UL; i<m.rows(); ++i )
4296  for( size_t j=0UL; j<m.columns(); ++j )
4297  if( !isDefault( m(i,j) ) ) return false;
4298  }
4299  else {
4300  for( size_t j=0UL; j<m.columns(); ++j )
4301  for( size_t i=0UL; i<m.rows(); ++i )
4302  if( !isDefault( m(i,j) ) ) return false;
4303  }
4304 
4305  return true;
4306 }
4307 //*************************************************************************************************
4308 
4309 
4310 //*************************************************************************************************
4328 template< typename Type // Data type of the matrix
4329  , bool SO > // Storage order
4331 {
4333  UNUSED_PARAMETER( m );
4334 
4335  return DynamicMatrix<Type,SO>();
4336 }
4337 //*************************************************************************************************
4338 
4339 
4340 //*************************************************************************************************
4349 template< typename Type // Data type of the matrix
4350  , bool SO > // Storage order
4351 inline void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) /* throw() */
4352 {
4353  a.swap( b );
4354 }
4355 //*************************************************************************************************
4356 
4357 
4358 
4359 
4360 //=================================================================================================
4361 //
4362 // ISRESIZABLE SPECIALIZATIONS
4363 //
4364 //=================================================================================================
4365 
4366 //*************************************************************************************************
4368 template< typename T, bool SO >
4369 struct IsResizable< DynamicMatrix<T,SO> > : public TrueType
4370 {
4371  enum { value = 1 };
4372  typedef TrueType Type;
4373 };
4374 
4375 template< typename T, bool SO >
4376 struct IsResizable< const DynamicMatrix<T,SO> > : public TrueType
4377 {
4378  enum { value = 1 };
4379  typedef TrueType Type;
4380 };
4381 
4382 template< typename T, bool SO >
4383 struct IsResizable< volatile DynamicMatrix<T,SO> > : public TrueType
4384 {
4385  enum { value = 1 };
4386  typedef TrueType Type;
4387 };
4388 
4389 template< typename T, bool SO >
4390 struct IsResizable< const volatile DynamicMatrix<T,SO> > : public TrueType
4391 {
4392  enum { value = 1 };
4393  typedef TrueType Type;
4394 };
4396 //*************************************************************************************************
4397 
4398 
4399 
4400 
4401 //=================================================================================================
4402 //
4403 // ADDTRAIT SPECIALIZATIONS
4404 //
4405 //=================================================================================================
4406 
4407 //*************************************************************************************************
4409 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4410 struct AddTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4411 {
4412  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4413 };
4414 
4415 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4416 struct AddTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4417 {
4418  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4419 };
4420 
4421 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4422 struct AddTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
4423 {
4424  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4425 };
4426 
4427 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4428 struct AddTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
4429 {
4430  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4431 };
4432 
4433 template< typename T1, bool SO, typename T2 >
4434 struct AddTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4435 {
4436  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4437 };
4438 
4439 template< typename T1, bool SO1, typename T2, bool SO2 >
4440 struct AddTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4441 {
4442  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4443 };
4445 //*************************************************************************************************
4446 
4447 
4448 
4449 
4450 //=================================================================================================
4451 //
4452 // SUBTRAIT SPECIALIZATIONS
4453 //
4454 //=================================================================================================
4455 
4456 //*************************************************************************************************
4458 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4459 struct SubTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4460 {
4461  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4462 };
4463 
4464 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4465 struct SubTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4466 {
4467  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4468 };
4469 
4470 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4471 struct SubTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
4472 {
4473  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4474 };
4475 
4476 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4477 struct SubTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
4478 {
4479  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4480 };
4481 
4482 template< typename T1, bool SO, typename T2 >
4483 struct SubTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4484 {
4485  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4486 };
4487 
4488 template< typename T1, bool SO1, typename T2, bool SO2 >
4489 struct SubTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4490 {
4491  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4492 };
4494 //*************************************************************************************************
4495 
4496 
4497 
4498 
4499 //=================================================================================================
4500 //
4501 // MULTTRAIT SPECIALIZATIONS
4502 //
4503 //=================================================================================================
4504 
4505 //*************************************************************************************************
4507 template< typename T1, bool SO, typename T2 >
4508 struct MultTrait< DynamicMatrix<T1,SO>, T2 >
4509 {
4510  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4512 };
4513 
4514 template< typename T1, typename T2, bool SO >
4515 struct MultTrait< T1, DynamicMatrix<T2,SO> >
4516 {
4517  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4519 };
4520 
4521 template< typename T1, bool SO, typename T2, size_t N >
4522 struct MultTrait< DynamicMatrix<T1,SO>, StaticVector<T2,N,false> >
4523 {
4524  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4525 };
4526 
4527 template< typename T1, size_t N, typename T2, bool SO >
4528 struct MultTrait< StaticVector<T1,N,true>, DynamicMatrix<T2,SO> >
4529 {
4530  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4531 };
4532 
4533 template< typename T1, bool SO, typename T2 >
4534 struct MultTrait< DynamicMatrix<T1,SO>, DynamicVector<T2,false> >
4535 {
4536  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4537 };
4538 
4539 template< typename T1, typename T2, bool SO >
4540 struct MultTrait< DynamicVector<T1,true>, DynamicMatrix<T2,SO> >
4541 {
4542  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4543 };
4544 
4545 template< typename T1, bool SO, typename T2 >
4546 struct MultTrait< DynamicMatrix<T1,SO>, CompressedVector<T2,false> >
4547 {
4548  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4549 };
4550 
4551 template< typename T1, typename T2, bool SO >
4552 struct MultTrait< CompressedVector<T1,true>, DynamicMatrix<T2,SO> >
4553 {
4554  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4555 };
4556 
4557 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4558 struct MultTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4559 {
4560  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4561 };
4562 
4563 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4564 struct MultTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
4565 {
4566  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4567 };
4568 
4569 template< typename T1, bool SO1, typename T2, bool SO2 >
4570 struct MultTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4571 {
4572  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4573 };
4575 //*************************************************************************************************
4576 
4577 
4578 
4579 
4580 //=================================================================================================
4581 //
4582 // DIVTRAIT SPECIALIZATIONS
4583 //
4584 //=================================================================================================
4585 
4586 //*************************************************************************************************
4588 template< typename T1, bool SO, typename T2 >
4589 struct DivTrait< DynamicMatrix<T1,SO>, T2 >
4590 {
4591  typedef DynamicMatrix< typename DivTrait<T1,T2>::Type , SO > Type;
4593 };
4595 //*************************************************************************************************
4596 
4597 
4598 
4599 
4600 //=================================================================================================
4601 //
4602 // MATHTRAIT SPECIALIZATIONS
4603 //
4604 //=================================================================================================
4605 
4606 //*************************************************************************************************
4608 template< typename T1, bool SO, typename T2 >
4609 struct MathTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4610 {
4611  typedef DynamicMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
4612  typedef DynamicMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
4613 };
4615 //*************************************************************************************************
4616 
4617 
4618 
4619 
4620 //=================================================================================================
4621 //
4622 // ROWTRAIT SPECIALIZATIONS
4623 //
4624 //=================================================================================================
4625 
4626 //*************************************************************************************************
4628 template< typename T1, bool SO >
4629 struct RowTrait< DynamicMatrix<T1,SO> >
4630 {
4631  typedef DynamicVector<T1,true> Type;
4632 };
4634 //*************************************************************************************************
4635 
4636 
4637 
4638 
4639 //=================================================================================================
4640 //
4641 // COLUMNTRAIT SPECIALIZATIONS
4642 //
4643 //=================================================================================================
4644 
4645 //*************************************************************************************************
4647 template< typename T1, bool SO >
4648 struct ColumnTrait< DynamicMatrix<T1,SO> >
4649 {
4650  typedef DynamicVector<T1,false> Type;
4651 };
4653 //*************************************************************************************************
4654 
4655 } // namespace blaze
4656 
4657 #endif