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>
70 #include <blaze/util/Unused.h>
71 
72 
73 namespace blaze {
74 
75 //=================================================================================================
76 //
77 // CLASS DEFINITION
78 //
79 //=================================================================================================
80 
81 //*************************************************************************************************
160 template< typename Type // Data type of the matrix
161  , bool SO = defaultStorageOrder > // Storage order
162 class DynamicMatrix : public DenseMatrix< DynamicMatrix<Type,SO>, SO >
163 {
164  private:
165  //**Type definitions****************************************************************************
167  //**********************************************************************************************
168 
169  public:
170  //**Type definitions****************************************************************************
172  typedef This ResultType;
175  typedef Type ElementType;
176  typedef const Type& ReturnType;
177  typedef typename IT::Type IntrinsicType;
178  typedef const This& CompositeType;
179  typedef Type& Reference;
180  typedef const Type& ConstReference;
181  typedef Type* Iterator;
182  typedef const Type* ConstIterator;
183  //**********************************************************************************************
184 
185  //**Compilation flags***************************************************************************
187 
191  enum { vectorizable = IsVectorizable<Type>::value };
192  //**********************************************************************************************
193 
194  //**Constructors********************************************************************************
197  explicit inline DynamicMatrix();
198  explicit inline DynamicMatrix( size_t m, size_t n );
199  explicit inline DynamicMatrix( size_t m, size_t n, Type init );
200  inline DynamicMatrix( const DynamicMatrix& m );
201  template< typename MT, bool SO2 > inline DynamicMatrix( const Matrix<MT,SO2>& m );
202 
203  template< typename Other, size_t M, size_t N >
204  inline DynamicMatrix( const Other (&rhs)[M][N] );
206  //**********************************************************************************************
207 
208  //**Destructor**********************************************************************************
211  inline ~DynamicMatrix();
213  //**********************************************************************************************
214 
215  //**Data access functions***********************************************************************
218  inline Reference operator()( size_t i, size_t j );
219  inline ConstReference operator()( size_t i, size_t j ) const;
220  inline Type* data ();
221  inline const Type* data () const;
222  inline Type* data ( size_t i );
223  inline const Type* data ( size_t i ) const;
224  inline Iterator begin ( size_t i );
225  inline ConstIterator begin ( size_t i ) const;
226  inline ConstIterator cbegin( size_t i ) const;
227  inline Iterator end ( size_t i );
228  inline ConstIterator end ( size_t i ) const;
229  inline ConstIterator cend ( size_t i ) const;
231  //**********************************************************************************************
232 
233  //**Assignment operators************************************************************************
236  template< typename Other, size_t M, size_t N >
237  inline DynamicMatrix& operator=( const Other (&rhs)[M][N] );
238 
239  inline DynamicMatrix& operator= ( Type set );
240  inline DynamicMatrix& operator= ( const DynamicMatrix& set );
241  template< typename MT, bool SO2 > inline DynamicMatrix& operator= ( const Matrix<MT,SO2>& rhs );
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 
246  template< typename Other >
247  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
248  operator*=( Other rhs );
249 
250  template< typename Other >
251  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
252  operator/=( Other rhs );
254  //**********************************************************************************************
255 
256  //**Utility functions***************************************************************************
259  inline size_t rows() const;
260  inline size_t columns() const;
261  inline size_t spacing() const;
262  inline size_t capacity() const;
263  inline size_t capacity( size_t i ) const;
264  inline size_t nonZeros() const;
265  inline size_t nonZeros( size_t i ) const;
266  inline void reset();
267  inline void reset( size_t i );
268  inline void clear();
269  void resize ( size_t m, size_t n, bool preserve=true );
270  inline void extend ( size_t m, size_t n, bool preserve=true );
271  inline void reserve( size_t elements );
272  inline DynamicMatrix& transpose();
273  inline bool isDiagonal() const;
274  inline bool isSymmetric() const;
275  template< typename Other > inline DynamicMatrix& scale( Other scalar );
276  inline void swap( DynamicMatrix& m ) /* throw() */;
278  //**********************************************************************************************
279 
280  private:
281  //**********************************************************************************************
283 
284  template< typename MT >
285  struct VectorizedAssign {
286  enum { value = vectorizable && MT::vectorizable &&
288  };
290  //**********************************************************************************************
291 
292  //**********************************************************************************************
294 
295  template< typename MT >
296  struct VectorizedAddAssign {
297  enum { value = vectorizable && MT::vectorizable &&
298  IsSame<Type,typename MT::ElementType>::value &&
299  IntrinsicTrait<Type>::addition };
300  };
302  //**********************************************************************************************
303 
304  //**********************************************************************************************
306 
307  template< typename MT >
308  struct VectorizedSubAssign {
309  enum { value = vectorizable && MT::vectorizable &&
310  IsSame<Type,typename MT::ElementType>::value &&
311  IntrinsicTrait<Type>::subtraction };
312  };
314  //**********************************************************************************************
315 
316  public:
317  //**Expression template evaluation functions****************************************************
320  template< typename Other > inline bool canAlias ( const Other* alias ) const;
321  template< typename Other > inline bool isAliased( const Other* alias ) const;
322  inline IntrinsicType get ( size_t i, size_t j ) const;
323 
324  template< typename MT >
325  inline typename DisableIf< VectorizedAssign<MT> >::Type
326  assign( const DenseMatrix<MT,SO>& rhs );
327 
328  template< typename MT >
329  inline typename EnableIf< VectorizedAssign<MT> >::Type
330  assign( const DenseMatrix<MT,SO>& rhs );
331 
332  template< typename MT > inline void assign( const DenseMatrix<MT,!SO>& rhs );
333  template< typename MT > inline void assign( const SparseMatrix<MT,SO>& rhs );
334  template< typename MT > inline void assign( const SparseMatrix<MT,!SO>& rhs );
335 
336  template< typename MT >
337  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
338  addAssign( const DenseMatrix<MT,SO>& rhs );
339 
340  template< typename MT >
341  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
342  addAssign( const DenseMatrix<MT,SO>& rhs );
343 
344  template< typename MT > inline void addAssign( const DenseMatrix<MT,!SO>& rhs );
345  template< typename MT > inline void addAssign( const SparseMatrix<MT,SO>& rhs );
346  template< typename MT > inline void addAssign( const SparseMatrix<MT,!SO>& rhs );
347 
348  template< typename MT >
349  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
350  subAssign( const DenseMatrix<MT,SO>& rhs );
351 
352  template< typename MT >
353  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
354  subAssign( const DenseMatrix<MT,SO>& rhs );
355 
356  template< typename MT > inline void subAssign( const DenseMatrix<MT,!SO>& rhs );
357  template< typename MT > inline void subAssign( const SparseMatrix<MT,SO>& rhs );
358  template< typename MT > inline void subAssign( const SparseMatrix<MT,!SO>& rhs );
360  //**********************************************************************************************
361 
362  private:
363  //**Utility functions***************************************************************************
366  inline size_t adjustColumns( size_t minColumns ) const;
368  //**********************************************************************************************
369 
370  //**Member variables****************************************************************************
373  size_t m_;
374  size_t n_;
375  size_t nn_;
376  size_t capacity_;
378 
388  //**********************************************************************************************
389 
390  //**Compile time checks*************************************************************************
397  //**********************************************************************************************
398 };
399 //*************************************************************************************************
400 
401 
402 
403 
404 //=================================================================================================
405 //
406 // CONSTRUCTORS
407 //
408 //=================================================================================================
409 
410 //*************************************************************************************************
413 template< typename Type // Data type of the matrix
414  , bool SO > // Storage order
416  : m_ ( 0UL ) // The current number of rows of the matrix
417  , n_ ( 0UL ) // The current number of columns of the matrix
418  , nn_ ( 0UL ) // The alignment adjusted number of columns
419  , capacity_( 0UL ) // The maximum capacity of the matrix
420  , v_ ( NULL ) // The matrix elements
421 {}
422 //*************************************************************************************************
423 
424 
425 //*************************************************************************************************
434 template< typename Type // Data type of the matrix
435  , bool SO > // Storage order
436 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n )
437  : m_ ( m ) // The current number of rows of the matrix
438  , n_ ( n ) // The current number of columns of the matrix
439  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
440  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
441  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
442 {
443  if( IsNumeric<Type>::value ) {
444  for( size_t i=0UL; i<m_; ++i ) {
445  for( size_t j=n_; j<nn_; ++j )
446  v_[i*nn_+j] = Type();
447  }
448  }
449 }
450 //*************************************************************************************************
451 
452 
453 //*************************************************************************************************
462 template< typename Type // Data type of the matrix
463  , bool SO > // Storage order
464 inline DynamicMatrix<Type,SO>::DynamicMatrix( size_t m, size_t n, Type init )
465  : m_ ( m ) // The current number of rows of the matrix
466  , n_ ( n ) // The current number of columns of the matrix
467  , nn_ ( adjustColumns( n ) ) // The alignment adjusted number of columns
468  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
469  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
470 {
471  for( size_t i=0UL; i<m; ++i ) {
472  for( size_t j=0UL; j<n_; ++j )
473  v_[i*nn_+j] = init;
474 
475  if( IsNumeric<Type>::value ) {
476  for( size_t j=n_; j<nn_; ++j )
477  v_[i*nn_+j] = Type();
478  }
479  }
480 }
481 //*************************************************************************************************
482 
483 
484 //*************************************************************************************************
492 template< typename Type // Data type of the matrix
493  , bool SO > // Storage order
495  : m_ ( m.m_ ) // The current number of rows of the matrix
496  , n_ ( m.n_ ) // The current number of columns of the matrix
497  , nn_ ( m.nn_ ) // The alignment adjusted number of columns
498  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
499  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
500 {
501  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
502 
503  for( size_t i=0UL; i<capacity_; ++i )
504  v_[i] = m.v_[i];
505 }
506 //*************************************************************************************************
507 
508 
509 //*************************************************************************************************
514 template< typename Type // Data type of the matrix
515  , bool SO > // Storage order
516 template< typename MT // Type of the foreign matrix
517  , bool SO2 > // Storage order of the foreign matrix
519  : m_ ( (~m).rows() ) // The current number of rows of the matrix
520  , n_ ( (~m).columns() ) // The current number of columns of the matrix
521  , nn_ ( adjustColumns( n_ ) ) // The alignment adjusted number of columns
522  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
523  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
524 {
525  using blaze::assign;
526 
527  if( IsNumeric<Type>::value ) {
528  for( size_t i=0UL; i<m_; ++i ) {
529  for( size_t j=( IsSparseMatrix<MT>::value )?( 0UL ):( n_ ); j<nn_; ++j )
530  v_[i*nn_+j] = Type();
531  }
532  }
533 
534  assign( *this, ~m );
535 }
536 //*************************************************************************************************
537 
538 
539 //*************************************************************************************************
557 template< typename Type // Data type of the matrix
558  , bool SO > // Storage order
559 template< typename Other // Data type of the initialization array
560  , size_t M // Number of rows of the initialization array
561  , size_t N > // Number of columns of the initialization array
562 inline DynamicMatrix<Type,SO>::DynamicMatrix( const Other (&rhs)[M][N] )
563  : m_ ( M ) // The current number of rows of the matrix
564  , n_ ( N ) // The current number of columns of the matrix
565  , nn_ ( adjustColumns( N ) ) // The alignment adjusted number of columns
566  , capacity_( m_*nn_ ) // The maximum capacity of the matrix
567  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
568 {
569  for( size_t i=0UL; i<M; ++i ) {
570  for( size_t j=0UL; j<N; ++j )
571  v_[i*nn_+j] = rhs[i][j];
572 
573  if( IsNumeric<Type>::value ) {
574  for( size_t j=N; j<nn_; ++j )
575  v_[i*nn_+j] = Type();
576  }
577  }
578 }
579 //*************************************************************************************************
580 
581 
582 
583 
584 //=================================================================================================
585 //
586 // DESTRUCTOR
587 //
588 //=================================================================================================
589 
590 //*************************************************************************************************
593 template< typename Type // Data type of the matrix
594  , bool SO > // Storage order
596 {
597  deallocate( v_ );
598 }
599 //*************************************************************************************************
600 
601 
602 
603 
604 //=================================================================================================
605 //
606 // DATA ACCESS FUNCTIONS
607 //
608 //=================================================================================================
609 
610 //*************************************************************************************************
617 template< typename Type // Data type of the matrix
618  , bool SO > // Storage order
619 inline typename DynamicMatrix<Type,SO>::Reference
621 {
622  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
623  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
624  return v_[i*nn_+j];
625 }
626 //*************************************************************************************************
627 
628 
629 //*************************************************************************************************
636 template< typename Type // Data type of the matrix
637  , bool SO > // Storage order
639  DynamicMatrix<Type,SO>::operator()( size_t i, size_t j ) const
640 {
641  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
642  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
643  return v_[i*nn_+j];
644 }
645 //*************************************************************************************************
646 
647 
648 //*************************************************************************************************
653 template< typename Type // Data type of the matrix
654  , bool SO > // Storage order
656 {
657  return v_;
658 }
659 //*************************************************************************************************
660 
661 
662 //*************************************************************************************************
667 template< typename Type // Data type of the matrix
668  , bool SO > // Storage order
669 inline const Type* DynamicMatrix<Type,SO>::data() const
670 {
671  return v_;
672 }
673 //*************************************************************************************************
674 
675 
676 //*************************************************************************************************
682 template< typename Type // Data type of the matrix
683  , bool SO > // Storage order
684 inline Type* DynamicMatrix<Type,SO>::data( size_t i )
685 {
686  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
687  return v_ + i*nn_;
688 }
689 //*************************************************************************************************
690 
691 
692 //*************************************************************************************************
698 template< typename Type // Data type of the matrix
699  , bool SO > // Storage order
700 inline const Type* DynamicMatrix<Type,SO>::data( size_t i ) const
701 {
702  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
703  return v_ + i*nn_;
704 }
705 //*************************************************************************************************
706 
707 
708 //*************************************************************************************************
719 template< typename Type // Data type of the matrix
720  , bool SO > // Storage order
721 inline typename DynamicMatrix<Type,SO>::Iterator
723 {
724  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
725  return v_ + i*nn_;
726 }
727 //*************************************************************************************************
728 
729 
730 //*************************************************************************************************
741 template< typename Type // Data type of the matrix
742  , bool SO > // Storage order
745 {
746  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
747  return v_ + i*nn_;
748 }
749 //*************************************************************************************************
750 
751 
752 //*************************************************************************************************
763 template< typename Type // Data type of the matrix
764  , bool SO > // Storage order
767 {
768  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
769  return v_ + i*nn_;
770 }
771 //*************************************************************************************************
772 
773 
774 //*************************************************************************************************
785 template< typename Type // Data type of the matrix
786  , bool SO > // Storage order
787 inline typename DynamicMatrix<Type,SO>::Iterator
789 {
790  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
791  return v_ + i*nn_ + n_;
792 }
793 //*************************************************************************************************
794 
795 
796 //*************************************************************************************************
807 template< typename Type // Data type of the matrix
808  , bool SO > // Storage order
810  DynamicMatrix<Type,SO>::end( size_t i ) const
811 {
812  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
813  return v_ + i*nn_ + n_;
814 }
815 //*************************************************************************************************
816 
817 
818 //*************************************************************************************************
829 template< typename Type // Data type of the matrix
830  , bool SO > // Storage order
833 {
834  BLAZE_USER_ASSERT( i < m_, "Invalid dense matrix row access index" );
835  return v_ + i*nn_ + n_;
836 }
837 //*************************************************************************************************
838 
839 
840 
841 
842 //=================================================================================================
843 //
844 // ASSIGNMENT OPERATORS
845 //
846 //=================================================================================================
847 
848 //*************************************************************************************************
867 template< typename Type // Data type of the matrix
868  , bool SO > // Storage order
869 template< typename Other // Data type of the initialization array
870  , size_t M // Number of rows of the initialization array
871  , size_t N > // Number of columns of the initialization array
873 {
874  resize( M, N, false );
875 
876  for( size_t i=0UL; i<M; ++i )
877  for( size_t j=0UL; j<N; ++j )
878  v_[i*nn_+j] = rhs[i][j];
879 
880  return *this;
881 }
882 //*************************************************************************************************
883 
884 
885 //*************************************************************************************************
891 template< typename Type // Data type of the matrix
892  , bool SO > // Storage order
894 {
895  for( size_t i=0UL; i<m_; ++i )
896  for( size_t j=0UL; j<n_; ++j )
897  v_[i*nn_+j] = rhs;
898 
899  return *this;
900 }
901 //*************************************************************************************************
902 
903 
904 //*************************************************************************************************
913 template< typename Type // Data type of the matrix
914  , bool SO > // Storage order
916 {
917  if( &rhs == this ) return *this;
918 
919  resize( rhs.m_, rhs.n_, false );
920 
921  for( size_t i=0UL; i<m_; ++i )
922  for( size_t j=0UL; j<n_; ++j )
923  v_[i*nn_+j] = rhs(i,j);
924 
925  return *this;
926 }
927 //*************************************************************************************************
928 
929 
930 //*************************************************************************************************
939 template< typename Type // Data type of the matrix
940  , bool SO > // Storage order
941 template< typename MT // Type of the right-hand side matrix
942  , bool SO2 > // Storage order of the right-hand side matrix
944 {
945  using blaze::assign;
946 
947  if( (~rhs).canAlias( this ) ) {
948  DynamicMatrix tmp( ~rhs );
949  swap( tmp );
950  }
951  else {
952  resize( (~rhs).rows(), (~rhs).columns(), false );
954  reset();
955  assign( *this, ~rhs );
956  }
957 
958  return *this;
959 }
960 //*************************************************************************************************
961 
962 
963 //*************************************************************************************************
973 template< typename Type // Data type of the matrix
974  , bool SO > // Storage order
975 template< typename MT // Type of the right-hand side matrix
976  , bool SO2 > // Storage order of the right-hand side matrix
978 {
979  using blaze::addAssign;
980 
981  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
982  throw std::invalid_argument( "Matrix sizes do not match" );
983 
984  if( (~rhs).canAlias( this ) ) {
985  typename MT::ResultType tmp( ~rhs );
986  addAssign( *this, tmp );
987  }
988  else {
989  addAssign( *this, ~rhs );
990  }
991 
992  return *this;
993 }
994 //*************************************************************************************************
995 
996 
997 //*************************************************************************************************
1007 template< typename Type // Data type of the matrix
1008  , bool SO > // Storage order
1009 template< typename MT // Type of the right-hand side matrix
1010  , bool SO2 > // Storage order of the right-hand side matrix
1012 {
1013  using blaze::subAssign;
1014 
1015  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
1016  throw std::invalid_argument( "Matrix sizes do not match" );
1017 
1018  if( (~rhs).canAlias( this ) ) {
1019  typename MT::ResultType tmp( ~rhs );
1020  subAssign( *this, tmp );
1021  }
1022  else {
1023  subAssign( *this, ~rhs );
1024  }
1025 
1026  return *this;
1027 }
1028 //*************************************************************************************************
1029 
1030 
1031 //*************************************************************************************************
1041 template< typename Type // Data type of the matrix
1042  , bool SO > // Storage order
1043 template< typename MT // Type of the right-hand side matrix
1044  , bool SO2 > // Storage order of the right-hand side matrix
1046 {
1047  if( (~rhs).rows() != n_ )
1048  throw std::invalid_argument( "Matrix sizes do not match" );
1049 
1050  DynamicMatrix tmp( *this * (~rhs) );
1051  swap( tmp );
1052 
1053  return *this;
1054 }
1055 //*************************************************************************************************
1056 
1057 
1058 //*************************************************************************************************
1065 template< typename Type // Data type of the matrix
1066  , bool SO > // Storage order
1067 template< typename Other > // Data type of the right-hand side scalar
1068 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,SO> >::Type&
1070 {
1071  return operator=( (*this) * rhs );
1072 }
1073 //*************************************************************************************************
1074 
1075 
1076 //*************************************************************************************************
1083 template< typename Type // Data type of the matrix
1084  , bool SO > // Storage order
1085 template< typename Other > // Data type of the right-hand side scalar
1086 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,SO> >::Type&
1088 {
1089  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1090 
1091  return operator=( (*this) / rhs );
1092 }
1093 //*************************************************************************************************
1094 
1095 
1096 
1097 
1098 //=================================================================================================
1099 //
1100 // UTILITY FUNCTIONS
1101 //
1102 //=================================================================================================
1103 
1104 //*************************************************************************************************
1109 template< typename Type // Data type of the matrix
1110  , bool SO > // Storage order
1111 inline size_t DynamicMatrix<Type,SO>::rows() const
1112 {
1113  return m_;
1114 }
1115 //*************************************************************************************************
1116 
1117 
1118 //*************************************************************************************************
1123 template< typename Type // Data type of the matrix
1124  , bool SO > // Storage order
1125 inline size_t DynamicMatrix<Type,SO>::columns() const
1126 {
1127  return n_;
1128 }
1129 //*************************************************************************************************
1130 
1131 
1132 //*************************************************************************************************
1140 template< typename Type // Data type of the matrix
1141  , bool SO > // Storage order
1142 inline size_t DynamicMatrix<Type,SO>::spacing() const
1143 {
1144  return nn_;
1145 }
1146 //*************************************************************************************************
1147 
1148 
1149 //*************************************************************************************************
1154 template< typename Type // Data type of the matrix
1155  , bool SO > // Storage order
1157 {
1158  return capacity_;
1159 }
1160 //*************************************************************************************************
1161 
1162 
1163 //*************************************************************************************************
1174 template< typename Type // Data type of the sparse matrix
1175  , bool SO > // Storage order
1176 inline size_t DynamicMatrix<Type,SO>::capacity( size_t i ) const
1177 {
1178  UNUSED_PARAMETER( i );
1179  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1180  return nn_;
1181 }
1182 //*************************************************************************************************
1183 
1184 
1185 //*************************************************************************************************
1190 template< typename Type // Data type of the matrix
1191  , bool SO > // Storage order
1193 {
1194  size_t nonzeros( 0UL );
1195 
1196  for( size_t i=0UL; i<m_; ++i )
1197  for( size_t j=0UL; j<n_; ++j )
1198  if( !isDefault( v_[i*nn_+j] ) )
1199  ++nonzeros;
1200 
1201  return nonzeros;
1202 }
1203 //*************************************************************************************************
1204 
1205 
1206 //*************************************************************************************************
1212 template< typename Type // Data type of the matrix
1213  , bool SO > // Storage order
1214 inline size_t DynamicMatrix<Type,SO>::nonZeros( size_t i ) const
1215 {
1216  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1217 
1218  const size_t jend( (i+1UL)*nn_ );
1219  size_t nonzeros( 0UL );
1220 
1221  for( size_t j=i*nn_; j<jend; ++j )
1222  if( !isDefault( v_[j] ) )
1223  ++nonzeros;
1224 
1225  return nonzeros;
1226 }
1227 //*************************************************************************************************
1228 
1229 
1230 //*************************************************************************************************
1235 template< typename Type // Data type of the matrix
1236  , bool SO > // Storage order
1238 {
1239  using blaze::reset;
1240 
1241  for( size_t i=0UL; i<m_; ++i )
1242  for( size_t j=0UL; j<n_; ++j )
1243  reset( v_[i*nn_+j] );
1244 }
1245 //*************************************************************************************************
1246 
1247 
1248 //*************************************************************************************************
1259 template< typename Type // Data type of the sparse matrix
1260  , bool SO > // Storage order
1261 inline void DynamicMatrix<Type,SO>::reset( size_t i )
1262 {
1263  using blaze::reset;
1264 
1265  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1266  for( size_t j=0UL; j<n_; ++j )
1267  reset( v_[i*nn_+j] );
1268 }
1269 //*************************************************************************************************
1270 
1271 
1272 //*************************************************************************************************
1279 template< typename Type // Data type of the matrix
1280  , bool SO > // Storage order
1282 {
1283  m_ = 0UL;
1284  n_ = 0UL;
1285  nn_ = 0UL;
1286 }
1287 //*************************************************************************************************
1288 
1289 
1290 //*************************************************************************************************
1323 template< typename Type // Data type of the matrix
1324  , bool SO > // Storage order
1325 void DynamicMatrix<Type,SO>::resize( size_t m, size_t n, bool preserve )
1326 {
1327  using blaze::min;
1328 
1329  if( m == m_ && n == n_ ) return;
1330 
1331  const size_t nn( adjustColumns( n ) );
1332 
1333  if( preserve )
1334  {
1335  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1336  const size_t min_m( min( m, m_ ) );
1337  const size_t min_n( min( n, n_ ) );
1338 
1339  for( size_t i=0UL; i<min_m; ++i )
1340  for( size_t j=0UL; j<min_n; ++j )
1341  v[i*nn+j] = v_[i*nn_+j];
1342 
1343  if( IsNumeric<Type>::value ) {
1344  for( size_t i=0UL; i<m; ++i )
1345  for( size_t j=n; j<nn; ++j )
1346  v[i*nn+j] = Type();
1347  }
1348 
1349  std::swap( v_, v );
1350  deallocate( v );
1351  capacity_ = m*nn;
1352  }
1353  else if( m*nn > capacity_ ) {
1354  Type* BLAZE_RESTRICT v = allocate<Type>( m*nn );
1355 
1356  if( IsNumeric<Type>::value ) {
1357  for( size_t i=0UL; i<m; ++i )
1358  for( size_t j=n; j<nn; ++j )
1359  v[i*nn+j] = Type();
1360  }
1361 
1362  std::swap( v_, v );
1363  deallocate( v );
1364  capacity_ = m*nn;
1365  }
1366 
1367  m_ = m;
1368  n_ = n;
1369  nn_ = nn;
1370 }
1371 //*************************************************************************************************
1372 
1373 
1374 //*************************************************************************************************
1388 template< typename Type // Data type of the matrix
1389  , bool SO > // Storage order
1390 inline void DynamicMatrix<Type,SO>::extend( size_t m, size_t n, bool preserve )
1391 {
1392  resize( m_+m, n_+n, preserve );
1393 }
1394 //*************************************************************************************************
1395 
1396 
1397 //*************************************************************************************************
1406 template< typename Type // Data type of the matrix
1407  , bool SO > // Storage order
1408 inline void DynamicMatrix<Type,SO>::reserve( size_t elements )
1409 {
1410  if( elements > capacity_ )
1411  {
1412  // Allocating a new array
1413  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
1414 
1415  // Initializing the new array
1416  std::copy( v_, v_+capacity_, tmp );
1417 
1418  if( IsNumeric<Type>::value ) {
1419  for( size_t i=capacity_; i<elements; ++i )
1420  tmp[i] = Type();
1421  }
1422 
1423  // Replacing the old array
1424  std::swap( tmp, v_ );
1425  deallocate( tmp );
1426  capacity_ = elements;
1427  }
1428 }
1429 //*************************************************************************************************
1430 
1431 
1432 //*************************************************************************************************
1437 template< typename Type // Data type of the matrix
1438  , bool SO > // Storage order
1440 {
1441  DynamicMatrix tmp( trans(*this) );
1442  swap( tmp );
1443  return *this;
1444 }
1445 //*************************************************************************************************
1446 
1447 
1448 //*************************************************************************************************
1465 template< typename Type // Data type of the matrix
1466  , bool SO > // Storage order
1468 {
1469  if( m_ != n_ ) return false;
1470 
1471  for( size_t i=1UL; i<m_; ++i ) {
1472  for( size_t j=0UL; j<i; ++j ) {
1473  if( !isDefault( v_[i*nn_+j] ) || !isDefault( v_[j*nn_+i] ) )
1474  return false;
1475  }
1476  }
1477 
1478  return true;
1479 }
1480 //*************************************************************************************************
1481 
1482 
1483 //*************************************************************************************************
1488 template< typename Type // Data type of the matrix
1489  , bool SO > // Storage order
1491 {
1492  if( m_ != n_ ) return false;
1493 
1494  for( size_t i=1UL; i<m_; ++i ) {
1495  for( size_t j=0UL; j<i; ++j ) {
1496  if( !equal( v_[i*nn_+j], v_[j*nn_+i] ) )
1497  return false;
1498  }
1499  }
1500 
1501  return true;
1502 }
1503 //*************************************************************************************************
1504 
1505 
1506 //*************************************************************************************************
1512 template< typename Type // Data type of the matrix
1513  , bool SO > // Storage order
1514 template< typename Other > // Data type of the scalar value
1516 {
1517  for( size_t i=0UL; i<m_; ++i )
1518  for( size_t j=0UL; j<n_; ++j )
1519  v_[i*nn_+j] *= scalar;
1520 
1521  return *this;
1522 }
1523 //*************************************************************************************************
1524 
1525 
1526 //*************************************************************************************************
1533 template< typename Type // Data type of the matrix
1534  , bool SO > // Storage order
1535 inline void DynamicMatrix<Type,SO>::swap( DynamicMatrix& m ) /* throw() */
1536 {
1537  std::swap( m_ , m.m_ );
1538  std::swap( n_ , m.n_ );
1539  std::swap( nn_, m.nn_ );
1540  std::swap( capacity_, m.capacity_ );
1541  std::swap( v_ , m.v_ );
1542 }
1543 //*************************************************************************************************
1544 
1545 
1546 //*************************************************************************************************
1552 template< typename Type // Data type of the matrix
1553  , bool SO > // Storage order
1554 inline size_t DynamicMatrix<Type,SO>::adjustColumns( size_t minColumns ) const
1555 {
1557  return minColumns + ( IT::size - ( minColumns % IT::size ) ) % IT::size;
1558  else return minColumns;
1559 }
1560 //*************************************************************************************************
1561 
1562 
1563 
1564 
1565 //=================================================================================================
1566 //
1567 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1568 //
1569 //=================================================================================================
1570 
1571 //*************************************************************************************************
1581 template< typename Type // Data type of the matrix
1582  , bool SO > // Storage order
1583 template< typename Other > // Data type of the foreign expression
1584 inline bool DynamicMatrix<Type,SO>::canAlias( const Other* alias ) const
1585 {
1586  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1587 }
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>::isAliased( const Other* alias ) const
1605 {
1606  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
1607 }
1608 //*************************************************************************************************
1609 
1610 
1611 //*************************************************************************************************
1623 template< typename Type // Data type of the matrix
1624  , bool SO > // Storage order
1626  DynamicMatrix<Type,SO>::get( size_t i, size_t j ) const
1627 {
1629 
1630  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
1631  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
1632  BLAZE_INTERNAL_ASSERT( j + IT::size <= nn_, "Invalid column access index" );
1633  BLAZE_INTERNAL_ASSERT( j % IT::size == 0UL, "Invalid column access index" );
1634 
1635  return load( &v_[i*nn_+j] );
1636 }
1637 //*************************************************************************************************
1638 
1639 
1640 //*************************************************************************************************
1651 template< typename Type // Data type of the matrix
1652  , bool SO > // Storage order
1653 template< typename MT > // Type of the right-hand side dense matrix
1654 inline typename DisableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
1656 {
1657  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1658  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1659 
1660  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == ( n_ & size_t(-2) ), "Invalid end calculation" );
1661  const size_t jend( n_ & size_t(-2) );
1662 
1663  for( size_t i=0UL; i<m_; ++i ) {
1664  for( size_t j=0UL; j<jend; j+=2UL ) {
1665  v_[i*nn_+j ] = (~rhs)(i,j );
1666  v_[i*nn_+j+1UL] = (~rhs)(i,j+1UL);
1667  }
1668  if( jend < n_ ) {
1669  v_[i*nn_+jend] = (~rhs)(i,jend);
1670  }
1671  }
1672 }
1673 //*************************************************************************************************
1674 
1675 
1676 //*************************************************************************************************
1687 template< typename Type // Data type of the matrix
1688  , bool SO > // Storage order
1689 template< typename MT > // Type of the right-hand side dense matrix
1690 inline typename EnableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
1692 {
1693  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1694  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1695 
1697 
1698  if( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
1699  {
1700  for( size_t i=0UL; i<m_; ++i )
1701  for( size_t j=0UL; j<n_; j+=IT::size )
1702  stream( &v_[i*nn_+j], (~rhs).get(i,j) );
1703  }
1704  else
1705  {
1706  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == ( n_ & size_t(-IT::size*4) ), "Invalid end calculation" );
1707  const size_t jend( n_ & size_t(-IT::size*4) );
1708 
1709  for( size_t i=0UL; i<m_; ++i ) {
1710  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1711  store( &v_[i*nn_+j ], (~rhs).get(i,j ) );
1712  store( &v_[i*nn_+j+IT::size ], (~rhs).get(i,j+IT::size ) );
1713  store( &v_[i*nn_+j+IT::size*2UL], (~rhs).get(i,j+IT::size*2UL) );
1714  store( &v_[i*nn_+j+IT::size*3UL], (~rhs).get(i,j+IT::size*3UL) );
1715  }
1716  for( size_t j=jend; j<n_; j+=IT::size ) {
1717  store( &v_[i*nn_+j], (~rhs).get(i,j) );
1718  }
1719  }
1720  }
1721 }
1722 //*************************************************************************************************
1723 
1724 
1725 //*************************************************************************************************
1736 template< typename Type // Data type of the matrix
1737  , bool SO > // Storage order
1738 template< typename MT > // Type of the right-hand side dense matrix
1740 {
1741  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1742  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1743 
1744  const size_t block( 16UL );
1745 
1746  for( size_t ii=0UL; ii<m_; ii+=block ) {
1747  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
1748  for( size_t jj=0UL; jj<n_; jj+=block ) {
1749  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
1750  for( size_t i=ii; i<iend; ++i ) {
1751  for( size_t j=jj; j<jend; ++j ) {
1752  v_[i*nn_+j] = (~rhs)(i,j);
1753  }
1754  }
1755  }
1756  }
1757 }
1758 //*************************************************************************************************
1759 
1760 
1761 //*************************************************************************************************
1772 template< typename Type // Data type of the matrix
1773  , bool SO > // Storage order
1774 template< typename MT > // Type of the right-hand side sparse matrix
1776 {
1777  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1778  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1779 
1780  for( size_t i=0UL; i<m_; ++i )
1781  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1782  v_[i*nn_+element->index()] = element->value();
1783 }
1784 //*************************************************************************************************
1785 
1786 
1787 //*************************************************************************************************
1798 template< typename Type // Data type of the matrix
1799  , bool SO > // Storage order
1800 template< typename MT > // Type of the right-hand side sparse matrix
1802 {
1803  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1804  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1805 
1806  for( size_t j=0UL; j<n_; ++j )
1807  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1808  v_[element->index()*nn_+j] = element->value();
1809 }
1810 //*************************************************************************************************
1811 
1812 
1813 //*************************************************************************************************
1824 template< typename Type // Data type of the matrix
1825  , bool SO > // Storage order
1826 template< typename MT > // Type of the right-hand side dense matrix
1827 inline typename DisableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
1829 {
1830  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1831  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1832 
1833  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == ( n_ & size_t(-2) ), "Invalid end calculation" );
1834  const size_t jend( n_ & size_t(-2) );
1835 
1836  for( size_t i=0UL; i<m_; ++i ) {
1837  for( size_t j=0UL; j<jend; j+=2UL ) {
1838  v_[i*nn_+j ] += (~rhs)(i,j );
1839  v_[i*nn_+j+1UL] += (~rhs)(i,j+1UL);
1840  }
1841  if( jend < n_ ) {
1842  v_[i*nn_+jend] += (~rhs)(i,jend);
1843  }
1844  }
1845 }
1846 //*************************************************************************************************
1847 
1848 
1849 //*************************************************************************************************
1860 template< typename Type // Data type of the matrix
1861  , bool SO > // Storage order
1862 template< typename MT > // Type of the right-hand side dense matrix
1863 inline typename EnableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
1865 {
1866  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1867  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1868 
1870 
1871  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == ( n_ & size_t(-IT::size*4) ), "Invalid end calculation" );
1872  const size_t jend( n_ & size_t(-IT::size*4) );
1873 
1874  for( size_t i=0UL; i<m_; ++i ) {
1875  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1876  store( &v_[i*nn_+j ], load( &v_[i*nn_+j ] ) + (~rhs).get(i,j ) );
1877  store( &v_[i*nn_+j+IT::size ], load( &v_[i*nn_+j+IT::size ] ) + (~rhs).get(i,j+IT::size ) );
1878  store( &v_[i*nn_+j+IT::size*2UL], load( &v_[i*nn_+j+IT::size*2UL] ) + (~rhs).get(i,j+IT::size*2UL) );
1879  store( &v_[i*nn_+j+IT::size*3UL], load( &v_[i*nn_+j+IT::size*3UL] ) + (~rhs).get(i,j+IT::size*3UL) );
1880  }
1881  for( size_t j=jend; j<n_; j+=IT::size ) {
1882  store( &v_[i*nn_+j], load( &v_[i*nn_+j] ) + (~rhs).get(i,j) );
1883  }
1884  }
1885 }
1886 //*************************************************************************************************
1887 
1888 
1889 //*************************************************************************************************
1900 template< typename Type // Data type of the matrix
1901  , bool SO > // Storage order
1902 template< typename MT > // Type of the right-hand side dense matrix
1904 {
1905  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1906  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1907 
1908  const size_t block( 16UL );
1909 
1910  for( size_t ii=0UL; ii<m_; ii+=block ) {
1911  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
1912  for( size_t jj=0UL; jj<n_; jj+=block ) {
1913  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
1914  for( size_t i=ii; i<iend; ++i ) {
1915  for( size_t j=jj; j<jend; ++j ) {
1916  v_[i*nn_+j] += (~rhs)(i,j);
1917  }
1918  }
1919  }
1920  }
1921 }
1922 //*************************************************************************************************
1923 
1924 
1925 //*************************************************************************************************
1936 template< typename Type // Data type of the matrix
1937  , bool SO > // Storage order
1938 template< typename MT > // Type of the right-hand side sparse matrix
1940 {
1941  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1942  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1943 
1944  for( size_t i=0UL; i<m_; ++i )
1945  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
1946  v_[i*nn_+element->index()] += element->value();
1947 }
1948 //*************************************************************************************************
1949 
1950 
1951 //*************************************************************************************************
1962 template< typename Type // Data type of the matrix
1963  , bool SO > // Storage order
1964 template< typename MT > // Type of the right-hand side sparse matrix
1966 {
1967  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1968  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1969 
1970  for( size_t j=0UL; j<n_; ++j )
1971  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
1972  v_[element->index()*nn_+j] += element->value();
1973 }
1974 //*************************************************************************************************
1975 
1976 
1977 //*************************************************************************************************
1988 template< typename Type // Data type of the matrix
1989  , bool SO > // Storage order
1990 template< typename MT > // Type of the right-hand side dense matrix
1991 inline typename DisableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
1993 {
1994  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
1995  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
1996 
1997  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % 2UL ) ) == ( n_ & size_t(-2) ), "Invalid end calculation" );
1998  const size_t jend( n_ & size_t(-2) );
1999 
2000  for( size_t i=0UL; i<m_; ++i ) {
2001  for( size_t j=0UL; j<jend; j+=2UL ) {
2002  v_[i*nn_+j ] -= (~rhs)(i,j );
2003  v_[i*nn_+j+1UL] -= (~rhs)(i,j+1UL);
2004  }
2005  if( jend < n_ ) {
2006  v_[i*nn_+jend] -= (~rhs)(i,jend);
2007  }
2008  }
2009 }
2010 //*************************************************************************************************
2011 
2012 
2013 //*************************************************************************************************
2024 template< typename Type // Data type of the matrix
2025  , bool SO > // Storage order
2026 template< typename MT > // Type of the right-hand side dense matrix
2027 inline typename EnableIf< typename DynamicMatrix<Type,SO>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
2029 {
2030  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2031  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2032 
2034 
2035  BLAZE_INTERNAL_ASSERT( ( n_ - ( n_ % (IT::size*4UL) ) ) == ( n_ & size_t(-IT::size*4) ), "Invalid end calculation" );
2036  const size_t jend( n_ & size_t(-IT::size*4) );
2037 
2038  for( size_t i=0UL; i<m_; ++i ) {
2039  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
2040  store( &v_[i*nn_+j ], load( &v_[i*nn_+j ] ) - (~rhs).get(i,j ) );
2041  store( &v_[i*nn_+j+IT::size ], load( &v_[i*nn_+j+IT::size ] ) - (~rhs).get(i,j+IT::size ) );
2042  store( &v_[i*nn_+j+IT::size*2UL], load( &v_[i*nn_+j+IT::size*2UL] ) - (~rhs).get(i,j+IT::size*2UL) );
2043  store( &v_[i*nn_+j+IT::size*3UL], load( &v_[i*nn_+j+IT::size*3UL] ) - (~rhs).get(i,j+IT::size*3UL) );
2044  }
2045  for( size_t j=jend; j<n_; j+=IT::size ) {
2046  store( &v_[i*nn_+j], load( &v_[i*nn_+j] ) - (~rhs).get(i,j) );
2047  }
2048  }
2049 }
2050 //*************************************************************************************************
2051 
2052 
2053 //*************************************************************************************************
2064 template< typename Type // Data type of the matrix
2065  , bool SO > // Storage order
2066 template< typename MT > // Type of the right-hand side dense matrix
2068 {
2069  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2070  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2071 
2072  const size_t block( 16UL );
2073 
2074  for( size_t ii=0UL; ii<m_; ii+=block ) {
2075  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
2076  for( size_t jj=0UL; jj<n_; jj+=block ) {
2077  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
2078  for( size_t i=ii; i<iend; ++i ) {
2079  for( size_t j=jj; j<jend; ++j ) {
2080  v_[i*nn_+j] -= (~rhs)(i,j);
2081  }
2082  }
2083  }
2084  }
2085 }
2086 //*************************************************************************************************
2087 
2088 
2089 //*************************************************************************************************
2100 template< typename Type // Data type of the matrix
2101  , bool SO > // Storage order
2102 template< typename MT > // Type of the right-hand side sparse matrix
2104 {
2105  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2106  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2107 
2108  for( size_t i=0UL; i<m_; ++i )
2109  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2110  v_[i*nn_+element->index()] -= element->value();
2111 }
2112 //*************************************************************************************************
2113 
2114 
2115 //*************************************************************************************************
2126 template< typename Type // Data type of the matrix
2127  , bool SO > // Storage order
2128 template< typename MT > // Type of the right-hand side sparse matrix
2130 {
2131  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
2132  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
2133 
2134  for( size_t j=0UL; j<n_; ++j )
2135  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2136  v_[element->index()*nn_+j] -= element->value();
2137 }
2138 //*************************************************************************************************
2139 
2140 
2141 
2142 
2143 
2144 
2145 
2146 
2147 //=================================================================================================
2148 //
2149 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
2150 //
2151 //=================================================================================================
2152 
2153 //*************************************************************************************************
2161 template< typename Type > // Data type of the matrix
2162 class DynamicMatrix<Type,true> : public DenseMatrix< DynamicMatrix<Type,true>, true >
2163 {
2164  private:
2165  //**Type definitions****************************************************************************
2166  typedef IntrinsicTrait<Type> IT;
2167  //**********************************************************************************************
2168 
2169  public:
2170  //**Type definitions****************************************************************************
2171  typedef DynamicMatrix<Type,true> This;
2172  typedef This ResultType;
2175  typedef Type ElementType;
2176  typedef const Type& ReturnType;
2177  typedef typename IT::Type IntrinsicType;
2178  typedef const This& CompositeType;
2179  typedef Type& Reference;
2180  typedef const Type& ConstReference;
2181  typedef Type* Iterator;
2182  typedef const Type* ConstIterator;
2183  //**********************************************************************************************
2184 
2185  //**Compilation flags***************************************************************************
2187 
2191  enum { vectorizable = IsVectorizable<Type>::value };
2192  //**********************************************************************************************
2193 
2194  //**Constructors********************************************************************************
2197  explicit inline DynamicMatrix();
2198  explicit inline DynamicMatrix( size_t m, size_t n );
2199  explicit inline DynamicMatrix( size_t m, size_t n, Type init );
2200  inline DynamicMatrix( const DynamicMatrix& m );
2201  template< typename MT, bool SO > inline DynamicMatrix( const Matrix<MT,SO>& m );
2202 
2203  template< typename Other, size_t M, size_t N >
2204  inline DynamicMatrix( const Other (&rhs)[M][N] );
2206  //**********************************************************************************************
2207 
2208  //**Destructor**********************************************************************************
2211  inline ~DynamicMatrix();
2213  //**********************************************************************************************
2214 
2215  //**Data access functions***********************************************************************
2218  inline Reference operator()( size_t i, size_t j );
2219  inline ConstReference operator()( size_t i, size_t j ) const;
2220  inline Type* data ();
2221  inline const Type* data () const;
2222  inline Type* data ( size_t j );
2223  inline const Type* data ( size_t j ) const;
2224  inline Iterator begin ( size_t j );
2225  inline ConstIterator begin ( size_t j ) const;
2226  inline ConstIterator cbegin( size_t j ) const;
2227  inline Iterator end ( size_t j );
2228  inline ConstIterator end ( size_t j ) const;
2229  inline ConstIterator cend ( size_t j ) const;
2231  //**********************************************************************************************
2232 
2233  //**Assignment operators************************************************************************
2236  template< typename Other, size_t M, size_t N >
2237  inline DynamicMatrix& operator=( const Other (&rhs)[M][N] );
2238 
2239  inline DynamicMatrix& operator= ( Type set );
2240  inline DynamicMatrix& operator= ( const DynamicMatrix& set );
2241  template< typename MT, bool SO > inline DynamicMatrix& operator= ( const Matrix<MT,SO>& rhs );
2242  template< typename MT, bool SO > inline DynamicMatrix& operator+=( const Matrix<MT,SO>& rhs );
2243  template< typename MT, bool SO > inline DynamicMatrix& operator-=( const Matrix<MT,SO>& rhs );
2244  template< typename MT, bool SO > inline DynamicMatrix& operator*=( const Matrix<MT,SO>& rhs );
2245 
2246  template< typename Other >
2247  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
2248  operator*=( Other rhs );
2249 
2250  template< typename Other >
2251  inline typename EnableIf< IsNumeric<Other>, DynamicMatrix >::Type&
2252  operator/=( Other rhs );
2254  //**********************************************************************************************
2255 
2256  //**Utility functions***************************************************************************
2259  inline size_t rows() const;
2260  inline size_t columns() const;
2261  inline size_t spacing() const;
2262  inline size_t capacity() const;
2263  inline size_t capacity( size_t j ) const;
2264  inline size_t nonZeros() const;
2265  inline size_t nonZeros( size_t j ) const;
2266  inline void reset();
2267  inline void reset( size_t j );
2268  inline void clear();
2269  void resize ( size_t m, size_t n, bool preserve=true );
2270  inline void extend ( size_t m, size_t n, bool preserve=true );
2271  inline void reserve( size_t elements );
2272  inline DynamicMatrix& transpose();
2273  inline bool isDiagonal() const;
2274  inline bool isSymmetric() const;
2275  template< typename Other > inline DynamicMatrix& scale( Other scalar );
2276  inline void swap( DynamicMatrix& m ) /* throw() */;
2278  //**********************************************************************************************
2279 
2280  private:
2281  //**********************************************************************************************
2283  template< typename MT >
2284  struct VectorizedAssign {
2285  enum { value = vectorizable && MT::vectorizable &&
2286  IsSame<Type,typename MT::ElementType>::value };
2287  };
2288  //**********************************************************************************************
2289 
2290  //**********************************************************************************************
2292  template< typename MT >
2293  struct VectorizedAddAssign {
2294  enum { value = vectorizable && MT::vectorizable &&
2295  IsSame<Type,typename MT::ElementType>::value &&
2296  IntrinsicTrait<Type>::addition };
2297  };
2298  //**********************************************************************************************
2299 
2300  //**********************************************************************************************
2302  template< typename MT >
2303  struct VectorizedSubAssign {
2304  enum { value = vectorizable && MT::vectorizable &&
2305  IsSame<Type,typename MT::ElementType>::value &&
2306  IntrinsicTrait<Type>::subtraction };
2307  };
2308  //**********************************************************************************************
2309 
2310  public:
2311  //**Expression template evaluation functions****************************************************
2314  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2315  template< typename Other > inline bool isAliased( const Other* alias ) const;
2316  inline IntrinsicType get ( size_t i, size_t j ) const;
2317 
2318  template< typename MT >
2319  inline typename DisableIf< VectorizedAssign<MT> >::Type
2320  assign( const DenseMatrix<MT,true>& rhs );
2321 
2322  template< typename MT >
2323  inline typename EnableIf< VectorizedAssign<MT> >::Type
2324  assign( const DenseMatrix<MT,true>& rhs );
2325 
2326  template< typename MT > inline void assign( const DenseMatrix<MT,false>& rhs );
2327  template< typename MT > inline void assign( const SparseMatrix<MT,true>& rhs );
2328  template< typename MT > inline void assign( const SparseMatrix<MT,false>& rhs );
2329 
2330  template< typename MT >
2331  inline typename DisableIf< VectorizedAddAssign<MT> >::Type
2332  addAssign( const DenseMatrix<MT,true>& rhs );
2333 
2334  template< typename MT >
2335  inline typename EnableIf< VectorizedAddAssign<MT> >::Type
2336  addAssign( const DenseMatrix<MT,true>& rhs );
2337 
2338  template< typename MT > inline void addAssign( const DenseMatrix<MT,false>& rhs );
2339  template< typename MT > inline void addAssign( const SparseMatrix<MT,true>& rhs );
2340  template< typename MT > inline void addAssign( const SparseMatrix<MT,false>& rhs );
2341 
2342  template< typename MT >
2343  inline typename DisableIf< VectorizedSubAssign<MT> >::Type
2344  subAssign ( const DenseMatrix<MT,true>& rhs );
2345 
2346  template< typename MT >
2347  inline typename EnableIf< VectorizedSubAssign<MT> >::Type
2348  subAssign ( const DenseMatrix<MT,true>& rhs );
2349 
2350  template< typename MT > inline void subAssign( const DenseMatrix<MT,false>& rhs );
2351  template< typename MT > inline void subAssign( const SparseMatrix<MT,true>& rhs );
2352  template< typename MT > inline void subAssign( const SparseMatrix<MT,false>& rhs );
2354  //**********************************************************************************************
2355 
2356  private:
2357  //**Utility functions***************************************************************************
2360  inline size_t adjustRows( size_t minRows ) const;
2362  //**********************************************************************************************
2363 
2364  //**Member variables****************************************************************************
2367  size_t m_;
2368  size_t mm_;
2369  size_t n_;
2370  size_t capacity_;
2371  Type* BLAZE_RESTRICT v_;
2372 
2382  //**********************************************************************************************
2383 
2384  //**Compile time checks*************************************************************************
2389  //**********************************************************************************************
2390 };
2392 //*************************************************************************************************
2393 
2394 
2395 
2396 
2397 //=================================================================================================
2398 //
2399 // CONSTRUCTORS
2400 //
2401 //=================================================================================================
2402 
2403 //*************************************************************************************************
2407 template< typename Type > // Data type of the matrix
2409  : m_ ( 0UL ) // The current number of rows of the matrix
2410  , mm_ ( 0UL ) // The alignment adjusted number of rows
2411  , n_ ( 0UL ) // The current number of columns of the matrix
2412  , capacity_( 0UL ) // The maximum capacity of the matrix
2413  , v_ ( NULL ) // The matrix elements
2414 {}
2416 //*************************************************************************************************
2417 
2418 
2419 //*************************************************************************************************
2429 template< typename Type > // Data type of the matrix
2430 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n )
2431  : m_ ( m ) // The current number of rows of the matrix
2432  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
2433  , n_ ( n ) // The current number of columns of the matrix
2434  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2435  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2436 {
2437  if( IsNumeric<Type>::value ) {
2438  for( size_t j=0UL; j<n_; ++j )
2439  for( size_t i=m_; i<mm_; ++i ) {
2440  v_[i+j*mm_] = Type();
2441  }
2442  }
2443 }
2445 //*************************************************************************************************
2446 
2447 
2448 //*************************************************************************************************
2458 template< typename Type > // Data type of the matrix
2459 inline DynamicMatrix<Type,true>::DynamicMatrix( size_t m, size_t n, Type init )
2460  : m_ ( m ) // The current number of rows of the matrix
2461  , mm_ ( adjustRows( m ) ) // The alignment adjusted number of rows
2462  , n_ ( n ) // The current number of columns of the matrix
2463  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2464  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2465 {
2466  for( size_t j=0UL; j<n_; ++j ) {
2467  for( size_t i=0UL; i<m_; ++i )
2468  v_[i+j*mm_] = init;
2469 
2470  if( IsNumeric<Type>::value ) {
2471  for( size_t i=m_; i<mm_; ++i )
2472  v_[i+j*mm_] = Type();
2473  }
2474  }
2475 }
2477 //*************************************************************************************************
2478 
2479 
2480 //*************************************************************************************************
2489 template< typename Type > // Data type of the matrix
2490 inline DynamicMatrix<Type,true>::DynamicMatrix( const DynamicMatrix& m )
2491  : m_ ( m.m_ ) // The current number of rows of the matrix
2492  , mm_ ( m.mm_ ) // The alignment adjusted number of rows
2493  , n_ ( m.n_ ) // The current number of columns of the matrix
2494  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2495  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2496 {
2497  BLAZE_INTERNAL_ASSERT( capacity_ <= m.capacity_, "Invalid capacity estimation" );
2498 
2499  for( size_t i=0UL; i<capacity_; ++i )
2500  v_[i] = m.v_[i];
2501 }
2503 //*************************************************************************************************
2504 
2505 
2506 //*************************************************************************************************
2512 template< typename Type > // Data type of the matrix
2513 template< typename MT // Type of the foreign matrix
2514  , bool SO > // Storage order of the foreign matrix
2515 inline DynamicMatrix<Type,true>::DynamicMatrix( const Matrix<MT,SO>& m )
2516  : m_ ( (~m).rows() ) // The current number of rows of the matrix
2517  , mm_ ( adjustRows( m_ ) ) // The alignment adjusted number of rows
2518  , n_ ( (~m).columns() ) // The current number of columns of the matrix
2519  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2520  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2521 {
2522  using blaze::assign;
2523 
2524  if( IsNumeric<Type>::value ) {
2525  for( size_t j=0UL; j<n_; ++j )
2526  for( size_t i=( IsSparseMatrix<MT>::value )?( 0UL ):( m_ ); i<mm_; ++i ) {
2527  v_[i+j*mm_] = Type();
2528  }
2529  }
2530 
2531  assign( *this, ~m );
2532 }
2534 //*************************************************************************************************
2535 
2536 
2537 //*************************************************************************************************
2558 template< typename Type > // Data type of the matrix
2559 template< typename Other // Data type of the initialization array
2560  , size_t M // Number of rows of the initialization array
2561  , size_t N > // Number of columns of the initialization array
2562 inline DynamicMatrix<Type,true>::DynamicMatrix( const Other (&rhs)[M][N] )
2563  : m_ ( M ) // The current number of rows of the matrix
2564  , mm_ ( adjustRows( M ) ) // The alignment adjusted number of rows
2565  , n_ ( N ) // The current number of columns of the matrix
2566  , capacity_( mm_*n_ ) // The maximum capacity of the matrix
2567  , v_ ( allocate<Type>( capacity_ ) ) // The matrix elements
2568 {
2569  for( size_t j=0UL; j<N; ++j ) {
2570  for( size_t i=0UL; i<M; ++i )
2571  v_[i+j*mm_] = rhs[i][j];
2572 
2573  if( IsNumeric<Type>::value ) {
2574  for( size_t i=M; i<mm_; ++i )
2575  v_[i+j*mm_] = Type();
2576  }
2577  }
2578 }
2580 //*************************************************************************************************
2581 
2582 
2583 
2584 
2585 //=================================================================================================
2586 //
2587 // DESTRUCTOR
2588 //
2589 //=================================================================================================
2590 
2591 //*************************************************************************************************
2595 template< typename Type > // Data type of the matrix
2597 {
2598  deallocate( v_ );
2599 }
2601 //*************************************************************************************************
2602 
2603 
2604 
2605 
2606 //=================================================================================================
2607 //
2608 // DATA ACCESS FUNCTIONS
2609 //
2610 //=================================================================================================
2611 
2612 //*************************************************************************************************
2620 template< typename Type > // Data type of the matrix
2621 inline typename DynamicMatrix<Type,true>::Reference
2622  DynamicMatrix<Type,true>::operator()( size_t i, size_t j )
2623 {
2624  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
2625  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
2626  return v_[i+j*mm_];
2627 }
2629 //*************************************************************************************************
2630 
2631 
2632 //*************************************************************************************************
2640 template< typename Type > // Data type of the matrix
2641 inline typename DynamicMatrix<Type,true>::ConstReference
2642  DynamicMatrix<Type,true>::operator()( size_t i, size_t j ) const
2643 {
2644  BLAZE_USER_ASSERT( i<m_, "Invalid row access index" );
2645  BLAZE_USER_ASSERT( j<n_, "Invalid column access index" );
2646  return v_[i+j*mm_];
2647 }
2649 //*************************************************************************************************
2650 
2651 
2652 //*************************************************************************************************
2658 template< typename Type > // Data type of the matrix
2659 inline Type* DynamicMatrix<Type,true>::data()
2660 {
2661  return v_;
2662 }
2664 //*************************************************************************************************
2665 
2666 
2667 //*************************************************************************************************
2673 template< typename Type > // Data type of the matrix
2674 inline const Type* DynamicMatrix<Type,true>::data() const
2675 {
2676  return v_;
2677 }
2679 //*************************************************************************************************
2680 
2681 
2682 //*************************************************************************************************
2689 template< typename Type > // Data type of the matrix
2690 inline Type* DynamicMatrix<Type,true>::data( size_t j )
2691 {
2692  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2693  return v_ + j*mm_;
2694 }
2696 //*************************************************************************************************
2697 
2698 
2699 //*************************************************************************************************
2706 template< typename Type > // Data type of the matrix
2707 inline const Type* DynamicMatrix<Type,true>::data( size_t j ) const
2708 {
2709  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2710  return v_ + j*mm_;
2711 }
2713 //*************************************************************************************************
2714 
2715 
2716 //*************************************************************************************************
2723 template< typename Type > // Data type of the matrix
2724 inline typename DynamicMatrix<Type,true>::Iterator
2726 {
2727  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2728  return v_ + j*mm_;
2729 }
2731 //*************************************************************************************************
2732 
2733 
2734 //*************************************************************************************************
2741 template< typename Type > // Data type of the matrix
2742 inline typename DynamicMatrix<Type,true>::ConstIterator
2743  DynamicMatrix<Type,true>::begin( size_t j ) const
2744 {
2745  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2746  return v_ + j*mm_;
2747 }
2749 //*************************************************************************************************
2750 
2751 
2752 //*************************************************************************************************
2759 template< typename Type > // Data type of the matrix
2760 inline typename DynamicMatrix<Type,true>::ConstIterator
2761  DynamicMatrix<Type,true>::cbegin( size_t j ) const
2762 {
2763  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2764  return v_ + j*mm_;
2765 }
2767 //*************************************************************************************************
2768 
2769 
2770 //*************************************************************************************************
2777 template< typename Type > // Data type of the matrix
2778 inline typename DynamicMatrix<Type,true>::Iterator
2779  DynamicMatrix<Type,true>::end( size_t j )
2780 {
2781  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2782  return v_ + j*mm_ + m_;
2783 }
2785 //*************************************************************************************************
2786 
2787 
2788 //*************************************************************************************************
2795 template< typename Type > // Data type of the matrix
2796 inline typename DynamicMatrix<Type,true>::ConstIterator
2797  DynamicMatrix<Type,true>::end( size_t j ) const
2798 {
2799  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2800  return v_ + j*mm_ + m_;
2801 }
2803 //*************************************************************************************************
2804 
2805 
2806 //*************************************************************************************************
2813 template< typename Type > // Data type of the matrix
2814 inline typename DynamicMatrix<Type,true>::ConstIterator
2815  DynamicMatrix<Type,true>::cend( size_t j ) const
2816 {
2817  BLAZE_USER_ASSERT( j < n_, "Invalid dense matrix column access index" );
2818  return v_ + j*mm_ + m_;
2819 }
2821 //*************************************************************************************************
2822 
2823 
2824 
2825 
2826 //=================================================================================================
2827 //
2828 // ASSIGNMENT OPERATORS
2829 //
2830 //=================================================================================================
2831 
2832 //*************************************************************************************************
2852 template< typename Type > // Data type of the matrix
2853 template< typename Other // Data type of the initialization array
2854  , size_t M // Number of rows of the initialization array
2855  , size_t N > // Number of columns of the initialization array
2856 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Other (&rhs)[M][N] )
2857 {
2858  resize( M, N, false );
2859 
2860  for( size_t j=0UL; j<N; ++j )
2861  for( size_t i=0UL; i<M; ++i )
2862  v_[i+j*mm_] = rhs[i][j];
2863 
2864  return *this;
2865 }
2867 //*************************************************************************************************
2868 
2869 
2870 //*************************************************************************************************
2877 template< typename Type > // Data type of the matrix
2878 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( Type rhs )
2879 {
2880  for( size_t j=0UL; j<n_; ++j )
2881  for( size_t i=0UL; i<m_; ++i )
2882  v_[i+j*mm_] = rhs;
2883 
2884  return *this;
2885 }
2887 //*************************************************************************************************
2888 
2889 
2890 //*************************************************************************************************
2900 template< typename Type > // Data type of the matrix
2901 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const DynamicMatrix& rhs )
2902 {
2903  if( &rhs == this ) return *this;
2904 
2905  resize( rhs.m_, rhs.n_, false );
2906 
2907  for( size_t j=0UL; j<n_; ++j )
2908  for( size_t i=0UL; i<m_; ++i )
2909  v_[i+j*mm_] = rhs(i,j);
2910 
2911  return *this;
2912 }
2914 //*************************************************************************************************
2915 
2916 
2917 //*************************************************************************************************
2927 template< typename Type > // Data type of the matrix
2928 template< typename MT // Type of the right-hand side matrix
2929  , bool SO > // Storage order of the right-hand side matrix
2930 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator=( const Matrix<MT,SO>& rhs )
2931 {
2932  using blaze::assign;
2933 
2934  if( (~rhs).canAlias( this ) ) {
2935  DynamicMatrix tmp( ~rhs );
2936  swap( tmp );
2937  }
2938  else {
2939  resize( (~rhs).rows(), (~rhs).columns(), false );
2940  if( IsSparseMatrix<MT>::value )
2941  reset();
2942  assign( *this, ~rhs );
2943  }
2944 
2945  return *this;
2946 }
2948 //*************************************************************************************************
2949 
2950 
2951 //*************************************************************************************************
2962 template< typename Type > // Data type of the matrix
2963 template< typename MT // Type of the right-hand side matrix
2964  , bool SO > // Storage order of the right-hand side matrix
2965 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator+=( const Matrix<MT,SO>& rhs )
2966 {
2967  using blaze::addAssign;
2968 
2969  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
2970  throw std::invalid_argument( "Matrix sizes do not match" );
2971 
2972  if( (~rhs).canAlias( this ) ) {
2973  typename MT::ResultType tmp( ~rhs );
2974  addAssign( *this, tmp );
2975  }
2976  else {
2977  addAssign( *this, ~rhs );
2978  }
2979 
2980  return *this;
2981 }
2983 //*************************************************************************************************
2984 
2985 
2986 //*************************************************************************************************
2997 template< typename Type > // Data type of the matrix
2998 template< typename MT // Type of the right-hand side matrix
2999  , bool SO > // Storage order of the right-hand side matrix
3000 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator-=( const Matrix<MT,SO>& rhs )
3001 {
3002  using blaze::subAssign;
3003 
3004  if( (~rhs).rows() != m_ || (~rhs).columns() != n_ )
3005  throw std::invalid_argument( "Matrix sizes do not match" );
3006 
3007  if( (~rhs).canAlias( this ) ) {
3008  typename MT::ResultType tmp( ~rhs );
3009  subAssign( *this, tmp );
3010  }
3011  else {
3012  subAssign( *this, ~rhs );
3013  }
3014 
3015  return *this;
3016 }
3018 //*************************************************************************************************
3019 
3020 
3021 //*************************************************************************************************
3032 template< typename Type > // Data type of the matrix
3033 template< typename MT // Type of the right-hand side matrix
3034  , bool SO > // Storage order of the right-hand side matrix
3035 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::operator*=( const Matrix<MT,SO>& rhs )
3036 {
3037  if( (~rhs).rows() != n_ )
3038  throw std::invalid_argument( "Matrix sizes do not match" );
3039 
3040  DynamicMatrix tmp( *this * (~rhs) );
3041  swap( tmp );
3042 
3043  return *this;
3044 }
3046 //*************************************************************************************************
3047 
3048 
3049 //*************************************************************************************************
3057 template< typename Type > // Data type of the matrix
3058 template< typename Other > // Data type of the right-hand side scalar
3059 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,true> >::Type&
3060  DynamicMatrix<Type,true>::operator*=( Other rhs )
3061 {
3062  return operator=( (*this) * rhs );
3063 }
3065 //*************************************************************************************************
3066 
3067 
3068 //*************************************************************************************************
3076 template< typename Type > // Data type of the matrix
3077 template< typename Other > // Data type of the right-hand side scalar
3078 inline typename EnableIf< IsNumeric<Other>, DynamicMatrix<Type,true> >::Type&
3079  DynamicMatrix<Type,true>::operator/=( Other rhs )
3080 {
3081  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3082 
3083  return operator=( (*this) / rhs );
3084 }
3086 //*************************************************************************************************
3087 
3088 
3089 
3090 
3091 //=================================================================================================
3092 //
3093 // UTILITY FUNCTIONS
3094 //
3095 //=================================================================================================
3096 
3097 //*************************************************************************************************
3103 template< typename Type > // Data type of the matrix
3104 inline size_t DynamicMatrix<Type,true>::rows() const
3105 {
3106  return m_;
3107 }
3109 //*************************************************************************************************
3110 
3111 
3112 //*************************************************************************************************
3118 template< typename Type > // Data type of the matrix
3119 inline size_t DynamicMatrix<Type,true>::columns() const
3120 {
3121  return n_;
3122 }
3124 //*************************************************************************************************
3125 
3126 
3127 //*************************************************************************************************
3136 template< typename Type > // Data type of the matrix
3137 inline size_t DynamicMatrix<Type,true>::spacing() const
3138 {
3139  return mm_;
3140 }
3142 //*************************************************************************************************
3143 
3144 
3145 //*************************************************************************************************
3151 template< typename Type > // Data type of the matrix
3152 inline size_t DynamicMatrix<Type,true>::capacity() const
3153 {
3154  return capacity_;
3155 }
3157 //*************************************************************************************************
3158 
3159 
3160 //*************************************************************************************************
3167 template< typename Type > // Data type of the sparse matrix
3168 inline size_t DynamicMatrix<Type,true>::capacity( size_t j ) const
3169 {
3170  UNUSED_PARAMETER( j );
3171  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3172  return mm_;
3173 }
3175 //*************************************************************************************************
3176 
3177 
3178 //*************************************************************************************************
3184 template< typename Type > // Data type of the matrix
3185 inline size_t DynamicMatrix<Type,true>::nonZeros() const
3186 {
3187  size_t nonzeros( 0UL );
3188 
3189  for( size_t j=0UL; j<n_; ++j )
3190  for( size_t i=0UL; i<m_; ++i )
3191  if( !isDefault( v_[i+j*mm_] ) )
3192  ++nonzeros;
3193 
3194  return nonzeros;
3195 }
3197 //*************************************************************************************************
3198 
3199 
3200 //*************************************************************************************************
3207 template< typename Type > // Data type of the matrix
3208 inline size_t DynamicMatrix<Type,true>::nonZeros( size_t j ) const
3209 {
3210  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3211 
3212  const size_t iend( (j+1UL)*mm_ );
3213  size_t nonzeros( 0UL );
3214 
3215  for( size_t i=j*mm_; i<iend; ++i )
3216  if( !isDefault( v_[i] ) )
3217  ++nonzeros;
3218 
3219  return nonzeros;
3220 }
3222 //*************************************************************************************************
3223 
3224 
3225 //*************************************************************************************************
3231 template< typename Type > // Data type of the matrix
3232 inline void DynamicMatrix<Type,true>::reset()
3233 {
3234  using blaze::reset;
3235 
3236  for( size_t j=0UL; j<n_; ++j )
3237  for( size_t i=0UL; i<m_; ++i )
3238  reset( v_[i+j*mm_] );
3239 }
3241 //*************************************************************************************************
3242 
3243 
3244 //*************************************************************************************************
3254 template< typename Type > // Data type of the sparse matrix
3255 inline void DynamicMatrix<Type,true>::reset( size_t j )
3256 {
3257  using blaze::reset;
3258 
3259  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3260  for( size_t i=0UL; i<m_; ++i )
3261  reset( v_[i+j*mm_] );
3262 }
3264 //*************************************************************************************************
3265 
3266 
3267 //*************************************************************************************************
3275 template< typename Type > // Data type of the matrix
3276 inline void DynamicMatrix<Type,true>::clear()
3277 {
3278  m_ = 0UL;
3279  mm_ = 0UL;
3280  n_ = 0UL;
3281 }
3283 //*************************************************************************************************
3284 
3285 
3286 //*************************************************************************************************
3320 template< typename Type > // Data type of the matrix
3321 void DynamicMatrix<Type,true>::resize( size_t m, size_t n, bool preserve )
3322 {
3323  using blaze::min;
3324 
3325  if( m == m_ && n == n_ ) return;
3326 
3327  const size_t mm( adjustRows( m ) );
3328 
3329  if( preserve )
3330  {
3331  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
3332  const size_t min_m( min( m, m_ ) );
3333  const size_t min_n( min( n, n_ ) );
3334 
3335  for( size_t j=0UL; j<min_n; ++j )
3336  for( size_t i=0UL; i<min_m; ++i )
3337  v[i+j*mm] = v_[i+j*mm_];
3338 
3339  if( IsNumeric<Type>::value ) {
3340  for( size_t j=0UL; j<n; ++j )
3341  for( size_t i=m; i<mm; ++i )
3342  v[i+j*mm] = Type();
3343  }
3344 
3345  std::swap( v_, v );
3346  deallocate( v );
3347  capacity_ = mm*n;
3348  }
3349  else if( mm*n > capacity_ ) {
3350  Type* BLAZE_RESTRICT v = allocate<Type>( mm*n );
3351 
3352  if( IsNumeric<Type>::value ) {
3353  for( size_t j=0UL; j<n; ++j )
3354  for( size_t i=m; i<mm; ++i )
3355  v[i+j*mm] = Type();
3356  }
3357 
3358  std::swap( v_, v );
3359  deallocate( v );
3360  capacity_ = mm*n;
3361  }
3362 
3363  m_ = m;
3364  mm_ = mm;
3365  n_ = n;
3366 }
3368 //*************************************************************************************************
3369 
3370 
3371 //*************************************************************************************************
3386 template< typename Type > // Data type of the matrix
3387 inline void DynamicMatrix<Type,true>::extend( size_t m, size_t n, bool preserve )
3388 {
3389  resize( m_+m, n_+n, preserve );
3390 }
3392 //*************************************************************************************************
3393 
3394 
3395 //*************************************************************************************************
3405 template< typename Type > // Data type of the matrix
3406 inline void DynamicMatrix<Type,true>::reserve( size_t elements )
3407 {
3408  if( elements > capacity_ )
3409  {
3410  // Allocating a new array
3411  Type* BLAZE_RESTRICT tmp = allocate<Type>( elements );
3412 
3413  // Initializing the new array
3414  std::copy( v_, v_+capacity_, tmp );
3415 
3416  if( IsNumeric<Type>::value ) {
3417  for( size_t i=capacity_; i<elements; ++i )
3418  tmp[i] = Type();
3419  }
3420 
3421  // Replacing the old array
3422  std::swap( tmp, v_ );
3423  deallocate( tmp );
3424  capacity_ = elements;
3425  }
3426 }
3428 //*************************************************************************************************
3429 
3430 
3431 //*************************************************************************************************
3437 template< typename Type > // Data type of the matrix
3438 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::transpose()
3439 {
3440  DynamicMatrix tmp( trans(*this) );
3441  swap( tmp );
3442  return *this;
3443 }
3445 //*************************************************************************************************
3446 
3447 
3448 //*************************************************************************************************
3466 template< typename Type > // Data type of the matrix
3467 inline bool DynamicMatrix<Type,true>::isDiagonal() const
3468 {
3469  if( m_ != n_ ) return false;
3470 
3471  for( size_t j=1UL; j<n_; ++j ) {
3472  for( size_t i=0UL; i<j; ++i ) {
3473  if( !isDefault( v_[i+j*mm_] ) || !isDefault( v_[j+i*mm_] ) )
3474  return false;
3475  }
3476  }
3477 
3478  return true;
3479 }
3481 //*************************************************************************************************
3482 
3483 
3484 //*************************************************************************************************
3490 template< typename Type > // Data type of the matrix
3491 inline bool DynamicMatrix<Type,true>::isSymmetric() const
3492 {
3493  if( m_ != n_ ) return false;
3494 
3495  for( size_t j=1UL; j<n_; ++j ) {
3496  for( size_t i=0UL; i<j; ++i ) {
3497  if( !equal( v_[i+j*mm_], v_[j+i*mm_] ) )
3498  return false;
3499  }
3500  }
3501 
3502  return true;
3503 }
3505 //*************************************************************************************************
3506 
3507 
3508 //*************************************************************************************************
3515 template< typename Type > // Data type of the matrix
3516 template< typename Other > // Data type of the scalar value
3517 inline DynamicMatrix<Type,true>& DynamicMatrix<Type,true>::scale( Other scalar )
3518 {
3519  for( size_t j=0UL; j<n_; ++j )
3520  for( size_t i=0UL; i<m_; ++i )
3521  v_[i+j*mm_] *= scalar;
3522 
3523  return *this;
3524 }
3526 //*************************************************************************************************
3527 
3528 
3529 //*************************************************************************************************
3537 template< typename Type > // Data type of the matrix
3538 inline void DynamicMatrix<Type,true>::swap( DynamicMatrix& m ) /* throw() */
3539 {
3540  std::swap( m_ , m.m_ );
3541  std::swap( mm_, m.mm_ );
3542  std::swap( n_ , m.n_ );
3543  std::swap( capacity_, m.capacity_ );
3544  std::swap( v_ , m.v_ );
3545 }
3547 //*************************************************************************************************
3548 
3549 
3550 //*************************************************************************************************
3557 template< typename Type > // Data type of the matrix
3558 inline size_t DynamicMatrix<Type,true>::adjustRows( size_t minRows ) const
3559 {
3560  if( IsNumeric<Type>::value )
3561  return minRows + ( IT::size - ( minRows % IT::size ) ) % IT::size;
3562  else return minRows;
3563 }
3565 //*************************************************************************************************
3566 
3567 
3568 
3569 
3570 //=================================================================================================
3571 //
3572 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3573 //
3574 //=================================================================================================
3575 
3576 //*************************************************************************************************
3587 template< typename Type > // Data type of the matrix
3588 template< typename Other > // Data type of the foreign expression
3589 inline bool DynamicMatrix<Type,true>::canAlias( const Other* alias ) const
3590 {
3591  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3592 }
3594 //*************************************************************************************************
3595 
3596 
3597 //*************************************************************************************************
3608 template< typename Type > // Data type of the matrix
3609 template< typename Other > // Data type of the foreign expression
3610 inline bool DynamicMatrix<Type,true>::isAliased( const Other* alias ) const
3611 {
3612  return static_cast<const void*>( this ) == static_cast<const void*>( alias );
3613 }
3615 //*************************************************************************************************
3616 
3617 
3618 //*************************************************************************************************
3631 template< typename Type > // Data type of the matrix
3632 inline typename DynamicMatrix<Type,true>::IntrinsicType
3633  DynamicMatrix<Type,true>::get( size_t i, size_t j ) const
3634 {
3636 
3637  BLAZE_INTERNAL_ASSERT( i < m_ , "Invalid row access index" );
3638  BLAZE_INTERNAL_ASSERT( i + IT::size <= mm_, "Invalid row access index" );
3639  BLAZE_INTERNAL_ASSERT( i % IT::size == 0UL, "Invalid row access index" );
3640  BLAZE_INTERNAL_ASSERT( j < n_ , "Invalid column access index" );
3641 
3642  return load( &v_[i+j*mm_] );
3643 }
3645 //*************************************************************************************************
3646 
3647 
3648 //*************************************************************************************************
3660 template< typename Type > // Data type of the matrix
3661 template< typename MT > // Type of the right-hand side dense matrix
3662 inline typename DisableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
3663  DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
3664 {
3665  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3666  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3667 
3668  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ( m_ & size_t(-2) ), "Invalid end calculation" );
3669  const size_t iend( m_ & size_t(-2) );
3670 
3671  for( size_t j=0UL; j<n_; ++j ) {
3672  for( size_t i=0UL; i<iend; i+=2UL ) {
3673  v_[i +j*mm_] = (~rhs)(i ,j);
3674  v_[i+1UL+j*mm_] = (~rhs)(i+1UL,j);
3675  }
3676  if( iend < m_ ) {
3677  v_[iend+j*mm_] = (~rhs)(iend,j);
3678  }
3679  }
3680 }
3682 //*************************************************************************************************
3683 
3684 
3685 //*************************************************************************************************
3697 template< typename Type > // Data type of the matrix
3698 template< typename MT > // Type of the right-hand side dense matrix
3699 inline typename EnableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAssign<MT> >::Type
3700  DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,true>& rhs )
3701 {
3702  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3703  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3704 
3706 
3707  if( m_*n_ > ( cacheSize / ( sizeof(Type) * 3UL ) ) && !(~rhs).isAliased( this ) )
3708  {
3709  for( size_t j=0UL; j<n_; ++j )
3710  for( size_t i=0UL; i<m_; i+=IT::size )
3711  stream( &v_[i+j*mm_], (~rhs).get(i,j) );
3712  }
3713  else
3714  {
3715  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ( m_ & size_t(-IT::size*4) ), "Invalid end calculation" );
3716  const size_t iend( m_ & size_t(-IT::size*4) );
3717 
3718  for( size_t j=0UL; j<n_; ++j ) {
3719  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3720  store( &v_[i+j*mm_ ], (~rhs).get(i ,j) );
3721  store( &v_[i+j*mm_+IT::size ], (~rhs).get(i+IT::size ,j) );
3722  store( &v_[i+j*mm_+IT::size*2UL], (~rhs).get(i+IT::size*2UL,j) );
3723  store( &v_[i+j*mm_+IT::size*3UL], (~rhs).get(i+IT::size*3UL,j) );
3724  }
3725  for( size_t i=iend; i<m_; i+=IT::size ) {
3726  store( &v_[i+j*mm_], (~rhs).get(i,j) );
3727  }
3728  }
3729  }
3730 }
3732 //*************************************************************************************************
3733 
3734 
3735 //*************************************************************************************************
3747 template< typename Type > // Data type of the matrix
3748 template< typename MT > // Type of the right-hand side dense matrix
3749 inline void DynamicMatrix<Type,true>::assign( const DenseMatrix<MT,false>& rhs )
3750 {
3751  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3752  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3753 
3754  const size_t block( 16UL );
3755 
3756  for( size_t jj=0UL; jj<n_; jj+=block ) {
3757  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3758  for( size_t ii=0UL; ii<m_; ii+=block ) {
3759  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3760  for( size_t j=jj; j<jend; ++j ) {
3761  for( size_t i=ii; i<iend; ++i ) {
3762  v_[i+j*mm_] = (~rhs)(i,j);
3763  }
3764  }
3765  }
3766  }
3767 }
3769 //*************************************************************************************************
3770 
3771 
3772 //*************************************************************************************************
3784 template< typename Type > // Data type of the matrix
3785 template< typename MT > // Type of the right-hand side sparse matrix
3786 inline void DynamicMatrix<Type,true>::assign( const SparseMatrix<MT,true>& rhs )
3787 {
3788  for( size_t j=0UL; j<(~rhs).columns(); ++j )
3789  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3790  v_[element->index()+j*mm_] = element->value();
3791 }
3793 //*************************************************************************************************
3794 
3795 
3796 //*************************************************************************************************
3808 template< typename Type > // Data type of the matrix
3809 template< typename MT > // Type of the right-hand side sparse matrix
3810 inline void DynamicMatrix<Type,true>::assign( const SparseMatrix<MT,false>& rhs )
3811 {
3812  for( size_t i=0UL; i<(~rhs).rows(); ++i )
3813  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3814  v_[i+element->index()*mm_] = element->value();
3815 }
3817 //*************************************************************************************************
3818 
3819 
3820 //*************************************************************************************************
3832 template< typename Type > // Data type of the matrix
3833 template< typename MT > // Type of the right-hand side dense matrix
3834 inline typename DisableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
3835  DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
3836 {
3837  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3838  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3839 
3840  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ( m_ & size_t(-2) ), "Invalid end calculation" );
3841  const size_t iend( m_ & size_t(-2) );
3842 
3843  for( size_t j=0UL; j<n_; ++j ) {
3844  for( size_t i=0UL; i<iend; i+=2UL ) {
3845  v_[i +j*mm_] += (~rhs)(i ,j);
3846  v_[i+1UL+j*mm_] += (~rhs)(i+1UL,j);
3847  }
3848  if( iend < m_ ) {
3849  v_[iend+j*mm_] += (~rhs)(iend,j);
3850  }
3851  }
3852 }
3854 //*************************************************************************************************
3855 
3856 
3857 //*************************************************************************************************
3869 template< typename Type > // Data type of the matrix
3870 template< typename MT > // Type of the right-hand side dense matrix
3871 inline typename EnableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedAddAssign<MT> >::Type
3872  DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,true>& rhs )
3873 {
3874  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
3875  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
3876 
3878 
3879  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ( m_ & size_t(-IT::size*4) ), "Invalid end calculation" );
3880  const size_t iend( m_ & size_t(-IT::size*4) );
3881 
3882  for( size_t j=0UL; j<n_; ++j ) {
3883  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
3884  store( &v_[i+j*mm_ ], load( &v_[i+j*mm_ ] ) + (~rhs).get(i ,j) );
3885  store( &v_[i+j*mm_+IT::size ], load( &v_[i+j*mm_+IT::size ] ) + (~rhs).get(i+IT::size ,j) );
3886  store( &v_[i+j*mm_+IT::size*2UL], load( &v_[i+j*mm_+IT::size*2UL] ) + (~rhs).get(i+IT::size*2UL,j) );
3887  store( &v_[i+j*mm_+IT::size*3UL], load( &v_[i+j*mm_+IT::size*3UL] ) + (~rhs).get(i+IT::size*3UL,j) );
3888  }
3889  for( size_t i=iend; i<m_; i+=IT::size ) {
3890  store( &v_[i+j*mm_], load( &v_[i+j*mm_] ) + (~rhs).get(i,j) );
3891  }
3892  }
3893 }
3895 //*************************************************************************************************
3896 
3897 
3898 //*************************************************************************************************
3910 template< typename Type > // Data type of the matrix
3911 template< typename MT > // Type of the right-hand side dense matrix
3912 inline void DynamicMatrix<Type,true>::addAssign( const DenseMatrix<MT,false>& 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 
3917  const size_t block( 16UL );
3918 
3919  for( size_t jj=0UL; jj<n_; jj+=block ) {
3920  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
3921  for( size_t ii=0UL; ii<m_; ii+=block ) {
3922  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
3923  for( size_t j=jj; j<jend; ++j ) {
3924  for( size_t i=ii; i<iend; ++i ) {
3925  v_[i+j*mm_] += (~rhs)(i,j);
3926  }
3927  }
3928  }
3929  }
3930 }
3932 //*************************************************************************************************
3933 
3934 
3935 //*************************************************************************************************
3947 template< typename Type > // Data type of the matrix
3948 template< typename MT > // Type of the right-hand side sparse matrix
3949 inline void DynamicMatrix<Type,true>::addAssign( const SparseMatrix<MT,true>& rhs )
3950 {
3951  for( size_t j=0UL; j<(~rhs).columns(); ++j )
3952  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
3953  v_[element->index()+j*mm_] += element->value();
3954 }
3956 //*************************************************************************************************
3957 
3958 
3959 //*************************************************************************************************
3971 template< typename Type > // Data type of the matrix
3972 template< typename MT > // Type of the right-hand side sparse matrix
3973 inline void DynamicMatrix<Type,true>::addAssign( const SparseMatrix<MT,false>& rhs )
3974 {
3975  for( size_t i=0UL; i<(~rhs).rows(); ++i )
3976  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
3977  v_[i+element->index()*mm_] += element->value();
3978 }
3980 //*************************************************************************************************
3981 
3982 
3983 //*************************************************************************************************
3995 template< typename Type > // Data type of the matrix
3996 template< typename MT > // Type of the right-hand side dense matrix
3997 inline typename DisableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
3998  DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
3999 {
4000  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4001  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4002 
4003  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % 2UL ) ) == ( m_ & size_t(-2) ), "Invalid end calculation" );
4004  const size_t iend( m_ & size_t(-2) );
4005 
4006  for( size_t j=0UL; j<n_; ++j ) {
4007  for( size_t i=0UL; i<iend; i+=2UL ) {
4008  v_[i +j*mm_] -= (~rhs)(i ,j);
4009  v_[i+1+j*mm_] -= (~rhs)(i+1,j);
4010  }
4011  if( iend < m_ ) {
4012  v_[iend+j*mm_] -= (~rhs)(iend,j);
4013  }
4014  }
4015 }
4017 //*************************************************************************************************
4018 
4019 
4020 //*************************************************************************************************
4033 template< typename Type > // Data type of the matrix
4034 template< typename MT > // Type of the right-hand side dense matrix
4035 inline typename EnableIf< typename DynamicMatrix<Type,true>::BLAZE_TEMPLATE VectorizedSubAssign<MT> >::Type
4036  DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,true>& rhs )
4037 {
4038  BLAZE_INTERNAL_ASSERT( m_ == (~rhs).rows() , "Invalid number of rows" );
4039  BLAZE_INTERNAL_ASSERT( n_ == (~rhs).columns(), "Invalid number of columns" );
4040 
4042 
4043  BLAZE_INTERNAL_ASSERT( ( m_ - ( m_ % (IT::size*4UL) ) ) == ( m_ & size_t(-IT::size*4) ), "Invalid end calculation" );
4044  const size_t iend( m_ & size_t(-IT::size*4) );
4045 
4046  for( size_t j=0UL; j<n_; ++j ) {
4047  for( size_t i=0UL; i<iend; i+=IT::size*4UL ) {
4048  store( &v_[i+j*mm_ ], load( &v_[i+j*mm_ ] ) - (~rhs).get(i ,j) );
4049  store( &v_[i+j*mm_+IT::size ], load( &v_[i+j*mm_+IT::size ] ) - (~rhs).get(i+IT::size ,j) );
4050  store( &v_[i+j*mm_+IT::size*2UL], load( &v_[i+j*mm_+IT::size*2UL] ) - (~rhs).get(i+IT::size*2UL,j) );
4051  store( &v_[i+j*mm_+IT::size*3UL], load( &v_[i+j*mm_+IT::size*3UL] ) - (~rhs).get(i+IT::size*3UL,j) );
4052  }
4053  for( size_t i=iend; i<m_; i+=IT::size ) {
4054  store( &v_[i+j*mm_], load( &v_[i+j*mm_] ) - (~rhs).get(i,j) );
4055  }
4056  }
4057 }
4059 //*************************************************************************************************
4060 
4061 
4062 //*************************************************************************************************
4074 template< typename Type > // Data type of the matrix
4075 template< typename MT > // Type of the right-hand side dense matrix
4076 inline void DynamicMatrix<Type,true>::subAssign( const DenseMatrix<MT,false>& rhs )
4077 {
4078  const size_t block( 16UL );
4079 
4080  for( size_t jj=0UL; jj<n_; jj+=block ) {
4081  const size_t jend( ( n_<(jj+block) )?( n_ ):( jj+block ) );
4082  for( size_t ii=0UL; ii<m_; ii+=block ) {
4083  const size_t iend( ( m_<(ii+block) )?( m_ ):( ii+block ) );
4084  for( size_t j=jj; j<jend; ++j ) {
4085  for( size_t i=ii; i<iend; ++i ) {
4086  v_[i+j*mm_] -= (~rhs)(i,j);
4087  }
4088  }
4089  }
4090  }
4091 }
4093 //*************************************************************************************************
4094 
4095 
4096 //*************************************************************************************************
4108 template< typename Type > // Data type of the matrix
4109 template< typename MT > // Type of the right-hand side sparse matrix
4110 inline void DynamicMatrix<Type,true>::subAssign( const SparseMatrix<MT,true>& rhs )
4111 {
4112  for( size_t j=0UL; j<(~rhs).columns(); ++j )
4113  for( typename MT::ConstIterator element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
4114  v_[element->index()+j*mm_] -= element->value();
4115 }
4117 //*************************************************************************************************
4118 
4119 
4120 //*************************************************************************************************
4132 template< typename Type > // Data type of the matrix
4133 template< typename MT > // Type of the right-hand side sparse matrix
4134 inline void DynamicMatrix<Type,true>::subAssign( const SparseMatrix<MT,false>& rhs )
4135 {
4136  for( size_t i=0UL; i<(~rhs).rows(); ++i )
4137  for( typename MT::ConstIterator element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
4138  v_[i+element->index()*mm_] -= element->value();
4139 }
4141 //*************************************************************************************************
4142 
4143 
4144 
4145 
4146 
4147 
4148 
4149 
4150 //=================================================================================================
4151 //
4152 // DYNAMICMATRIX OPERATORS
4153 //
4154 //=================================================================================================
4155 
4156 //*************************************************************************************************
4159 template< typename Type, bool SO >
4160 inline bool isnan( const DynamicMatrix<Type,SO>& m );
4161 
4162 template< typename Type, bool SO >
4163 inline void reset( DynamicMatrix<Type,SO>& m );
4164 
4165 template< typename Type, bool SO >
4166 inline void clear( DynamicMatrix<Type,SO>& m );
4167 
4168 template< typename Type, bool SO >
4169 inline bool isDefault( const DynamicMatrix<Type,SO>& m );
4170 
4171 template< typename Type, bool SO >
4172 inline void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) /* throw() */;
4174 //*************************************************************************************************
4175 
4176 
4177 //*************************************************************************************************
4184 template< typename Type // Data type of the matrix
4185  , bool SO > // Storage order
4186 inline bool isnan( const DynamicMatrix<Type,SO>& m )
4187 {
4188  for( size_t i=0UL; i<m.rows(); ++i ) {
4189  for( size_t j=0UL; j<m.columns(); ++j )
4190  if( isnan( m(i,j) ) ) return true;
4191  }
4192  return false;
4193 }
4194 //*************************************************************************************************
4195 
4196 
4197 //*************************************************************************************************
4204 template< typename Type // Data type of the matrix
4205  , bool SO > // Storage order
4207 {
4208  m.reset();
4209 }
4210 //*************************************************************************************************
4211 
4212 
4213 //*************************************************************************************************
4220 template< typename Type // Data type of the matrix
4221  , bool SO > // Storage order
4223 {
4224  m.clear();
4225 }
4226 //*************************************************************************************************
4227 
4228 
4229 //*************************************************************************************************
4247 template< typename Type // Data type of the matrix
4248  , bool SO > // Storage order
4249 inline bool isDefault( const DynamicMatrix<Type,SO>& m )
4250 {
4251  if( SO == rowMajor ) {
4252  for( size_t i=0UL; i<m.rows(); ++i )
4253  for( size_t j=0UL; j<m.columns(); ++j )
4254  if( !isDefault( m(i,j) ) ) return false;
4255  }
4256  else {
4257  for( size_t j=0UL; j<m.columns(); ++j )
4258  for( size_t i=0UL; i<m.rows(); ++i )
4259  if( !isDefault( m(i,j) ) ) return false;
4260  }
4261 
4262  return true;
4263 }
4264 //*************************************************************************************************
4265 
4266 
4267 //*************************************************************************************************
4276 template< typename Type // Data type of the matrix
4277  , bool SO > // Storage order
4278 inline void swap( DynamicMatrix<Type,SO>& a, DynamicMatrix<Type,SO>& b ) /* throw() */
4279 {
4280  a.swap( b );
4281 }
4282 //*************************************************************************************************
4283 
4284 
4285 
4286 
4287 //=================================================================================================
4288 //
4289 // ISRESIZABLE SPECIALIZATIONS
4290 //
4291 //=================================================================================================
4292 
4293 //*************************************************************************************************
4295 template< typename T, bool SO >
4296 struct IsResizable< DynamicMatrix<T,SO> > : public TrueType
4297 {
4298  enum { value = 1 };
4299  typedef TrueType Type;
4300 };
4301 
4302 template< typename T, bool SO >
4303 struct IsResizable< const DynamicMatrix<T,SO> > : public TrueType
4304 {
4305  enum { value = 1 };
4306  typedef TrueType Type;
4307 };
4308 
4309 template< typename T, bool SO >
4310 struct IsResizable< volatile DynamicMatrix<T,SO> > : public TrueType
4311 {
4312  enum { value = 1 };
4313  typedef TrueType Type;
4314 };
4315 
4316 template< typename T, bool SO >
4317 struct IsResizable< const volatile DynamicMatrix<T,SO> > : public TrueType
4318 {
4319  enum { value = 1 };
4320  typedef TrueType Type;
4321 };
4323 //*************************************************************************************************
4324 
4325 
4326 
4327 
4328 //=================================================================================================
4329 //
4330 // ADDTRAIT SPECIALIZATIONS
4331 //
4332 //=================================================================================================
4333 
4334 //*************************************************************************************************
4336 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4337 struct AddTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4338 {
4339  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4340 };
4341 
4342 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4343 struct AddTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4344 {
4345  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4346 };
4347 
4348 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4349 struct AddTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
4350 {
4351  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, SO > Type;
4352 };
4353 
4354 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4355 struct AddTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
4356 {
4357  typedef StaticMatrix< typename AddTrait<T1,T2>::Type, M, N, false > Type;
4358 };
4359 
4360 template< typename T1, bool SO, typename T2 >
4361 struct AddTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4362 {
4363  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , SO > Type;
4364 };
4365 
4366 template< typename T1, bool SO1, typename T2, bool SO2 >
4367 struct AddTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4368 {
4369  typedef DynamicMatrix< typename AddTrait<T1,T2>::Type , false > Type;
4370 };
4372 //*************************************************************************************************
4373 
4374 
4375 
4376 
4377 //=================================================================================================
4378 //
4379 // SUBTRAIT SPECIALIZATIONS
4380 //
4381 //=================================================================================================
4382 
4383 //*************************************************************************************************
4385 template< typename T1, bool SO, typename T2, size_t M, size_t N >
4386 struct SubTrait< DynamicMatrix<T1,SO>, StaticMatrix<T2,M,N,SO> >
4387 {
4388  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4389 };
4390 
4391 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4392 struct SubTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4393 {
4394  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4395 };
4396 
4397 template< typename T1, size_t M, size_t N, bool SO, typename T2 >
4398 struct SubTrait< StaticMatrix<T1,M,N,SO>, DynamicMatrix<T2,SO> >
4399 {
4400  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, SO > Type;
4401 };
4402 
4403 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4404 struct SubTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
4405 {
4406  typedef StaticMatrix< typename SubTrait<T1,T2>::Type, M, N, false > Type;
4407 };
4408 
4409 template< typename T1, bool SO, typename T2 >
4410 struct SubTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4411 {
4412  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , SO > Type;
4413 };
4414 
4415 template< typename T1, bool SO1, typename T2, bool SO2 >
4416 struct SubTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4417 {
4418  typedef DynamicMatrix< typename SubTrait<T1,T2>::Type , false > Type;
4419 };
4421 //*************************************************************************************************
4422 
4423 
4424 
4425 
4426 //=================================================================================================
4427 //
4428 // MULTTRAIT SPECIALIZATIONS
4429 //
4430 //=================================================================================================
4431 
4432 //*************************************************************************************************
4434 template< typename T1, bool SO, typename T2 >
4435 struct MultTrait< DynamicMatrix<T1,SO>, T2 >
4436 {
4437  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4439 };
4440 
4441 template< typename T1, typename T2, bool SO >
4442 struct MultTrait< T1, DynamicMatrix<T2,SO> >
4443 {
4444  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO > Type;
4446 };
4447 
4448 template< typename T1, bool SO, typename T2, size_t N >
4449 struct MultTrait< DynamicMatrix<T1,SO>, StaticVector<T2,N,false> >
4450 {
4451  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4452 };
4453 
4454 template< typename T1, size_t N, typename T2, bool SO >
4455 struct MultTrait< StaticVector<T1,N,true>, DynamicMatrix<T2,SO> >
4456 {
4457  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4458 };
4459 
4460 template< typename T1, bool SO, typename T2 >
4461 struct MultTrait< DynamicMatrix<T1,SO>, DynamicVector<T2,false> >
4462 {
4463  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4464 };
4465 
4466 template< typename T1, typename T2, bool SO >
4467 struct MultTrait< DynamicVector<T1,true>, DynamicMatrix<T2,SO> >
4468 {
4469  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4470 };
4471 
4472 template< typename T1, bool SO, typename T2 >
4473 struct MultTrait< DynamicMatrix<T1,SO>, CompressedVector<T2,false> >
4474 {
4475  typedef DynamicVector< typename MultTrait<T1,T2>::Type, false > Type;
4476 };
4477 
4478 template< typename T1, typename T2, bool SO >
4479 struct MultTrait< CompressedVector<T1,true>, DynamicMatrix<T2,SO> >
4480 {
4481  typedef DynamicVector< typename MultTrait<T1,T2>::Type, true > Type;
4482 };
4483 
4484 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
4485 struct MultTrait< DynamicMatrix<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
4486 {
4487  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4488 };
4489 
4490 template< typename T1, size_t M, size_t N, bool SO1, typename T2, bool SO2 >
4491 struct MultTrait< StaticMatrix<T1,M,N,SO1>, DynamicMatrix<T2,SO2> >
4492 {
4493  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4494 };
4495 
4496 template< typename T1, bool SO1, typename T2, bool SO2 >
4497 struct MultTrait< DynamicMatrix<T1,SO1>, DynamicMatrix<T2,SO2> >
4498 {
4499  typedef DynamicMatrix< typename MultTrait<T1,T2>::Type, SO1 > Type;
4500 };
4502 //*************************************************************************************************
4503 
4504 
4505 
4506 
4507 //=================================================================================================
4508 //
4509 // DIVTRAIT SPECIALIZATIONS
4510 //
4511 //=================================================================================================
4512 
4513 //*************************************************************************************************
4515 template< typename T1, bool SO, typename T2 >
4516 struct DivTrait< DynamicMatrix<T1,SO>, T2 >
4517 {
4518  typedef DynamicMatrix< typename DivTrait<T1,T2>::Type , SO > Type;
4520 };
4522 //*************************************************************************************************
4523 
4524 
4525 
4526 
4527 //=================================================================================================
4528 //
4529 // MATHTRAIT SPECIALIZATIONS
4530 //
4531 //=================================================================================================
4532 
4533 //*************************************************************************************************
4535 template< typename T1, bool SO, typename T2 >
4536 struct MathTrait< DynamicMatrix<T1,SO>, DynamicMatrix<T2,SO> >
4537 {
4538  typedef DynamicMatrix< typename MathTrait<T1,T2>::HighType, SO > HighType;
4539  typedef DynamicMatrix< typename MathTrait<T1,T2>::LowType , SO > LowType;
4540 };
4542 //*************************************************************************************************
4543 
4544 
4545 
4546 
4547 //=================================================================================================
4548 //
4549 // ROWTRAIT SPECIALIZATIONS
4550 //
4551 //=================================================================================================
4552 
4553 //*************************************************************************************************
4555 template< typename T1, bool SO >
4556 struct RowTrait< DynamicMatrix<T1,SO> >
4557 {
4558  typedef DynamicVector<T1,true> Type;
4559 };
4561 //*************************************************************************************************
4562 
4563 
4564 
4565 
4566 //=================================================================================================
4567 //
4568 // COLUMNTRAIT SPECIALIZATIONS
4569 //
4570 //=================================================================================================
4571 
4572 //*************************************************************************************************
4574 template< typename T1, bool SO >
4575 struct ColumnTrait< DynamicMatrix<T1,SO> >
4576 {
4577  typedef DynamicVector<T1,false> Type;
4578 };
4580 //*************************************************************************************************
4581 
4582 } // namespace blaze
4583 
4584 #endif