All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DenseRow.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_VIEWS_DENSEROW_H_
23 #define _BLAZE_MATH_VIEWS_DENSEROW_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <iterator>
31 #include <stdexcept>
39 #include <blaze/math/Forward.h>
40 #include <blaze/math/Intrinsics.h>
41 #include <blaze/math/shims/Reset.h>
49 #include <blaze/util/Assert.h>
51 #include <blaze/util/DisableIf.h>
52 #include <blaze/util/EnableIf.h>
54 #include <blaze/util/Template.h>
55 #include <blaze/util/Types.h>
60 
61 
62 namespace blaze {
63 
64 //=================================================================================================
65 //
66 // CLASS DEFINITION
67 //
68 //=================================================================================================
69 
70 //*************************************************************************************************
277 template< typename MT // Type of the dense matrix
278  , bool SO = IsRowMajorMatrix<MT>::value > // Storage order
279 class DenseRow : public DenseVector< DenseRow<MT,SO>, true >
280  , private Expression
281 {
282  private:
283  //**Type definitions****************************************************************************
285  //**********************************************************************************************
286 
287  //**********************************************************************************************
289 
295  enum { useConst = IsConst<MT>::value };
296  //**********************************************************************************************
297 
298  public:
299  //**Type definitions****************************************************************************
301  typedef typename RowTrait<MT>::Type ResultType;
302  typedef typename ResultType::TransposeType TransposeType;
303  typedef typename MT::ElementType ElementType;
304  typedef typename IT::Type IntrinsicType;
305  typedef typename MT::ReturnType ReturnType;
306  typedef const DenseRow& CompositeType;
307 
309  typedef typename MT::ConstReference ConstReference;
310 
313 
315  typedef const ElementType* ConstPointer;
316 
319 
321  typedef typename MT::ConstIterator ConstIterator;
322 
325  //**********************************************************************************************
326 
327  //**Compilation flags***************************************************************************
329  enum { vectorizable = MT::vectorizable };
330  //**********************************************************************************************
331 
332  //**Constructors********************************************************************************
335  explicit inline DenseRow( MT& matrix, size_t index );
336  // No explicitly declared copy constructor.
338  //**********************************************************************************************
339 
340  //**Destructor**********************************************************************************
341  // No explicitly declared destructor.
342  //**********************************************************************************************
343 
344  //**Data access functions***********************************************************************
347  inline Reference operator[]( size_t index );
348  inline ConstReference operator[]( size_t index ) const;
349  inline Pointer data ();
350  inline ConstPointer data () const;
351  inline Iterator begin ();
352  inline ConstIterator begin () const;
353  inline ConstIterator cbegin() const;
354  inline Iterator end ();
355  inline ConstIterator end () const;
356  inline ConstIterator cend () const;
358  //**********************************************************************************************
359 
360  //**Assignment operators************************************************************************
363  inline DenseRow& operator= ( const ElementType& rhs );
364  inline DenseRow& operator= ( const DenseRow& rhs );
365  template< typename VT > inline DenseRow& operator= ( const Vector<VT,true>& rhs );
366  template< typename VT > inline DenseRow& operator+=( const Vector<VT,true>& rhs );
367  template< typename VT > inline DenseRow& operator-=( const Vector<VT,true>& rhs );
368  template< typename VT > inline DenseRow& operator*=( const Vector<VT,true>& rhs );
369 
370  template< typename Other >
371  inline typename EnableIf< IsNumeric<Other>, DenseRow >::Type&
372  operator*=( Other rhs );
373 
374  template< typename Other >
375  inline typename EnableIf< IsNumeric<Other>, DenseRow >::Type&
376  operator/=( Other rhs );
378  //**********************************************************************************************
379 
380  //**Utility functions***************************************************************************
383  inline size_t size() const;
384  inline size_t capacity() const;
385  inline size_t nonZeros() const;
386  inline void reset();
387  template< typename Other > inline DenseRow& scale( const Other& scalar );
389  //**********************************************************************************************
390 
391  private:
392  //**********************************************************************************************
394 
395  template< typename VT >
396  struct VectorizedAssign {
397  enum { value = vectorizable && VT::vectorizable &&
399  };
401  //**********************************************************************************************
402 
403  //**********************************************************************************************
405 
406  template< typename VT >
407  struct VectorizedAddAssign {
408  enum { value = vectorizable && VT::vectorizable &&
409  IsSame<ElementType,typename VT::ElementType>::value &&
410  IntrinsicTrait<ElementType>::addition };
411  };
413  //**********************************************************************************************
414 
415  //**********************************************************************************************
417 
418  template< typename VT >
419  struct VectorizedSubAssign {
420  enum { value = vectorizable && VT::vectorizable &&
421  IsSame<ElementType,typename VT::ElementType>::value &&
422  IntrinsicTrait<ElementType>::subtraction };
423  };
425  //**********************************************************************************************
426 
427  //**********************************************************************************************
429 
430  template< typename VT >
431  struct VectorizedMultAssign {
432  enum { value = vectorizable && VT::vectorizable &&
433  IsSame<ElementType,typename VT::ElementType>::value &&
434  IntrinsicTrait<ElementType>::multiplication };
435  };
437  //**********************************************************************************************
438 
439  public:
440  //**Expression template evaluation functions****************************************************
443  template< typename Other > inline bool canAlias ( const Other* alias ) const;
444  template< typename Other > inline bool isAliased( const Other* alias ) const;
445  inline IntrinsicType get ( size_t index ) const;
446 
447  template< typename VT >
448  inline typename DisableIf< VectorizedAssign<VT> >::Type
449  assign( const DenseVector<VT,true>& rhs );
450 
451  template< typename VT >
452  inline typename EnableIf< VectorizedAssign<VT> >::Type
453  assign( const DenseVector<VT,true>& rhs );
454 
455  template< typename VT > inline void assign( const SparseVector<VT,true>& rhs );
456 
457  template< typename VT >
458  inline typename DisableIf< VectorizedAddAssign<VT> >::Type
459  addAssign( const DenseVector<VT,true>& rhs );
460 
461  template< typename VT >
462  inline typename EnableIf< VectorizedAddAssign<VT> >::Type
463  addAssign( const DenseVector<VT,true>& rhs );
464 
465  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
466 
467  template< typename VT >
468  inline typename DisableIf< VectorizedSubAssign<VT> >::Type
469  subAssign( const DenseVector<VT,true>& rhs );
470 
471  template< typename VT >
472  inline typename EnableIf< VectorizedSubAssign<VT> >::Type
473  subAssign( const DenseVector<VT,true>& rhs );
474 
475  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
476 
477  template< typename VT >
478  inline typename DisableIf< VectorizedMultAssign<VT> >::Type
479  multAssign( const DenseVector<VT,true>& rhs );
480 
481  template< typename VT >
482  inline typename EnableIf< VectorizedMultAssign<VT> >::Type
483  multAssign( const DenseVector<VT,true>& rhs );
484 
485  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
487  //**********************************************************************************************
488 
489  private:
490  //**Member variables****************************************************************************
493  MT& matrix_;
494  const size_t row_;
495 
496  //**********************************************************************************************
497 
498  //**Compile time checks*************************************************************************
504  //**********************************************************************************************
505 };
506 //*************************************************************************************************
507 
508 
509 
510 
511 //=================================================================================================
512 //
513 // CONSTRUCTOR
514 //
515 //=================================================================================================
516 
517 //*************************************************************************************************
524 template< typename MT // Type of the dense matrix
525  , bool SO > // Storage order
526 inline DenseRow<MT,SO>::DenseRow( MT& matrix, size_t index )
527  : matrix_( matrix ) // The dense matrix containing the row
528  , row_ ( index ) // The index of the row in the matrix
529 {
530  if( matrix_.rows() <= index )
531  throw std::invalid_argument( "Invalid row access index" );
532 }
533 //*************************************************************************************************
534 
535 
536 
537 
538 //=================================================================================================
539 //
540 // DATA ACCESS FUNCTIONS
541 //
542 //=================================================================================================
543 
544 //*************************************************************************************************
550 template< typename MT // Type of the dense matrix
551  , bool SO > // Storage order
553 {
554  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
555  return matrix_(row_,index);
556 }
557 //*************************************************************************************************
558 
559 
560 //*************************************************************************************************
566 template< typename MT // Type of the dense matrix
567  , bool SO > // Storage order
569 {
570  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
571  return matrix_(row_,index);
572 }
573 //*************************************************************************************************
574 
575 
576 //*************************************************************************************************
581 template< typename MT // Type of the dense matrix
582  , bool SO > // Storage order
584 {
585  return matrix_.data( row_ );
586 }
587 //*************************************************************************************************
588 
589 
590 //*************************************************************************************************
595 template< typename MT // Type of the dense matrix
596  , bool SO > // Storage order
598 {
599  return matrix_.data( row_ );
600 }
601 //*************************************************************************************************
602 
603 
604 //*************************************************************************************************
611 template< typename MT // Type of the dense matrix
612  , bool SO > // Storage order
614 {
615  return matrix_.begin( row_ );
616 }
617 //*************************************************************************************************
618 
619 
620 //*************************************************************************************************
627 template< typename MT // Type of the dense matrix
628  , bool SO > // Storage order
630 {
631  return matrix_.begin( row_ );
632 }
633 //*************************************************************************************************
634 
635 
636 //*************************************************************************************************
643 template< typename MT // Type of the dense matrix
644  , bool SO > // Storage order
646 {
647  return matrix_.begin( row_ );
648 }
649 //*************************************************************************************************
650 
651 
652 //*************************************************************************************************
659 template< typename MT // Type of the dense matrix
660  , bool SO > // Storage order
662 {
663  return matrix_.end( row_ );
664 }
665 //*************************************************************************************************
666 
667 
668 //*************************************************************************************************
675 template< typename MT // Type of the dense matrix
676  , bool SO > // Storage order
678 {
679  return matrix_.end( row_ );
680 }
681 //*************************************************************************************************
682 
683 
684 //*************************************************************************************************
691 template< typename MT // Type of the dense matrix
692  , bool SO > // Storage order
694 {
695  return matrix_.end( row_ );
696 }
697 //*************************************************************************************************
698 
699 
700 
701 
702 //=================================================================================================
703 //
704 // ASSIGNMENT OPERATORS
705 //
706 //=================================================================================================
707 
708 //*************************************************************************************************
714 template< typename MT // Type of the dense matrix
715  , bool SO > // Storage order
717 {
718  const size_t columns( size() );
719 
720  for( size_t j=0UL; j<columns; ++j )
721  matrix_(row_,j) = rhs;
722 
723  return *this;
724 }
725 //*************************************************************************************************
726 
727 
728 //*************************************************************************************************
738 template< typename MT // Type of the dense matrix
739  , bool SO > // Storage order
741 {
742  if( &rhs == this ) return *this;
743 
744  if( size() != rhs.size() )
745  throw std::invalid_argument( "Row sizes do not match" );
746 
747  const size_t columns( size() );
748 
749  for( size_t j=0UL; j<columns; ++j )
750  matrix_(row_,j) = rhs[j];
751 
752  return *this;
753 }
754 //*************************************************************************************************
755 
756 
757 //*************************************************************************************************
767 template< typename MT // Type of the dense matrix
768  , bool SO > // Storage order
769 template< typename VT > // Type of the right-hand side vector
771 {
772  using blaze::assign;
773 
774  BLAZE_CONSTRAINT_MUST_BE_TRANSPOSE_VECTOR_TYPE( typename VT::ResultType );
775  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION ( typename VT::ResultType );
776 
777  if( size() != (~rhs).size() )
778  throw std::invalid_argument( "Vector sizes do not match" );
779 
780  if( (~rhs).canAlias( &matrix_ ) ) {
781  const typename VT::ResultType tmp( ~rhs );
782  assign( *this, tmp );
783  }
784  else {
786  reset();
787  assign( *this, ~rhs );
788  }
789 
790  return *this;
791 }
792 //*************************************************************************************************
793 
794 
795 //*************************************************************************************************
805 template< typename MT // Type of the dense matrix
806  , bool SO > // Storage order
807 template< typename VT > // Type of the right-hand side vector
809 {
810  using blaze::addAssign;
811 
812  BLAZE_CONSTRAINT_MUST_BE_TRANSPOSE_VECTOR_TYPE( typename VT::ResultType );
813  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION ( typename VT::ResultType );
814 
815  if( size() != (~rhs).size() )
816  throw std::invalid_argument( "Vector sizes do not match" );
817 
818  if( (~rhs).canAlias( &matrix_ ) ) {
819  const typename VT::ResultType tmp( ~rhs );
820  addAssign( *this, tmp );
821  }
822  else {
823  addAssign( *this, ~rhs );
824  }
825 
826  return *this;
827 }
828 //*************************************************************************************************
829 
830 
831 //*************************************************************************************************
841 template< typename MT // Type of the dense matrix
842  , bool SO > // Storage order
843 template< typename VT > // Type of the right-hand side vector
845 {
846  using blaze::subAssign;
847 
848  BLAZE_CONSTRAINT_MUST_BE_TRANSPOSE_VECTOR_TYPE( typename VT::ResultType );
849  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION ( typename VT::ResultType );
850 
851  if( size() != (~rhs).size() )
852  throw std::invalid_argument( "Vector sizes do not match" );
853 
854  if( (~rhs).canAlias( &matrix_ ) ) {
855  const typename VT::ResultType tmp( ~rhs );
856  subAssign( *this, tmp );
857  }
858  else {
859  subAssign( *this, ~rhs );
860  }
861 
862  return *this;
863 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
878 template< typename MT // Type of the dense matrix
879  , bool SO > // Storage order
880 template< typename VT > // Type of the right-hand side vector
882 {
883  using blaze::multAssign;
884 
885  BLAZE_CONSTRAINT_MUST_BE_TRANSPOSE_VECTOR_TYPE( typename VT::ResultType );
886  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION ( typename VT::ResultType );
887 
888  if( size() != (~rhs).size() )
889  throw std::invalid_argument( "Vector sizes do not match" );
890 
891  if( (~rhs).canAlias( &matrix_ ) || IsSparseVector<VT>::value ) {
892  const typename VT::ResultType tmp( ~rhs );
893  multAssign( *this, tmp );
894  }
895  else {
896  multAssign( *this, ~rhs );
897  }
898 
899  return *this;
900 }
901 //*************************************************************************************************
902 
903 
904 //*************************************************************************************************
911 template< typename MT // Type of the dense matrix
912  , bool SO > // Storage order
913 template< typename Other > // Data type of the right-hand side scalar
914 inline typename EnableIf< IsNumeric<Other>, DenseRow<MT,SO> >::Type&
916 {
917  return operator=( (*this) * rhs );
918 }
919 //*************************************************************************************************
920 
921 
922 //*************************************************************************************************
931 template< typename MT // Type of the dense matrix
932  , bool SO > // Storage order
933 template< typename Other > // Data type of the right-hand side scalar
934 inline typename EnableIf< IsNumeric<Other>, DenseRow<MT,SO> >::Type&
936 {
937  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
938 
939  return operator=( (*this) / rhs );
940 }
941 //*************************************************************************************************
942 
943 
944 
945 
946 //=================================================================================================
947 //
948 // UTILITY FUNCTIONS
949 //
950 //=================================================================================================
951 
952 //*************************************************************************************************
957 template< typename MT // Type of the dense matrix
958  , bool SO > // Storage order
959 inline size_t DenseRow<MT,SO>::size() const
960 {
961  return matrix_.columns();
962 }
963 //*************************************************************************************************
964 
965 
966 //*************************************************************************************************
971 template< typename MT // Type of the dense matrix
972  , bool SO > // Storage order
973 inline size_t DenseRow<MT,SO>::capacity() const
974 {
975  return matrix_.capacity( row_ );
976 }
977 //*************************************************************************************************
978 
979 
980 //*************************************************************************************************
988 template< typename MT // Type of the dense matrix
989  , bool SO > // Storage order
990 inline size_t DenseRow<MT,SO>::nonZeros() const
991 {
992  return matrix_.nonZeros( row_ );
993 }
994 //*************************************************************************************************
995 
996 
997 //*************************************************************************************************
1002 template< typename MT // Type of the dense matrix
1003  , bool SO > // Storage order
1005 {
1006  matrix_.reset( row_ );
1007 }
1008 //*************************************************************************************************
1009 
1010 
1011 //*************************************************************************************************
1017 template< typename MT // Type of the dense matrix
1018  , bool SO > // Storage order
1019 template< typename Other > // Data type of the scalar value
1020 inline DenseRow<MT,SO>& DenseRow<MT,SO>::scale( const Other& scalar )
1021 {
1022  for( size_t j=0UL; j<size(); ++j ) {
1023  matrix_(row_,j) *= scalar;
1024  }
1025  return *this;
1026 }
1027 //*************************************************************************************************
1028 
1029 
1030 
1031 
1032 //=================================================================================================
1033 //
1034 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1035 //
1036 //=================================================================================================
1037 
1038 //*************************************************************************************************
1048 template< typename MT // Type of the dense matrix
1049  , bool SO > // Storage order
1050 template< typename Other > // Data type of the foreign expression
1051 inline bool DenseRow<MT,SO>::canAlias( const Other* alias ) const
1052 {
1053  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1054 }
1055 //*************************************************************************************************
1056 
1057 
1058 //*************************************************************************************************
1068 template< typename MT // Type of the dense matrix
1069  , bool SO > // Storage order
1070 template< typename Other > // Data type of the foreign expression
1071 inline bool DenseRow<MT,SO>::isAliased( const Other* alias ) const
1072 {
1073  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1074 }
1075 //*************************************************************************************************
1076 
1077 
1078 //*************************************************************************************************
1089 template< typename MT // Type of the dense matrix
1090  , bool SO > // Storage order
1091 inline typename DenseRow<MT,SO>::IntrinsicType DenseRow<MT,SO>::get( size_t index ) const
1092 {
1093  return matrix_.get( row_, index );
1094 }
1095 //*************************************************************************************************
1096 
1097 
1098 //*************************************************************************************************
1109 template< typename MT // Type of the dense matrix
1110  , bool SO > // Storage order
1111 template< typename VT > // Type of the right-hand side dense vector
1112 inline typename DisableIf< typename DenseRow<MT,SO>::BLAZE_TEMPLATE VectorizedAssign<VT> >::Type
1114 {
1115  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1116 
1117  const size_t jend( (~rhs).size() & size_t(-2) );
1118  for( size_t j=0UL; j<jend; j+=2UL ) {
1119  matrix_(row_,j ) = (~rhs)[j ];
1120  matrix_(row_,j+1UL) = (~rhs)[j+1UL];
1121  }
1122  if( jend < (~rhs).size() )
1123  matrix_(row_,jend) = (~rhs)[jend];
1124 }
1125 //*************************************************************************************************
1126 
1127 
1128 //*************************************************************************************************
1139 template< typename MT // Type of the dense matrix
1140  , bool SO > // Storage order
1141 template< typename VT > // Type of the right-hand side dense vector
1142 inline typename EnableIf< typename DenseRow<MT,SO>::BLAZE_TEMPLATE VectorizedAssign<VT> >::Type
1144 {
1145  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1146 
1148 
1149  const size_t columns( size() );
1150 
1151  if( columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( &matrix_ ) )
1152  {
1153  for( size_t j=0UL; j<columns; j+=IT::size ) {
1154  stream( &matrix_(row_,j), (~rhs).get(j) );
1155  }
1156  }
1157  else
1158  {
1159  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (IT::size*4UL) ) ) == ( columns & size_t(-IT::size*4) ), "Invalid end calculation" );
1160  const size_t jend( columns & size_t(-IT::size*4) );
1161 
1162  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1163  store( &matrix_(row_,j ), (~rhs).get(j ) );
1164  store( &matrix_(row_,j+IT::size ), (~rhs).get(j+IT::size ) );
1165  store( &matrix_(row_,j+IT::size*2UL), (~rhs).get(j+IT::size*2UL) );
1166  store( &matrix_(row_,j+IT::size*3UL), (~rhs).get(j+IT::size*3UL) );
1167  }
1168  for( size_t j=jend; j<columns; j+=IT::size ) {
1169  store( &matrix_(row_,j), (~rhs).get(j) );
1170  }
1171  }
1172 }
1173 //*************************************************************************************************
1174 
1175 
1176 //*************************************************************************************************
1187 template< typename MT // Type of the dense matrix
1188  , bool SO > // Storage order
1189 template< typename VT > // Type of the right-hand side sparse vector
1191 {
1192  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1193 
1194  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1195  matrix_(row_,element->index()) = element->value();
1196 }
1197 //*************************************************************************************************
1198 
1199 
1200 //*************************************************************************************************
1211 template< typename MT // Type of the dense matrix
1212  , bool SO > // Storage order
1213 template< typename VT > // Type of the right-hand side dense vector
1214 inline typename DisableIf< typename DenseRow<MT,SO>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >::Type
1216 {
1217  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1218 
1219  const size_t jend( (~rhs).size() & size_t(-2) );
1220  for( size_t j=0UL; j<jend; j+=2UL ) {
1221  matrix_(row_,j ) += (~rhs)[j ];
1222  matrix_(row_,j+1UL) += (~rhs)[j+1UL];
1223  }
1224  if( jend < (~rhs).size() )
1225  matrix_(row_,jend) += (~rhs)[jend];
1226 }
1227 //*************************************************************************************************
1228 
1229 
1230 //*************************************************************************************************
1241 template< typename MT // Type of the dense matrix
1242  , bool SO > // Storage order
1243 template< typename VT > // Type of the right-hand side dense vector
1244 inline typename EnableIf< typename DenseRow<MT,SO>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >::Type
1246 {
1247  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1248 
1250 
1251  const size_t columns( size() );
1252 
1253  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (IT::size*4UL) ) ) == ( columns & size_t(-IT::size*4) ), "Invalid end calculation" );
1254  const size_t jend( columns & size_t(-IT::size*4) );
1255 
1256  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1257  store( &matrix_(row_,j ), load( &matrix_(row_,j ) ) + (~rhs).get(j ) );
1258  store( &matrix_(row_,j+IT::size ), load( &matrix_(row_,j+IT::size ) ) + (~rhs).get(j+IT::size ) );
1259  store( &matrix_(row_,j+IT::size*2UL), load( &matrix_(row_,j+IT::size*2UL) ) + (~rhs).get(j+IT::size*2UL) );
1260  store( &matrix_(row_,j+IT::size*3UL), load( &matrix_(row_,j+IT::size*3UL) ) + (~rhs).get(j+IT::size*3UL) );
1261  }
1262  for( size_t j=jend; j<columns; j+=IT::size ) {
1263  store( &matrix_(row_,j), load( &matrix_(row_,j) ) + (~rhs).get(j) );
1264  }
1265 }
1266 //*************************************************************************************************
1267 
1268 
1269 //*************************************************************************************************
1280 template< typename MT // Type of the dense matrix
1281  , bool SO > // Storage order
1282 template< typename VT > // Type of the right-hand side sparse vector
1284 {
1285  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1286 
1287  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1288  matrix_(row_,element->index()) += element->value();
1289 }
1290 //*************************************************************************************************
1291 
1292 
1293 //*************************************************************************************************
1304 template< typename MT // Type of the dense matrix
1305  , bool SO > // Storage order
1306 template< typename VT > // Type of the right-hand side dense vector
1307 inline typename DisableIf< typename DenseRow<MT,SO>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >::Type
1309 {
1310  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1311 
1312  const size_t jend( (~rhs).size() & size_t(-2) );
1313  for( size_t j=0UL; j<jend; j+=2UL ) {
1314  matrix_(row_,j ) -= (~rhs)[j ];
1315  matrix_(row_,j+1UL) -= (~rhs)[j+1UL];
1316  }
1317  if( jend < (~rhs).size() )
1318  matrix_(row_,jend) -= (~rhs)[jend];
1319 }
1320 //*************************************************************************************************
1321 
1322 
1323 //*************************************************************************************************
1334 template< typename MT // Type of the dense matrix
1335  , bool SO > // Storage order
1336 template< typename VT > // Type of the right-hand side dense vector
1337 inline typename EnableIf< typename DenseRow<MT,SO>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >::Type
1339 {
1340  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1341 
1343 
1344  const size_t columns( size() );
1345 
1346  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (IT::size*4UL) ) ) == ( columns & size_t(-IT::size*4) ), "Invalid end calculation" );
1347  const size_t jend( columns & size_t(-IT::size*4) );
1348 
1349  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1350  store( &matrix_(row_,j ), load( &matrix_(row_,j ) ) - (~rhs).get(j ) );
1351  store( &matrix_(row_,j+IT::size ), load( &matrix_(row_,j+IT::size ) ) - (~rhs).get(j+IT::size ) );
1352  store( &matrix_(row_,j+IT::size*2UL), load( &matrix_(row_,j+IT::size*2UL) ) - (~rhs).get(j+IT::size*2UL) );
1353  store( &matrix_(row_,j+IT::size*3UL), load( &matrix_(row_,j+IT::size*3UL) ) - (~rhs).get(j+IT::size*3UL) );
1354  }
1355  for( size_t j=jend; j<columns; j+=IT::size ) {
1356  store( &matrix_(row_,j), load( &matrix_(row_,j) ) - (~rhs).get(j) );
1357  }
1358 }
1359 //*************************************************************************************************
1360 
1361 
1362 //*************************************************************************************************
1373 template< typename MT // Type of the dense matrix
1374  , bool SO > // Storage order
1375 template< typename VT > // Type of the right-hand side sparse vector
1377 {
1378  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1379 
1380  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1381  matrix_(row_,element->index()) -= element->value();
1382 }
1383 //*************************************************************************************************
1384 
1385 
1386 //*************************************************************************************************
1397 template< typename MT // Type of the dense matrix
1398  , bool SO > // Storage order
1399 template< typename VT > // Type of the right-hand side dense vector
1400 inline typename DisableIf< typename DenseRow<MT,SO>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >::Type
1402 {
1403  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1404 
1405  const size_t jend( (~rhs).size() & size_t(-2) );
1406  for( size_t j=0UL; j<jend; j+=2UL ) {
1407  matrix_(row_,j ) *= (~rhs)[j ];
1408  matrix_(row_,j+1UL) *= (~rhs)[j+1UL];
1409  }
1410  if( jend < (~rhs).size() )
1411  matrix_(row_,jend) *= (~rhs)[jend];
1412 }
1413 //*************************************************************************************************
1414 
1415 
1416 //*************************************************************************************************
1427 template< typename MT // Type of the dense matrix
1428  , bool SO > // Storage order
1429 template< typename VT > // Type of the right-hand side dense vector
1430 inline typename EnableIf< typename DenseRow<MT,SO>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >::Type
1432 {
1433  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1434 
1436 
1437  const size_t columns( size() );
1438 
1439  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (IT::size*4UL) ) ) == ( columns & size_t(-IT::size*4) ), "Invalid end calculation" );
1440  const size_t jend( columns & size_t(-IT::size*4) );
1441 
1442  for( size_t j=0UL; j<jend; j+=IT::size*4UL ) {
1443  store( &matrix_(row_,j ), load( &matrix_(row_,j ) ) * (~rhs).get(j ) );
1444  store( &matrix_(row_,j+IT::size ), load( &matrix_(row_,j+IT::size ) ) * (~rhs).get(j+IT::size ) );
1445  store( &matrix_(row_,j+IT::size*2UL), load( &matrix_(row_,j+IT::size*2UL) ) * (~rhs).get(j+IT::size*2UL) );
1446  store( &matrix_(row_,j+IT::size*3UL), load( &matrix_(row_,j+IT::size*3UL) ) * (~rhs).get(j+IT::size*3UL) );
1447  }
1448  for( size_t j=jend; j<columns; j+=IT::size ) {
1449  store( &matrix_(row_,j), load( &matrix_(row_,j) ) * (~rhs).get(j) );
1450  }
1451 }
1452 //*************************************************************************************************
1453 
1454 
1455 //*************************************************************************************************
1466 template< typename MT // Type of the dense matrix
1467  , bool SO > // Storage order
1468 template< typename VT > // Type of the right-hand side sparse vector
1470 {
1471  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1472 
1473  const ResultType tmp( *this );
1474 
1475  reset();
1476 
1477  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1478  matrix_(row_,element->index()) = tmp[element->index()] * element->value();
1479 }
1480 //*************************************************************************************************
1481 
1482 
1483 
1484 
1485 
1486 
1487 
1488 
1489 //=================================================================================================
1490 //
1491 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
1492 //
1493 //=================================================================================================
1494 
1495 //*************************************************************************************************
1503 template< typename MT > // Type of the dense matrix
1504 class DenseRow<MT,false> : public DenseVector< DenseRow<MT,false>, true >
1505  , private Expression
1506 {
1507  private:
1508  //**********************************************************************************************
1510 
1516  enum { useConst = IsConst<MT>::value };
1517  //**********************************************************************************************
1518 
1519  public:
1520  //**Type definitions****************************************************************************
1521  typedef DenseRow<MT,false> This;
1522  typedef typename RowTrait<MT>::Type ResultType;
1523  typedef typename ResultType::TransposeType TransposeType;
1524  typedef typename MT::ElementType ElementType;
1525  typedef typename MT::ReturnType ReturnType;
1526  typedef const ResultType CompositeType;
1527 
1529  typedef typename MT::ConstReference ConstReference;
1530 
1532  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
1533  //**********************************************************************************************
1534 
1535  //**RowIterator class definition****************************************************************
1538  template< typename MatrixType > // Type of the dense matrix
1539  class RowIterator
1540  {
1541  private:
1542  //*******************************************************************************************
1544 
1549  enum { returnConst = IsConst<MatrixType>::value };
1550  //*******************************************************************************************
1551 
1552  public:
1553  //**Type definitions*************************************************************************
1555  typedef typename SelectType< returnConst, typename MT::ConstReference, typename MT::Reference >::Type Reference;
1556 
1557  typedef std::forward_iterator_tag IteratorCategory;
1558  typedef RemoveReference<Reference> ValueType;
1559  typedef ValueType* PointerType;
1560  typedef Reference ReferenceType;
1561  typedef ptrdiff_t DifferenceType;
1562 
1563  // STL iterator requirements
1564  typedef IteratorCategory iterator_category;
1565  typedef ValueType value_type;
1566  typedef PointerType pointer;
1567  typedef ReferenceType reference;
1568  typedef DifferenceType difference_type;
1569  //*******************************************************************************************
1570 
1571  //**Constructor******************************************************************************
1578  inline RowIterator( MatrixType& matrix, size_t row, size_t column )
1579  : matrix_( matrix ) // The dense matrix containing the row.
1580  , row_ ( row ) // The current row index.
1581  , column_( column ) // The current column index.
1582  {}
1583  //*******************************************************************************************
1584 
1585  //**Constructor******************************************************************************
1590  template< typename MatrixType2 >
1591  inline RowIterator( const RowIterator<MatrixType2>& it )
1592  : matrix_( it.matrix_ ) // The dense matrix containing the row.
1593  , row_ ( it.row_ ) // The current row index.
1594  , column_( it.column_ ) // The current column index.
1595  {}
1596  //*******************************************************************************************
1597 
1598  //**Prefix increment operator****************************************************************
1603  inline RowIterator& operator++() {
1604  ++column_;
1605  return *this;
1606  }
1607  //*******************************************************************************************
1608 
1609  //**Postfix increment operator***************************************************************
1614  inline const RowIterator operator++( int ) {
1615  const RowIterator tmp( *this );
1616  ++(*this);
1617  return tmp;
1618  }
1619  //*******************************************************************************************
1620 
1621  //**Element access operator******************************************************************
1626  inline ReferenceType operator*() const {
1627  return matrix_(row_,column_);
1628  }
1629  //*******************************************************************************************
1630 
1631  //**Element access operator******************************************************************
1636  inline PointerType operator->() const {
1637  return &matrix_(row_,column_);
1638  }
1639  //*******************************************************************************************
1640 
1641  //**Equality operator************************************************************************
1647  template< typename MatrixType2 >
1648  inline bool operator==( const RowIterator<MatrixType2>& rhs ) const {
1649  return ( &matrix_ == &rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
1650  }
1651  //*******************************************************************************************
1652 
1653  //**Inequality operator**********************************************************************
1659  template< typename MatrixType2 >
1660  inline bool operator!=( const RowIterator<MatrixType2>& rhs ) const {
1661  return !( *this == rhs );
1662  }
1663  //*******************************************************************************************
1664 
1665  //**Subtraction operator*********************************************************************
1671  inline DifferenceType operator-( const RowIterator& rhs ) const {
1672  return column_ - rhs.column_;
1673  }
1674  //*******************************************************************************************
1675 
1676  private:
1677  //**Member variables*************************************************************************
1678  MatrixType& matrix_;
1679  size_t row_;
1680  size_t column_;
1681  //*******************************************************************************************
1682 
1683  //**Friend declarations**********************************************************************
1685  template< typename MatrixType2 > friend class RowIterator;
1687  //*******************************************************************************************
1688  };
1689  //**********************************************************************************************
1690 
1691  //**Type definitions****************************************************************************
1693  typedef RowIterator<const MT> ConstIterator;
1694 
1696  typedef typename SelectType< useConst, ConstIterator, RowIterator<MT> >::Type Iterator;
1697  //**********************************************************************************************
1698 
1699  //**Compilation flags***************************************************************************
1701  enum { vectorizable = 0 };
1702  //**********************************************************************************************
1703 
1704  //**Constructors********************************************************************************
1707  explicit inline DenseRow( MT& matrix, size_t index );
1708  // No explicitly declared copy constructor.
1710  //**********************************************************************************************
1711 
1712  //**Destructor**********************************************************************************
1713  // No explicitly declared destructor.
1714  //**********************************************************************************************
1715 
1716  //**Data access functions***********************************************************************
1719  inline Reference operator[]( size_t index );
1720  inline ConstReference operator[]( size_t index ) const;
1721  inline Iterator begin ();
1722  inline ConstIterator begin () const;
1723  inline ConstIterator cbegin() const;
1724  inline Iterator end ();
1725  inline ConstIterator end () const;
1726  inline ConstIterator cend () const;
1728  //**********************************************************************************************
1729 
1730  //**Assignment operators************************************************************************
1733  inline DenseRow& operator= ( const ElementType& rhs );
1734  inline DenseRow& operator= ( const DenseRow& rhs );
1735  template< typename VT > inline DenseRow& operator= ( const Vector<VT,true>& rhs );
1736  template< typename VT > inline DenseRow& operator+=( const Vector<VT,true>& rhs );
1737  template< typename VT > inline DenseRow& operator-=( const Vector<VT,true>& rhs );
1738  template< typename VT > inline DenseRow& operator*=( const Vector<VT,true>& rhs );
1739 
1740  template< typename Other >
1741  inline typename EnableIf< IsNumeric<Other>, DenseRow >::Type&
1742  operator*=( Other rhs );
1743 
1744  template< typename Other >
1745  inline typename EnableIf< IsNumeric<Other>, DenseRow >::Type&
1746  operator/=( Other rhs );
1748  //**********************************************************************************************
1749 
1750  //**Utility functions***************************************************************************
1753  inline size_t size() const;
1754  inline size_t capacity() const;
1755  inline size_t nonZeros() const;
1756  inline void reset();
1757  template< typename Other > inline DenseRow& scale( const Other& scalar );
1759  //**********************************************************************************************
1760 
1761  public:
1762  //**Expression template evaluation functions****************************************************
1765  template< typename Other > inline bool canAlias ( const Other* alias ) const;
1766  template< typename Other > inline bool isAliased ( const Other* alias ) const;
1767  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
1768  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
1769  template< typename VT > inline void addAssign ( const DenseVector <VT,true>& rhs );
1770  template< typename VT > inline void addAssign ( const SparseVector<VT,true>& rhs );
1771  template< typename VT > inline void subAssign ( const DenseVector <VT,true>& rhs );
1772  template< typename VT > inline void subAssign ( const SparseVector<VT,true>& rhs );
1773  template< typename VT > inline void multAssign( const DenseVector <VT,true>& rhs );
1774  template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
1776  //**********************************************************************************************
1777 
1778  private:
1779  //**Member variables****************************************************************************
1782  MT& matrix_;
1783  const size_t row_;
1784 
1785  //**********************************************************************************************
1786 
1787  //**Compile time checks*************************************************************************
1793  //**********************************************************************************************
1794 };
1796 //*************************************************************************************************
1797 
1798 
1799 
1800 
1801 //=================================================================================================
1802 //
1803 // CONSTRUCTOR
1804 //
1805 //=================================================================================================
1806 
1807 //*************************************************************************************************
1815 template< typename MT > // Type of the dense matrix
1816 inline DenseRow<MT,false>::DenseRow( MT& matrix, size_t index )
1817  : matrix_( matrix ) // The dense matrix containing the row
1818  , row_ ( index ) // The index of the row in the matrix
1819 {
1820  if( matrix_.rows() <= index )
1821  throw std::invalid_argument( "Invalid row access index" );
1822 }
1824 //*************************************************************************************************
1825 
1826 
1827 
1828 
1829 //=================================================================================================
1830 //
1831 // DATA ACCESS FUNCTIONS
1832 //
1833 //=================================================================================================
1834 
1835 //*************************************************************************************************
1842 template< typename MT > // Type of the dense matrix
1843 inline typename DenseRow<MT,false>::Reference DenseRow<MT,false>::operator[]( size_t index )
1844 {
1845  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
1846  return matrix_(row_,index);
1847 }
1849 //*************************************************************************************************
1850 
1851 
1852 //*************************************************************************************************
1859 template< typename MT > // Type of the dense matrix
1860 inline typename DenseRow<MT,false>::ConstReference DenseRow<MT,false>::operator[]( size_t index ) const
1861 {
1862  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
1863  return matrix_(row_,index);
1864 }
1866 //*************************************************************************************************
1867 
1868 
1869 //*************************************************************************************************
1877 template< typename MT > // Type of the dense matrix
1878 inline typename DenseRow<MT,false>::Iterator DenseRow<MT,false>::begin()
1879 {
1880  return Iterator( matrix_, row_, 0UL );
1881 }
1883 //*************************************************************************************************
1884 
1885 
1886 //*************************************************************************************************
1894 template< typename MT > // Type of the dense matrix
1895 inline typename DenseRow<MT,false>::ConstIterator DenseRow<MT,false>::begin() const
1896 {
1897  return ConstIterator( matrix_, row_, 0UL );
1898 }
1900 //*************************************************************************************************
1901 
1902 
1903 //*************************************************************************************************
1911 template< typename MT > // Type of the dense matrix
1912 inline typename DenseRow<MT,false>::ConstIterator DenseRow<MT,false>::cbegin() const
1913 {
1914  return ConstIterator( matrix_, row_, 0UL );
1915 }
1917 //*************************************************************************************************
1918 
1919 
1920 //*************************************************************************************************
1928 template< typename MT > // Type of the dense matrix
1929 inline typename DenseRow<MT,false>::Iterator DenseRow<MT,false>::end()
1930 {
1931  return Iterator( matrix_, row_, size() );
1932 }
1934 //*************************************************************************************************
1935 
1936 
1937 //*************************************************************************************************
1945 template< typename MT > // Type of the dense matrix
1946 inline typename DenseRow<MT,false>::ConstIterator DenseRow<MT,false>::end() const
1947 {
1948  return ConstIterator( matrix_, row_, size() );
1949 }
1951 //*************************************************************************************************
1952 
1953 
1954 //*************************************************************************************************
1962 template< typename MT > // Type of the dense matrix
1963 inline typename DenseRow<MT,false>::ConstIterator DenseRow<MT,false>::cend() const
1964 {
1965  return ConstIterator( matrix_, row_, size() );
1966 }
1968 //*************************************************************************************************
1969 
1970 
1971 
1972 
1973 //=================================================================================================
1974 //
1975 // ASSIGNMENT OPERATORS
1976 //
1977 //=================================================================================================
1978 
1979 //*************************************************************************************************
1986 template< typename MT > // Type of the dense matrix
1987 inline DenseRow<MT,false>& DenseRow<MT,false>::operator=( const ElementType& rhs )
1988 {
1989  const size_t columns( size() );
1990 
1991  for( size_t j=0UL; j<columns; ++j )
1992  matrix_(row_,j) = rhs;
1993 
1994  return *this;
1995 }
1997 //*************************************************************************************************
1998 
1999 
2000 //*************************************************************************************************
2011 template< typename MT > // Type of the dense matrix
2012 inline DenseRow<MT,false>& DenseRow<MT,false>::operator=( const DenseRow& rhs )
2013 {
2014  if( &rhs == this ) return *this;
2015 
2016  if( size() != rhs.size() )
2017  throw std::invalid_argument( "Row sizes do not match" );
2018 
2019  const size_t columns( size() );
2020 
2021  for( size_t j=0UL; j<columns; ++j )
2022  matrix_(row_,j) = rhs[j];
2023 
2024  return *this;
2025 }
2027 //*************************************************************************************************
2028 
2029 
2030 //*************************************************************************************************
2041 template< typename MT > // Type of the dense matrix
2042 template< typename VT > // Type of the right-hand side vector
2043 inline DenseRow<MT,false>& DenseRow<MT,false>::operator=( const Vector<VT,true>& rhs )
2044 {
2045  using blaze::assign;
2046 
2047  if( size() != (~rhs).size() )
2048  throw std::invalid_argument( "Vector sizes do not match" );
2049 
2050  if( (~rhs).canAlias( &matrix_ ) ) {
2051  const ResultType tmp( ~rhs );
2052  assign( *this, tmp );
2053  }
2054  else {
2055  if( IsSparseVector<VT>::value )
2056  reset();
2057  assign( *this, ~rhs );
2058  }
2059 
2060  return *this;
2061 }
2063 //*************************************************************************************************
2064 
2065 
2066 //*************************************************************************************************
2077 template< typename MT > // Type of the dense matrix
2078 template< typename VT > // Type of the right-hand side vector
2079 inline DenseRow<MT,false>& DenseRow<MT,false>::operator+=( const Vector<VT,true>& rhs )
2080 {
2081  using blaze::addAssign;
2082 
2083  BLAZE_CONSTRAINT_MUST_BE_TRANSPOSE_VECTOR_TYPE( typename VT::ResultType );
2084  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION ( typename VT::ResultType );
2085 
2086  if( size() != (~rhs).size() )
2087  throw std::invalid_argument( "Vector sizes do not match" );
2088 
2089  if( (~rhs).canAlias( &matrix_ ) ) {
2090  const typename VT::ResultType tmp( ~rhs );
2091  addAssign( *this, tmp );
2092  }
2093  else {
2094  addAssign( *this, ~rhs );
2095  }
2096 
2097  return *this;
2098 }
2100 //*************************************************************************************************
2101 
2102 
2103 //*************************************************************************************************
2114 template< typename MT > // Type of the dense matrix
2115 template< typename VT > // Type of the right-hand side vector
2116 inline DenseRow<MT,false>& DenseRow<MT,false>::operator-=( const Vector<VT,true>& rhs )
2117 {
2118  using blaze::subAssign;
2119 
2120  BLAZE_CONSTRAINT_MUST_BE_TRANSPOSE_VECTOR_TYPE( typename VT::ResultType );
2121  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION ( typename VT::ResultType );
2122 
2123  if( size() != (~rhs).size() )
2124  throw std::invalid_argument( "Vector sizes do not match" );
2125 
2126  if( (~rhs).canAlias( &matrix_ ) ) {
2127  const typename VT::ResultType tmp( ~rhs );
2128  subAssign( *this, tmp );
2129  }
2130  else {
2131  subAssign( *this, ~rhs );
2132  }
2133 
2134  return *this;
2135 }
2137 //*************************************************************************************************
2138 
2139 
2140 //*************************************************************************************************
2152 template< typename MT > // Type of the dense matrix
2153 template< typename VT > // Type of the right-hand side vector
2154 inline DenseRow<MT,false>& DenseRow<MT,false>::operator*=( const Vector<VT,true>& rhs )
2155 {
2156  using blaze::multAssign;
2157 
2158  BLAZE_CONSTRAINT_MUST_BE_TRANSPOSE_VECTOR_TYPE( typename VT::ResultType );
2159  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION ( typename VT::ResultType );
2160 
2161  if( size() != (~rhs).size() )
2162  throw std::invalid_argument( "Vector sizes do not match" );
2163 
2164  if( (~rhs).canAlias( &matrix_ ) || IsSparseVector<VT>::value ) {
2165  const typename VT::ResultType tmp( ~rhs );
2166  multAssign( *this, tmp );
2167  }
2168  else {
2169  multAssign( *this, ~rhs );
2170  }
2171 
2172  return *this;
2173 }
2175 //*************************************************************************************************
2176 
2177 
2178 //*************************************************************************************************
2186 template< typename MT > // Type of the dense matrix
2187 template< typename Other > // Data type of the right-hand side scalar
2188 inline typename EnableIf< IsNumeric<Other>, DenseRow<MT,false> >::Type&
2189  DenseRow<MT,false>::operator*=( Other rhs )
2190 {
2191  return operator=( (*this) * rhs );
2192 }
2194 //*************************************************************************************************
2195 
2196 
2197 //*************************************************************************************************
2207 template< typename MT > // Type of the dense matrix
2208 template< typename Other > // Data type of the right-hand side scalar
2209 inline typename EnableIf< IsNumeric<Other>, DenseRow<MT,false> >::Type&
2210  DenseRow<MT,false>::operator/=( Other rhs )
2211 {
2212  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
2213 
2214  return operator=( (*this) / rhs );
2215 }
2217 //*************************************************************************************************
2218 
2219 
2220 
2221 
2222 //=================================================================================================
2223 //
2224 // UTILITY FUNCTIONS
2225 //
2226 //=================================================================================================
2227 
2228 //*************************************************************************************************
2234 template< typename MT > // Type of the dense matrix
2235 inline size_t DenseRow<MT,false>::size() const
2236 {
2237  return matrix_.columns();
2238 }
2240 //*************************************************************************************************
2241 
2242 
2243 //*************************************************************************************************
2249 template< typename MT > // Type of the dense matrix
2250 inline size_t DenseRow<MT,false>::capacity() const
2251 {
2252  return matrix_.columns();
2253 }
2255 //*************************************************************************************************
2256 
2257 
2258 //*************************************************************************************************
2267 template< typename MT > // Type of the dense matrix
2268 inline size_t DenseRow<MT,false>::nonZeros() const
2269 {
2270  const size_t columns( size() );
2271  size_t nonzeros( 0UL );
2272 
2273  for( size_t j=0UL; j<columns; ++j )
2274  if( !isDefault( matrix_(row_,j) ) )
2275  ++nonzeros;
2276 
2277  return nonzeros;
2278 }
2280 //*************************************************************************************************
2281 
2282 
2283 //*************************************************************************************************
2289 template< typename MT > // Type of the dense matrix
2290 inline void DenseRow<MT,false>::reset()
2291 {
2292  using blaze::reset;
2293  const size_t columns( size() );
2294  for( size_t j=0UL; j<columns; ++j )
2295  reset( matrix_(row_,j) );
2296 }
2298 //*************************************************************************************************
2299 
2300 
2301 //*************************************************************************************************
2308 template< typename MT > // Type of the dense matrix
2309 template< typename Other > // Data type of the scalar value
2310 inline DenseRow<MT,false>& DenseRow<MT,false>::scale( const Other& scalar )
2311 {
2312  for( size_t j=0UL; j<size(); ++j ) {
2313  matrix_(row_,j) *= scalar;
2314  }
2315  return *this;
2316 }
2318 //*************************************************************************************************
2319 
2320 
2321 
2322 
2323 //=================================================================================================
2324 //
2325 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2326 //
2327 //=================================================================================================
2328 
2329 //*************************************************************************************************
2340 template< typename MT > // Type of the dense matrix
2341 template< typename Other > // Data type of the foreign expression
2342 inline bool DenseRow<MT,false>::canAlias( const Other* alias ) const
2343 {
2344  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
2345 }
2347 //*************************************************************************************************
2348 
2349 
2350 //*************************************************************************************************
2361 template< typename MT > // Type of the dense matrix
2362 template< typename Other > // Data type of the foreign expression
2363 inline bool DenseRow<MT,false>::isAliased( const Other* alias ) const
2364 {
2365  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
2366 }
2368 //*************************************************************************************************
2369 
2370 
2371 //*************************************************************************************************
2383 template< typename MT > // Type of the dense matrix
2384 template< typename VT > // Type of the right-hand side dense vector
2385 inline void DenseRow<MT,false>::assign( const DenseVector<VT,true>& rhs )
2386 {
2387  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2388 
2389  const size_t jend( (~rhs).size() & size_t(-2) );
2390  for( size_t j=0UL; j<jend; j+=2UL ) {
2391  matrix_(row_,j ) = (~rhs)[j ];
2392  matrix_(row_,j+1UL) = (~rhs)[j+1UL];
2393  }
2394  if( jend < (~rhs).size() )
2395  matrix_(row_,jend) = (~rhs)[jend];
2396 }
2398 //*************************************************************************************************
2399 
2400 
2401 //*************************************************************************************************
2413 template< typename MT > // Type of the dense matrix
2414 template< typename VT > // Type of the right-hand side sparse vector
2415 inline void DenseRow<MT,false>::assign( const SparseVector<VT,true>& rhs )
2416 {
2417  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2418 
2419  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2420  matrix_(row_,element->index()) = element->value();
2421 }
2423 //*************************************************************************************************
2424 
2425 
2426 //*************************************************************************************************
2438 template< typename MT > // Type of the dense matrix
2439 template< typename VT > // Type of the right-hand side dense vector
2440 inline void DenseRow<MT,false>::addAssign( const DenseVector<VT,true>& rhs )
2441 {
2442  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2443 
2444  const size_t jend( (~rhs).size() & size_t(-2) );
2445  for( size_t j=0UL; j<jend; j+=2UL ) {
2446  matrix_(row_,j ) += (~rhs)[j ];
2447  matrix_(row_,j+1UL) += (~rhs)[j+1UL];
2448  }
2449  if( jend < (~rhs).size() )
2450  matrix_(row_,jend) += (~rhs)[jend];
2451 }
2453 //*************************************************************************************************
2454 
2455 
2456 //*************************************************************************************************
2468 template< typename MT > // Type of the dense matrix
2469 template< typename VT > // Type of the right-hand side sparse vector
2470 inline void DenseRow<MT,false>::addAssign( const SparseVector<VT,true>& rhs )
2471 {
2472  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2473 
2474  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2475  matrix_(row_,element->index()) += element->value();
2476 }
2478 //*************************************************************************************************
2479 
2480 
2481 //*************************************************************************************************
2493 template< typename MT > // Type of the dense matrix
2494 template< typename VT > // Type of the right-hand side dense vector
2495 inline void DenseRow<MT,false>::subAssign( const DenseVector<VT,true>& rhs )
2496 {
2497  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2498 
2499  const size_t jend( (~rhs).size() & size_t(-2) );
2500  for( size_t j=0UL; j<jend; j+=2UL ) {
2501  matrix_(row_,j ) -= (~rhs)[j ];
2502  matrix_(row_,j+1UL) -= (~rhs)[j+1UL];
2503  }
2504  if( jend < (~rhs).size() )
2505  matrix_(row_,jend) -= (~rhs)[jend];
2506 }
2508 //*************************************************************************************************
2509 
2510 
2511 //*************************************************************************************************
2523 template< typename MT > // Type of the dense matrix
2524 template< typename VT > // Type of the right-hand side sparse vector
2525 inline void DenseRow<MT,false>::subAssign( const SparseVector<VT,true>& rhs )
2526 {
2527  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2528 
2529  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2530  matrix_(row_,element->index()) -= element->value();
2531 }
2533 //*************************************************************************************************
2534 
2535 
2536 //*************************************************************************************************
2548 template< typename MT > // Type of the dense matrix
2549 template< typename VT > // Type of the right-hand side dense vector
2550 inline void DenseRow<MT,false>::multAssign( const DenseVector<VT,true>& rhs )
2551 {
2552  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2553 
2554  const size_t jend( (~rhs).size() & size_t(-2) );
2555  for( size_t j=0UL; j<jend; j+=2UL ) {
2556  matrix_(row_,j ) *= (~rhs)[j ];
2557  matrix_(row_,j+1UL) *= (~rhs)[j+1UL];
2558  }
2559  if( jend < (~rhs).size() )
2560  matrix_(row_,jend) *= (~rhs)[jend];
2561 }
2563 //*************************************************************************************************
2564 
2565 
2566 //*************************************************************************************************
2578 template< typename MT > // Type of the dense matrix
2579 template< typename VT > // Type of the right-hand side sparse vector
2580 inline void DenseRow<MT,false>::multAssign( const SparseVector<VT,true>& rhs )
2581 {
2582  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2583 
2584  const ResultType tmp( *this );
2585 
2586  reset();
2587 
2588  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2589  matrix_(row_,element->index()) = tmp[element->index()] * element->value();
2590 }
2592 //*************************************************************************************************
2593 
2594 
2595 
2596 
2597 
2598 
2599 
2600 
2601 //=================================================================================================
2602 //
2603 // DENSEROW OPERATORS
2604 //
2605 //=================================================================================================
2606 
2607 //*************************************************************************************************
2610 template< typename MT, bool SO >
2611 inline void reset( DenseRow<MT,SO>& row );
2612 
2613 template< typename MT, bool SO >
2614 inline void clear( DenseRow<MT,SO>& row );
2615 
2616 template< typename MT, bool SO >
2617 inline bool isnan( const DenseRow<MT,SO>& row );
2618 
2619 template< typename MT, bool SO >
2620 inline bool isDefault( const DenseRow<MT,SO>& row );
2622 //*************************************************************************************************
2623 
2624 
2625 //*************************************************************************************************
2632 template< typename MT // Type of the dense matrix
2633  , bool SO > // Storage order
2634 inline void reset( DenseRow<MT,SO>& row )
2635 {
2636  row.reset();
2637 }
2638 //*************************************************************************************************
2639 
2640 
2641 //*************************************************************************************************
2648 template< typename MT // Type of the dense matrix
2649  , bool SO > // Storage order
2650 inline void clear( DenseRow<MT,SO>& row )
2651 {
2652  row.reset();
2653 }
2654 //*************************************************************************************************
2655 
2656 
2657 //*************************************************************************************************
2673 template< typename MT // Type of the dense matrix
2674  , bool SO > // Storage order
2675 inline bool isnan( const DenseRow<MT,SO>& row )
2676 {
2677  for( size_t i=0UL; i<row.size(); ++i ) {
2678  if( isnan( row[i] ) ) return true;
2679  }
2680  return false;
2681 }
2682 //*************************************************************************************************
2683 
2684 
2685 //*************************************************************************************************
2703 template< typename MT // Type of the dense matrix
2704  , bool SO > // Storage order
2705 inline bool isDefault( const DenseRow<MT,SO>& row )
2706 {
2707  for( size_t i=0UL; i<row.size(); ++i )
2708  if( !isDefault( row[i] ) ) return false;
2709  return true;
2710 }
2711 //*************************************************************************************************
2712 
2713 
2714 
2715 
2716 //=================================================================================================
2717 //
2718 // GLOBAL OPERATORS
2719 //
2720 //=================================================================================================
2721 
2722 //*************************************************************************************************
2741 template< typename MT // Type of the dense matrix
2742  , bool SO > // Storage order
2743 inline DenseRow<MT> row( DenseMatrix<MT,SO>& dm, size_t index )
2744 {
2746 
2747  return DenseRow<MT>( ~dm, index );
2748 }
2749 //*************************************************************************************************
2750 
2751 
2752 //*************************************************************************************************
2771 template< typename MT // Type of the dense matrix
2772  , bool SO > // Storage order
2773 inline DenseRow<const MT> row( const DenseMatrix<MT,SO>& dm, size_t index )
2774 {
2776 
2777  return DenseRow<const MT>( ~dm, index );
2778 }
2779 //*************************************************************************************************
2780 
2781 
2782 
2783 
2784 //=================================================================================================
2785 //
2786 // ADDTRAIT SPECIALIZATIONS
2787 //
2788 //=================================================================================================
2789 
2790 //*************************************************************************************************
2792 template< typename T1, bool SO, typename T2, size_t N >
2793 struct AddTrait< DenseRow<T1,SO>, StaticVector<T2,N,true> >
2794 {
2795  typedef typename AddTrait< typename DenseRow<T1,SO>::ResultType,
2796  StaticVector<T2,N,true> >::Type Type;
2797 };
2798 
2799 template< typename T1, size_t N, typename T2, bool SO >
2800 struct AddTrait< StaticVector<T1,N,true>, DenseRow<T2,SO> >
2801 {
2802  typedef typename AddTrait< StaticVector<T1,N,true>,
2803  typename DenseRow<T2,SO>::ResultType >::Type Type;
2804 };
2805 
2806 template< typename T1, bool SO, typename T2 >
2807 struct AddTrait< DenseRow<T1,SO>, DynamicVector<T2,true> >
2808 {
2809  typedef typename AddTrait< typename DenseRow<T1,SO>::ResultType,
2810  DynamicVector<T2,true> >::Type Type;
2811 };
2812 
2813 template< typename T1, typename T2, bool SO >
2814 struct AddTrait< DynamicVector<T1,true>, DenseRow<T2,SO> >
2815 {
2816  typedef typename AddTrait< DynamicVector<T1,true>,
2817  typename DenseRow<T2,SO>::ResultType >::Type Type;
2818 };
2819 
2820 template< typename T1, bool SO, typename T2 >
2821 struct AddTrait< DenseRow<T1,SO>, CompressedVector<T2,true> >
2822 {
2823  typedef typename AddTrait< typename DenseRow<T1,SO>::ResultType,
2824  CompressedVector<T2,true> >::Type Type;
2825 };
2826 
2827 template< typename T1, typename T2, bool SO >
2828 struct AddTrait< CompressedVector<T1,true>, DenseRow<T2,SO> >
2829 {
2830  typedef typename AddTrait< CompressedVector<T1,true>,
2831  typename DenseRow<T2,SO>::ResultType >::Type Type;
2832 };
2833 
2834 template< typename T1, bool SO1, typename T2, bool SO2 >
2835 struct AddTrait< DenseRow<T1,SO1>, DenseRow<T2,SO2> >
2836 {
2837  typedef typename AddTrait< typename DenseRow<T1,SO1>::ResultType,
2838  typename DenseRow<T2,SO2>::ResultType >::Type Type;
2839 };
2841 //*************************************************************************************************
2842 
2843 
2844 
2845 
2846 //=================================================================================================
2847 //
2848 // SUBTRAIT SPECIALIZATIONS
2849 //
2850 //=================================================================================================
2851 
2852 //*************************************************************************************************
2854 template< typename T1, bool SO, typename T2, size_t N >
2855 struct SubTrait< DenseRow<T1,SO>, StaticVector<T2,N,true> >
2856 {
2857  typedef typename SubTrait< typename DenseRow<T1,SO>::ResultType,
2858  StaticVector<T2,N,true> >::Type Type;
2859 };
2860 
2861 template< typename T1, size_t N, typename T2, bool SO >
2862 struct SubTrait< StaticVector<T1,N,true>, DenseRow<T2,SO> >
2863 {
2864  typedef typename SubTrait< StaticVector<T1,N,true>,
2865  typename DenseRow<T2,SO>::ResultType >::Type Type;
2866 };
2867 
2868 template< typename T1, bool SO, typename T2 >
2869 struct SubTrait< DenseRow<T1,SO>, DynamicVector<T2,true> >
2870 {
2871  typedef typename SubTrait< typename DenseRow<T1,SO>::ResultType,
2872  DynamicVector<T2,true> >::Type Type;
2873 };
2874 
2875 template< typename T1, typename T2, bool SO >
2876 struct SubTrait< DynamicVector<T1,true>, DenseRow<T2,SO> >
2877 {
2878  typedef typename SubTrait< DynamicVector<T1,true>,
2879  typename DenseRow<T2,SO>::ResultType >::Type Type;
2880 };
2881 
2882 template< typename T1, bool SO, typename T2 >
2883 struct SubTrait< DenseRow<T1,SO>, CompressedVector<T2,true> >
2884 {
2885  typedef typename SubTrait< typename DenseRow<T1,SO>::ResultType,
2886  CompressedVector<T2,true> >::Type Type;
2887 };
2888 
2889 template< typename T1, typename T2, bool SO >
2890 struct SubTrait< CompressedVector<T1,true>, DenseRow<T2,SO> >
2891 {
2892  typedef typename SubTrait< CompressedVector<T1,true>,
2893  typename DenseRow<T2,SO>::ResultType >::Type Type;
2894 };
2895 
2896 template< typename T1, bool SO1, typename T2, bool SO2 >
2897 struct SubTrait< DenseRow<T1,SO1>, DenseRow<T2,SO2> >
2898 {
2899  typedef typename SubTrait< typename DenseRow<T1,SO1>::ResultType,
2900  typename DenseRow<T2,SO2>::ResultType >::Type Type;
2901 };
2903 //*************************************************************************************************
2904 
2905 
2906 
2907 
2908 //=================================================================================================
2909 //
2910 // MULTTRAIT SPECIALIZATIONS
2911 //
2912 //=================================================================================================
2913 
2914 //*************************************************************************************************
2916 template< typename T1, bool SO, typename T2 >
2917 struct MultTrait< DenseRow<T1,SO>, T2 >
2918 {
2919  typedef typename MultTrait< typename DenseRow<T1,SO>::ResultType, T2 >::Type Type;
2921 };
2922 
2923 template< typename T1, typename T2, bool SO >
2924 struct MultTrait< T1, DenseRow<T2,SO> >
2925 {
2926  typedef typename MultTrait< T1, typename DenseRow<T2,SO>::ResultType >::Type Type;
2928 };
2929 
2930 template< typename T1, bool SO, typename T2, size_t N, bool TF >
2931 struct MultTrait< DenseRow<T1,SO>, StaticVector<T2,N,TF> >
2932 {
2933  typedef typename MultTrait< typename DenseRow<T1,SO>::ResultType,
2934  StaticVector<T2,N,TF> >::Type Type;
2935 };
2936 
2937 template< typename T1, size_t N, bool TF, typename T2, bool SO >
2938 struct MultTrait< StaticVector<T1,N,TF>, DenseRow<T2,SO> >
2939 {
2940  typedef typename MultTrait< StaticVector<T1,N,TF>,
2941  typename DenseRow<T2,SO>::ResultType >::Type Type;
2942 };
2943 
2944 template< typename T1, bool SO, typename T2, bool TF >
2945 struct MultTrait< DenseRow<T1,SO>, DynamicVector<T2,TF> >
2946 {
2947  typedef typename MultTrait< typename DenseRow<T1,SO>::ResultType,
2948  DynamicVector<T2,TF> >::Type Type;
2949 };
2950 
2951 template< typename T1, bool TF, typename T2, bool SO >
2952 struct MultTrait< DynamicVector<T1,TF>, DenseRow<T2,SO> >
2953 {
2954  typedef typename MultTrait< DynamicVector<T1,TF>,
2955  typename DenseRow<T2,SO>::ResultType >::Type Type;
2956 };
2957 
2958 template< typename T1, bool SO, typename T2, bool TF >
2959 struct MultTrait< DenseRow<T1,SO>, CompressedVector<T2,TF> >
2960 {
2961  typedef typename MultTrait< typename DenseRow<T1,SO>::ResultType,
2962  CompressedVector<T2,TF> >::Type Type;
2963 };
2964 
2965 template< typename T1, bool TF, typename T2, bool SO >
2966 struct MultTrait< CompressedVector<T1,TF>, DenseRow<T2,SO> >
2967 {
2968  typedef typename MultTrait< CompressedVector<T1,TF>,
2969  typename DenseRow<T2,SO>::ResultType >::Type Type;
2970 };
2971 
2972 template< typename T1, bool SO1, typename T2, bool SO2 >
2973 struct MultTrait< DenseRow<T1,SO1>, DenseRow<T2,SO2> >
2974 {
2975  typedef typename MultTrait< typename DenseRow<T1,SO1>::ResultType,
2976  typename DenseRow<T2,SO2>::ResultType >::Type Type;
2977 };
2978 
2979 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
2980 struct MultTrait< DenseRow<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
2981 {
2982  typedef typename MultTrait< typename DenseRow<T1,SO1>::ResultType,
2983  StaticMatrix<T2,M,N,SO2> >::Type Type;
2984 };
2985 
2986 template< typename T1, bool SO1, typename T2, bool SO2 >
2987 struct MultTrait< DenseRow<T1,SO1>, DynamicMatrix<T2,SO2> >
2988 {
2989  typedef typename MultTrait< typename DenseRow<T1,SO1>::ResultType,
2990  DynamicMatrix<T2,SO2> >::Type Type;
2991 };
2992 
2993 template< typename T1, bool SO1, typename T2, bool SO2 >
2994 struct MultTrait< DenseRow<T1,SO1>, CompressedMatrix<T2,SO2> >
2995 {
2996  typedef typename MultTrait< typename DenseRow<T1,SO1>::ResultType,
2997  CompressedMatrix<T2,SO2> >::Type Type;
2998 };
3000 //*************************************************************************************************
3001 
3002 
3003 
3004 
3005 //=================================================================================================
3006 //
3007 // DIVTRAIT SPECIALIZATIONS
3008 //
3009 //=================================================================================================
3010 
3011 //*************************************************************************************************
3013 template< typename T1, bool SO, typename T2 >
3014 struct DivTrait< DenseRow<T1,SO>, T2 >
3015 {
3016  typedef typename DivTrait< typename DenseRow<T1,SO>::ResultType, T2 >::Type Type;
3018 };
3020 //*************************************************************************************************
3021 
3022 } // namespace blaze
3023 
3024 #endif