SparseRow.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SPARSEROW_H_
36 #define _BLAZE_MATH_VIEWS_SPARSEROW_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <stdexcept>
58 #include <blaze/math/Functions.h>
60 #include <blaze/math/shims/IsOne.h>
61 #include <blaze/math/shims/Reset.h>
83 #include <blaze/util/Assert.h>
86 #include <blaze/util/DisableIf.h>
87 #include <blaze/util/EnableIf.h>
89 #include <blaze/util/mpl/And.h>
90 #include <blaze/util/mpl/If.h>
91 #include <blaze/util/mpl/Or.h>
92 #include <blaze/util/Null.h>
94 #include <blaze/util/Types.h>
100 #include <blaze/util/Unused.h>
101 
102 
103 namespace blaze {
104 
105 //=================================================================================================
106 //
107 // CLASS DEFINITION
108 //
109 //=================================================================================================
110 
111 //*************************************************************************************************
368 template< typename MT // Type of the sparse matrix
369  , bool SO = IsRowMajorMatrix<MT>::value // Storage order
370  , bool SF = IsSymmetric<MT>::value > // Symmetry flag
371 class SparseRow : public SparseVector< SparseRow<MT,SO,SF>, true >
372  , private Row
373 {
374  private:
375  //**Type definitions****************************************************************************
377  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
378  //**********************************************************************************************
379 
380  //**********************************************************************************************
382 
388  enum { useConst = IsConst<MT>::value };
389  //**********************************************************************************************
390 
391  public:
392  //**Type definitions****************************************************************************
394  typedef typename RowTrait<MT>::Type ResultType;
396  typedef typename MT::ElementType ElementType;
397  typedef typename MT::ReturnType ReturnType;
398  typedef const SparseRow& CompositeType;
399 
402 
405 
408 
411  //**********************************************************************************************
412 
413  //**Compilation flags***************************************************************************
415  enum { smpAssignable = 0 };
416  //**********************************************************************************************
417 
418  //**Constructors********************************************************************************
421  explicit inline SparseRow( MT& matrix, size_t index );
422  // No explicitly declared copy constructor.
424  //**********************************************************************************************
425 
426  //**Destructor**********************************************************************************
427  // No explicitly declared destructor.
428  //**********************************************************************************************
429 
430  //**Data access functions***********************************************************************
433  inline Reference operator[]( size_t index );
434  inline ConstReference operator[]( size_t index ) const;
435  inline Iterator begin ();
436  inline ConstIterator begin () const;
437  inline ConstIterator cbegin() const;
438  inline Iterator end ();
439  inline ConstIterator end () const;
440  inline ConstIterator cend () const;
442  //**********************************************************************************************
443 
444  //**Assignment operators************************************************************************
447  inline SparseRow& operator=( const SparseRow& rhs );
448 
449  template< typename VT > inline SparseRow& operator= ( const DenseVector<VT,true>& rhs );
450  template< typename VT > inline SparseRow& operator= ( const SparseVector<VT,true>& rhs );
451  template< typename VT > inline SparseRow& operator+=( const DenseVector<VT,true>& rhs );
452  template< typename VT > inline SparseRow& operator+=( const SparseVector<VT,true>& rhs );
453  template< typename VT > inline SparseRow& operator-=( const DenseVector<VT,true>& rhs );
454  template< typename VT > inline SparseRow& operator-=( const SparseVector<VT,true>& rhs );
455  template< typename VT > inline SparseRow& operator*=( const Vector<VT,true>& rhs );
456 
457  template< typename Other >
458  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
459  operator*=( Other rhs );
460 
461  template< typename Other >
462  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
463  operator/=( Other rhs );
465  //**********************************************************************************************
466 
467  //**Utility functions***************************************************************************
470  inline size_t size() const;
471  inline size_t capacity() const;
472  inline size_t nonZeros() const;
473  inline void reset();
474  inline Iterator set ( size_t index, const ElementType& value );
475  inline Iterator insert ( size_t index, const ElementType& value );
476  inline void erase ( size_t index );
477  inline Iterator erase ( Iterator pos );
478  inline Iterator erase ( Iterator first, Iterator last );
479  inline void reserve( size_t n );
480  template< typename Other > inline SparseRow& scale ( const Other& scalar );
482  //**********************************************************************************************
483 
484  //**Lookup functions****************************************************************************
487  inline Iterator find ( size_t index );
488  inline ConstIterator find ( size_t index ) const;
489  inline Iterator lowerBound( size_t index );
490  inline ConstIterator lowerBound( size_t index ) const;
491  inline Iterator upperBound( size_t index );
492  inline ConstIterator upperBound( size_t index ) const;
494  //**********************************************************************************************
495 
496  //**Low-level utility functions*****************************************************************
499  inline void append( size_t index, const ElementType& value, bool check=false );
501  //**********************************************************************************************
502 
503  //**Expression template evaluation functions****************************************************
506  template< typename Other > inline bool canAlias ( const Other* alias ) const;
507  template< typename Other > inline bool isAliased( const Other* alias ) const;
508 
509  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
510  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
511  template< typename VT > inline void addAssign( const DenseVector <VT,true>& rhs );
512  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
513  template< typename VT > inline void subAssign( const DenseVector <VT,true>& rhs );
514  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
516  //**********************************************************************************************
517 
518  private:
519  //**Utility functions***************************************************************************
522  inline size_t extendCapacity() const;
523 
524  template< typename MT2, bool SO2, typename VT >
525  inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
526  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,true>& rhs );
527 
528  template< typename MT2, bool SO2, typename VT >
529  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
530  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs );
531 
532  template< typename MT2, bool SO2, typename VT >
533  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
534  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs );
535 
536  template< typename MT2, bool SO2, typename VT >
537  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
538  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs );
539 
540  template< typename MT2, bool SO2, typename VT >
541  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
542  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs );
543 
544  template< typename MT2, bool SO2, typename VT >
545  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
546  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs );
547 
548  template< typename MT2, bool SO2, typename VT >
549  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
550  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs );
552  //**********************************************************************************************
553 
554  //**Member variables****************************************************************************
557  Operand matrix_;
558  const size_t row_;
559 
560  //**********************************************************************************************
561 
562  //**Friend declarations*************************************************************************
564  template< typename MT2, bool SO2, bool SF2 >
565  friend bool isSame( const SparseRow<MT2,SO2,SF2>& a, const SparseRow<MT2,SO2,SF2>& b );
566 
567  template< typename MT2, bool SO2, bool SF2 >
568  friend typename DerestrictTrait< SparseRow<MT2,SO2,SF2> >::Type
569  derestrict( SparseRow<MT2,SO2,SF2>& dm );
571  //**********************************************************************************************
572 
573  //**Compile time checks*************************************************************************
583  //**********************************************************************************************
584 };
585 //*************************************************************************************************
586 
587 
588 
589 
590 //=================================================================================================
591 //
592 // CONSTRUCTOR
593 //
594 //=================================================================================================
595 
596 //*************************************************************************************************
603 template< typename MT // Type of the sparse matrix
604  , bool SO // Storage order
605  , bool SF > // Symmetry flag
606 inline SparseRow<MT,SO,SF>::SparseRow( MT& matrix, size_t index )
607  : matrix_( matrix ) // The sparse matrix containing the row
608  , row_ ( index ) // The index of the row in the matrix
609 {
610  if( matrix_.rows() <= index )
611  throw std::invalid_argument( "Invalid row access index" );
612 }
613 //*************************************************************************************************
614 
615 
616 
617 
618 //=================================================================================================
619 //
620 // DATA ACCESS FUNCTIONS
621 //
622 //=================================================================================================
623 
624 //*************************************************************************************************
630 template< typename MT // Type of the sparse matrix
631  , bool SO // Storage order
632  , bool SF > // Symmetry flag
634 {
635  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
636  return matrix_(row_,index);
637 }
638 //*************************************************************************************************
639 
640 
641 //*************************************************************************************************
647 template< typename MT // Type of the sparse matrix
648  , bool SO // Storage order
649  , bool SF > // Symmetry flag
651  SparseRow<MT,SO,SF>::operator[]( size_t index ) const
652 {
653  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
654  return const_cast<const MT&>( matrix_ )(row_,index);
655 }
656 //*************************************************************************************************
657 
658 
659 //*************************************************************************************************
666 template< typename MT // Type of the sparse matrix
667  , bool SO // Storage order
668  , bool SF > // Symmetry flag
670 {
671  return matrix_.begin( row_ );
672 }
673 //*************************************************************************************************
674 
675 
676 //*************************************************************************************************
683 template< typename MT // Type of the sparse matrix
684  , bool SO // Storage order
685  , bool SF > // Symmetry flag
687 {
688  return matrix_.cbegin( row_ );
689 }
690 //*************************************************************************************************
691 
692 
693 //*************************************************************************************************
700 template< typename MT // Type of the sparse matrix
701  , bool SO // Storage order
702  , bool SF > // Symmetry flag
704 {
705  return matrix_.cbegin( row_ );
706 }
707 //*************************************************************************************************
708 
709 
710 //*************************************************************************************************
717 template< typename MT // Type of the sparse matrix
718  , bool SO // Storage order
719  , bool SF > // Symmetry flag
721 {
722  return matrix_.end( row_ );
723 }
724 //*************************************************************************************************
725 
726 
727 //*************************************************************************************************
734 template< typename MT // Type of the sparse matrix
735  , bool SO // Storage order
736  , bool SF > // Symmetry flag
738 {
739  return matrix_.cend( row_ );
740 }
741 //*************************************************************************************************
742 
743 
744 //*************************************************************************************************
751 template< typename MT // Type of the sparse matrix
752  , bool SO // Storage order
753  , bool SF > // Symmetry flag
755 {
756  return matrix_.cend( row_ );
757 }
758 //*************************************************************************************************
759 
760 
761 
762 
763 //=================================================================================================
764 //
765 // ASSIGNMENT OPERATORS
766 //
767 //=================================================================================================
768 
769 //*************************************************************************************************
782 template< typename MT // Type of the sparse matrix
783  , bool SO // Storage order
784  , bool SF > // Symmetry flag
786 {
787  using blaze::assign;
788 
792 
793  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
794  return *this;
795 
796  if( size() != rhs.size() )
797  throw std::invalid_argument( "Row sizes do not match" );
798 
799  if( !preservesInvariant( matrix_, rhs ) )
800  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
801 
802  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
803 
804  if( rhs.canAlias( &matrix_ ) ) {
805  const ResultType tmp( rhs );
806  left.reset();
807  left.reserve( tmp.nonZeros() );
808  assign( left, tmp );
809  }
810  else {
811  left.reset();
812  left.reserve( rhs.nonZeros() );
813  assign( left, rhs );
814  }
815 
816  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
817  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
818 
819  return *this;
820 }
821 //*************************************************************************************************
822 
823 
824 //*************************************************************************************************
837 template< typename MT // Type of the sparse matrix
838  , bool SO // Storage order
839  , bool SF > // Symmetry flag
840 template< typename VT > // Type of the right-hand side dense vector
842 {
843  using blaze::assign;
844 
848 
849  if( size() != (~rhs).size() )
850  throw std::invalid_argument( "Vector sizes do not match" );
851 
852  typedef typename If< IsRestricted<MT>, typename VT::CompositeType, const VT& >::Type Right;
853  Right right( ~rhs );
854 
855  if( !preservesInvariant( matrix_, right ) )
856  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
857 
858  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
859 
860  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
861  const typename VT::ResultType tmp( right );
862  left.reset();
863  assign( left, tmp );
864  }
865  else {
866  left.reset();
867  assign( left, right );
868  }
869 
870  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
871  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
872 
873  return *this;
874 }
875 //*************************************************************************************************
876 
877 
878 //*************************************************************************************************
891 template< typename MT // Type of the sparse matrix
892  , bool SO // Storage order
893  , bool SF > // Symmetry flag
894 template< typename VT > // Type of the right-hand side sparse vector
896 {
897  using blaze::assign;
898 
902 
903  if( size() != (~rhs).size() )
904  throw std::invalid_argument( "Vector sizes do not match" );
905 
906  typedef typename If< IsRestricted<MT>, typename VT::CompositeType, const VT& >::Type Right;
907  Right right( ~rhs );
908 
909  if( !preservesInvariant( matrix_, right ) )
910  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
911 
912  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
913 
914  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
915  const typename VT::ResultType tmp( right );
916  left.reset();
917  left.reserve( tmp.nonZeros() );
918  assign( left, tmp );
919  }
920  else {
921  left.reset();
922  left.reserve( right.nonZeros() );
923  assign( left, right );
924  }
925 
926  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
927  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
928 
929  return *this;
930 }
931 //*************************************************************************************************
932 
933 
934 //*************************************************************************************************
947 template< typename MT // Type of the sparse matrix
948  , bool SO // Storage order
949  , bool SF > // Symmetry flag
950 template< typename VT > // Type of the right-hand side dense vector
952 {
953  using blaze::assign;
954 
961 
963 
967 
968  if( size() != (~rhs).size() )
969  throw std::invalid_argument( "Vector sizes do not match" );
970 
971  const AddType tmp( *this + (~rhs) );
972 
973  if( !preservesInvariant( matrix_, tmp ) )
974  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
975 
976  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
977 
978  left.reset();
979  assign( left, tmp );
980 
981  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
982  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
983 
984  return *this;
985 }
986 //*************************************************************************************************
987 
988 
989 //*************************************************************************************************
1002 template< typename MT // Type of the sparse matrix
1003  , bool SO // Storage order
1004  , bool SF > // Symmetry flag
1005 template< typename VT > // Type of the right-hand side sparse vector
1007 {
1008  using blaze::assign;
1009 
1016 
1017  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
1018 
1022 
1023  if( size() != (~rhs).size() )
1024  throw std::invalid_argument( "Vector sizes do not match" );
1025 
1026  const AddType tmp( *this + (~rhs) );
1027 
1028  if( !preservesInvariant( matrix_, tmp ) )
1029  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
1030 
1031  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1032 
1033  left.reset();
1034  left.reserve( tmp.nonZeros() );
1035  assign( left, tmp );
1036 
1037  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1038  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1039 
1040  return *this;
1041 }
1042 //*************************************************************************************************
1043 
1044 
1045 //*************************************************************************************************
1059 template< typename MT // Type of the sparse matrix
1060  , bool SO // Storage order
1061  , bool SF > // Symmetry flag
1062 template< typename VT > // Type of the right-hand side dense vector
1064 {
1065  using blaze::assign;
1066 
1073 
1074  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
1075 
1079 
1080  if( size() != (~rhs).size() )
1081  throw std::invalid_argument( "Vector sizes do not match" );
1082 
1083  const SubType tmp( *this - (~rhs) );
1084 
1085  if( !preservesInvariant( matrix_, tmp ) )
1086  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
1087 
1088  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1089 
1090  left.reset();
1091  assign( left, tmp );
1092 
1093  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1094  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1095 
1096  return *this;
1097 }
1098 //*************************************************************************************************
1099 
1100 
1101 //*************************************************************************************************
1115 template< typename MT // Type of the sparse matrix
1116  , bool SO // Storage order
1117  , bool SF > // Symmetry flag
1118 template< typename VT > // Type of the right-hand side sparse vector
1120 {
1121  using blaze::assign;
1122 
1129 
1130  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
1131 
1135 
1136  if( size() != (~rhs).size() )
1137  throw std::invalid_argument( "Vector sizes do not match" );
1138 
1139  const SubType tmp( *this - (~rhs) );
1140 
1141  if( !preservesInvariant( matrix_, tmp ) )
1142  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
1143 
1144  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1145 
1146  left.reset();
1147  left.reserve( tmp.nonZeros() );
1148  assign( left, tmp );
1149 
1150  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1151  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1152 
1153  return *this;
1154 }
1155 //*************************************************************************************************
1156 
1157 
1158 //*************************************************************************************************
1169 template< typename MT // Type of the sparse matrix
1170  , bool SO // Storage order
1171  , bool SF > // Symmetry flag
1172 template< typename VT > // Type of the right-hand side vector
1174 {
1175  using blaze::assign;
1176 
1182 
1183  typedef typename MultTrait<ResultType,typename VT::ResultType>::Type MultType;
1184 
1187 
1188  if( size() != (~rhs).size() )
1189  throw std::invalid_argument( "Vector sizes do not match" );
1190 
1191  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1192 
1193  const MultType tmp( *this * (~rhs) );
1194  left.reset();
1195  assign( left, tmp );
1196 
1197  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1198  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1199 
1200  return *this;
1201 }
1202 //*************************************************************************************************
1203 
1204 
1205 //*************************************************************************************************
1219 template< typename MT // Type of the sparse matrix
1220  , bool SO // Storage order
1221  , bool SF > // Symmetry flag
1222 template< typename Other > // Data type of the right-hand side scalar
1223 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,SO,SF> >::Type&
1225 {
1227 
1228  for( Iterator element=begin(); element!=end(); ++element )
1229  element->value() *= rhs;
1230  return *this;
1231 }
1232 //*************************************************************************************************
1233 
1234 
1235 //*************************************************************************************************
1252 template< typename MT // Type of the sparse matrix
1253  , bool SO // Storage order
1254  , bool SF > // Symmetry flag
1255 template< typename Other > // Data type of the right-hand side scalar
1256 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,SO,SF> >::Type&
1258 {
1260 
1261  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1262 
1263  typedef typename DivTrait<ElementType,Other>::Type DT;
1264  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1265 
1266  // Depending on the two involved data types, an integer division is applied or a
1267  // floating point division is selected.
1269  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1270  for( Iterator element=begin(); element!=end(); ++element )
1271  element->value() *= tmp;
1272  }
1273  else {
1274  for( Iterator element=begin(); element!=end(); ++element )
1275  element->value() /= rhs;
1276  }
1277 
1278  return *this;
1279 }
1280 //*************************************************************************************************
1281 
1282 
1283 
1284 
1285 //=================================================================================================
1286 //
1287 // UTILITY FUNCTIONS
1288 //
1289 //=================================================================================================
1290 
1291 //*************************************************************************************************
1296 template< typename MT // Type of the sparse matrix
1297  , bool SO // Storage order
1298  , bool SF > // Symmetry flag
1299 inline size_t SparseRow<MT,SO,SF>::size() const
1300 {
1301  return matrix_.columns();
1302 }
1303 //*************************************************************************************************
1304 
1305 
1306 //*************************************************************************************************
1311 template< typename MT // Type of the sparse matrix
1312  , bool SO // Storage order
1313  , bool SF > // Symmetry flag
1314 inline size_t SparseRow<MT,SO,SF>::capacity() const
1315 {
1316  return matrix_.capacity( row_ );
1317 }
1318 //*************************************************************************************************
1319 
1320 
1321 //*************************************************************************************************
1329 template< typename MT // Type of the sparse matrix
1330  , bool SO // Storage order
1331  , bool SF > // Symmetry flag
1332 inline size_t SparseRow<MT,SO,SF>::nonZeros() const
1333 {
1334  return matrix_.nonZeros( row_ );
1335 }
1336 //*************************************************************************************************
1337 
1338 
1339 //*************************************************************************************************
1344 template< typename MT // Type of the sparse matrix
1345  , bool SO // Storage order
1346  , bool SF > // Symmetry flag
1348 {
1349  matrix_.reset( row_ );
1350 }
1351 //*************************************************************************************************
1352 
1353 
1354 //*************************************************************************************************
1365 template< typename MT // Type of the sparse matrix
1366  , bool SO // Storage order
1367  , bool SF > // Symmetry flag
1368 inline typename SparseRow<MT,SO,SF>::Iterator
1369  SparseRow<MT,SO,SF>::set( size_t index, const ElementType& value )
1370 {
1371  return matrix_.set( row_, index, value );
1372 }
1373 //*************************************************************************************************
1374 
1375 
1376 //*************************************************************************************************
1388 template< typename MT // Type of the sparse matrix
1389  , bool SO // Storage order
1390  , bool SF > // Symmetry flag
1391 inline typename SparseRow<MT,SO,SF>::Iterator
1392  SparseRow<MT,SO,SF>::insert( size_t index, const ElementType& value )
1393 {
1394  return matrix_.insert( row_, index, value );
1395 }
1396 //*************************************************************************************************
1397 
1398 
1399 //*************************************************************************************************
1407 template< typename MT // Type of the sparse matrix
1408  , bool SO // Storage order
1409  , bool SF > // Symmetry flag
1410 inline void SparseRow<MT,SO,SF>::erase( size_t index )
1411 {
1412  matrix_.erase( row_, index );
1413 }
1414 //*************************************************************************************************
1415 
1416 
1417 //*************************************************************************************************
1425 template< typename MT // Type of the sparse matrix
1426  , bool SO // Storage order
1427  , bool SF > // Symmetry flag
1429 {
1430  return matrix_.erase( row_, pos );
1431 }
1432 //*************************************************************************************************
1433 
1434 
1435 //*************************************************************************************************
1444 template< typename MT // Type of the sparse matrix
1445  , bool SO // Storage order
1446  , bool SF > // Symmetry flag
1447 inline typename SparseRow<MT,SO,SF>::Iterator
1449 {
1450  return matrix_.erase( row_, first, last );
1451 }
1452 //*************************************************************************************************
1453 
1454 
1455 //*************************************************************************************************
1464 template< typename MT // Type of the sparse matrix
1465  , bool SO // Storage order
1466  , bool SF > // Symmetry flag
1468 {
1469  matrix_.reserve( row_, n );
1470 }
1471 //*************************************************************************************************
1472 
1473 
1474 //*************************************************************************************************
1484 template< typename MT // Type of the sparse matrix
1485  , bool SO // Storage order
1486  , bool SF > // Symmetry flag
1487 template< typename Other > // Data type of the scalar value
1488 inline SparseRow<MT,SO,SF>& SparseRow<MT,SO,SF>::scale( const Other& scalar )
1489 {
1491 
1492  for( Iterator element=begin(); element!=end(); ++element )
1493  element->value() *= scalar;
1494  return *this;
1495 }
1496 //*************************************************************************************************
1497 
1498 
1499 //*************************************************************************************************
1507 template< typename MT // Type of the sparse matrix
1508  , bool SO // Storage order
1509  , bool SF > // Symmetry flag
1511 {
1512  using blaze::max;
1513  using blaze::min;
1514 
1515  size_t nonzeros( 2UL*capacity()+1UL );
1516  nonzeros = max( nonzeros, 7UL );
1517  nonzeros = min( nonzeros, size() );
1518 
1519  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1520 
1521  return nonzeros;
1522 }
1523 //*************************************************************************************************
1524 
1525 
1526 //*************************************************************************************************
1537 template< typename MT // Type of the sparse matrix
1538  , bool SO // Storage order
1539  , bool SF > // Symmetry flag
1540 template< typename MT2 // Type of the left-hand side sparse matrix
1541  , bool SO2 // Storage order of the left-hand side sparse matrix
1542  , typename VT > // Type of the right-hand side vector
1543 inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
1545 {
1546  UNUSED_PARAMETER( lhs, rhs );
1547 
1548  return true;
1549 }
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1564 template< typename MT // Type of the sparse matrix
1565  , bool SO // Storage order
1566  , bool SF > // Symmetry flag
1567 template< typename MT2 // Type of the left-hand side sparse matrix
1568  , bool SO2 // Storage order of the left-hand side sparse matrix
1569  , typename VT > // Type of the right-hand side dense vector
1570 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1572 {
1574 
1575  UNUSED_PARAMETER( lhs );
1576 
1577  if( IsUniLower<MT2>::value && !isOne( (~rhs)[row_] ) )
1578  return false;
1579 
1580  const size_t ibegin( ( IsStrictlyLower<MT2>::value )?( row_ ):( row_+1UL ) );
1581 
1582  for( size_t i=ibegin; i<size(); ++i ) {
1583  if( !isDefault( (~rhs)[i] ) )
1584  return false;
1585  }
1586 
1587  return true;
1588 }
1589 //*************************************************************************************************
1590 
1591 
1592 //*************************************************************************************************
1603 template< typename MT // Type of the sparse matrix
1604  , bool SO // Storage order
1605  , bool SF > // Symmetry flag
1606 template< typename MT2 // Type of the left-hand side sparse matrix
1607  , bool SO2 // Storage order of the left-hand side sparse matrix
1608  , typename VT > // Type of the right-hand side sparse vector
1609 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1611 {
1613 
1614  UNUSED_PARAMETER( lhs );
1615 
1616  typedef typename VT::ConstIterator RhsIterator;
1617 
1618  const bool checkDiagonal( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value );
1619  const RhsIterator last( (~rhs).end() );
1620  RhsIterator element( (~rhs).lowerBound( ( checkDiagonal )?( row_ ):( row_+1UL ) ) );
1621 
1622  if( IsUniLower<MT2>::value ) {
1623  if( element == last || element->index() != row_ || !isOne( element->value() ) )
1624  return false;
1625  ++element;
1626  }
1627 
1628  for( ; element!=last; ++element ) {
1629  if( !isDefault( element->value() ) )
1630  return false;
1631  }
1632 
1633  return true;
1634 }
1635 //*************************************************************************************************
1636 
1637 
1638 //*************************************************************************************************
1649 template< typename MT // Type of the sparse matrix
1650  , bool SO // Storage order
1651  , bool SF > // Symmetry flag
1652 template< typename MT2 // Type of the left-hand side sparse matrix
1653  , bool SO2 // Storage order of the left-hand side sparse matrix
1654  , typename VT > // Type of the right-hand side dense vector
1655 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1657 {
1659 
1660  UNUSED_PARAMETER( lhs );
1661 
1662  const size_t iend( ( IsStrictlyUpper<MT2>::value )?( row_+1UL ):( row_ ) );
1663 
1664  for( size_t i=0UL; i<iend; ++i ) {
1665  if( !isDefault( (~rhs)[i] ) )
1666  return false;
1667  }
1668 
1669  if( IsUniUpper<MT2>::value && !isOne( (~rhs)[row_] ) )
1670  return false;
1671 
1672  return true;
1673 }
1674 //*************************************************************************************************
1675 
1676 
1677 //*************************************************************************************************
1688 template< typename MT // Type of the sparse matrix
1689  , bool SO // Storage order
1690  , bool SF > // Symmetry flag
1691 template< typename MT2 // Type of the left-hand side sparse matrix
1692  , bool SO2 // Storage order of the left-hand side sparse matrix
1693  , typename VT > // Type of the right-hand side sparse vector
1694 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1696 {
1698 
1699  UNUSED_PARAMETER( lhs );
1700 
1701  typedef typename VT::ConstIterator RhsIterator;
1702 
1703  const RhsIterator last( (~rhs).lowerBound( ( IsStrictlyUpper<MT2>::value )?( row_+1UL ):( row_ ) ) );
1704 
1705  if( IsUniUpper<MT2>::value && ( last == (~rhs).end() || last->index() != row_ || !isOne( last->value() ) ) )
1706  return false;
1707 
1708  for( RhsIterator element=(~rhs).begin(); element!=last; ++element ) {
1709  if( !isDefault( element->value() ) )
1710  return false;
1711  }
1712 
1713  return true;
1714 }
1715 //*************************************************************************************************
1716 
1717 
1718 //*************************************************************************************************
1729 template< typename MT // Type of the sparse matrix
1730  , bool SO // Storage order
1731  , bool SF > // Symmetry flag
1732 template< typename MT2 // Type of the left-hand side sparse matrix
1733  , bool SO2 // Storage order of the left-hand side sparse matrix
1734  , typename VT > // Type of the right-hand side dense vector
1735 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
1737 {
1739 
1740  UNUSED_PARAMETER( lhs );
1741 
1742  for( size_t i=0UL; i<row_; ++i ) {
1743  if( !isDefault( (~rhs)[i] ) )
1744  return false;
1745  }
1746 
1747  for( size_t i=row_+1UL; i<size(); ++i ) {
1748  if( !isDefault( (~rhs)[i] ) )
1749  return false;
1750  }
1751 
1752  return true;
1753 }
1754 //*************************************************************************************************
1755 
1756 
1757 //*************************************************************************************************
1768 template< typename MT // Type of the sparse matrix
1769  , bool SO // Storage order
1770  , bool SF > // Symmetry flag
1771 template< typename MT2 // Type of the left-hand side sparse matrix
1772  , bool SO2 // Storage order of the left-hand side sparse matrix
1773  , typename VT > // Type of the right-hand side sparse vector
1774 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
1776 {
1778 
1779  UNUSED_PARAMETER( lhs );
1780 
1781  typedef typename VT::ConstIterator RhsIterator;
1782 
1783  for( RhsIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
1784  if( element->index() != row_ && !isDefault( element->value() ) )
1785  return false;
1786  }
1787 
1788  return true;
1789 }
1790 //*************************************************************************************************
1791 
1792 
1793 
1794 
1795 //=================================================================================================
1796 //
1797 // LOOKUP FUNCTIONS
1798 //
1799 //=================================================================================================
1800 
1801 //*************************************************************************************************
1814 template< typename MT // Type of the sparse matrix
1815  , bool SO // Storage order
1816  , bool SF > // Symmetry flag
1818 {
1819  return matrix_.find( row_, index );
1820 }
1821 //*************************************************************************************************
1822 
1823 
1824 //*************************************************************************************************
1837 template< typename MT // Type of the sparse matrix
1838  , bool SO // Storage order
1839  , bool SF > // Symmetry flag
1841 {
1842  return matrix_.find( row_, index );
1843 }
1844 //*************************************************************************************************
1845 
1846 
1847 //*************************************************************************************************
1859 template< typename MT // Type of the sparse matrix
1860  , bool SO // Storage order
1861  , bool SF > // Symmetry flag
1863 {
1864  return matrix_.lowerBound( row_, index );
1865 }
1866 //*************************************************************************************************
1867 
1868 
1869 //*************************************************************************************************
1881 template< typename MT // Type of the sparse matrix
1882  , bool SO // Storage order
1883  , bool SF > // Symmetry flag
1885 {
1886  return matrix_.lowerBound( row_, index );
1887 }
1888 //*************************************************************************************************
1889 
1890 
1891 //*************************************************************************************************
1903 template< typename MT // Type of the sparse matrix
1904  , bool SO // Storage order
1905  , bool SF > // Symmetry flag
1907 {
1908  return matrix_.upperBound( row_, index );
1909 }
1910 //*************************************************************************************************
1911 
1912 
1913 //*************************************************************************************************
1925 template< typename MT // Type of the sparse matrix
1926  , bool SO // Storage order
1927  , bool SF > // Symmetry flag
1929 {
1930  return matrix_.upperBound( row_, index );
1931 }
1932 //*************************************************************************************************
1933 
1934 
1935 
1936 
1937 //=================================================================================================
1938 //
1939 // LOW-LEVEL UTILITY FUNCTIONS
1940 //
1941 //=================================================================================================
1942 
1943 //*************************************************************************************************
1967 template< typename MT // Type of the sparse matrix
1968  , bool SO // Storage order
1969  , bool SF > // Symmetry flag
1970 inline void SparseRow<MT,SO,SF>::append( size_t index, const ElementType& value, bool check )
1971 {
1972  matrix_.append( row_, index, value, check );
1973 }
1974 //*************************************************************************************************
1975 
1976 
1977 
1978 
1979 //=================================================================================================
1980 //
1981 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1982 //
1983 //=================================================================================================
1984 
1985 //*************************************************************************************************
1995 template< typename MT // Type of the sparse matrix
1996  , bool SO // Storage order
1997  , bool SF > // Symmetry flag
1998 template< typename Other > // Data type of the foreign expression
1999 inline bool SparseRow<MT,SO,SF>::canAlias( const Other* alias ) const
2000 {
2001  return matrix_.isAliased( alias );
2002 }
2003 //*************************************************************************************************
2004 
2005 
2006 //*************************************************************************************************
2016 template< typename MT // Type of the sparse matrix
2017  , bool SO // Storage order
2018  , bool SF > // Symmetry flag
2019 template< typename Other > // Data type of the foreign expression
2020 inline bool SparseRow<MT,SO,SF>::isAliased( const Other* alias ) const
2021 {
2022  return matrix_.isAliased( alias );
2023 }
2024 //*************************************************************************************************
2025 
2026 
2027 //*************************************************************************************************
2038 template< typename MT // Type of the sparse matrix
2039  , bool SO // Storage order
2040  , bool SF > // Symmetry flag
2041 template< typename VT > // Type of the right-hand side dense vector
2043 {
2045 
2046  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2047  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2048 
2049  for( size_t j=0UL; j<size(); ++j )
2050  {
2051  if( matrix_.nonZeros( row_ ) == matrix_.capacity( row_ ) )
2052  matrix_.reserve( row_, extendCapacity() );
2053 
2054  matrix_.append( row_, j, (~rhs)[j], true );
2055  }
2056 }
2057 //*************************************************************************************************
2058 
2059 
2060 //*************************************************************************************************
2071 template< typename MT // Type of the sparse matrix
2072  , bool SO // Storage order
2073  , bool SF > // Symmetry flag
2074 template< typename VT > // Type of the right-hand side sparse vector
2076 {
2078 
2079  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2080  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2081 
2082  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2083  matrix_.append( row_, element->index(), element->value(), true );
2084  }
2085 }
2086 //*************************************************************************************************
2087 
2088 
2089 //*************************************************************************************************
2100 template< typename MT // Type of the sparse matrix
2101  , bool SO // Storage order
2102  , bool SF > // Symmetry flag
2103 template< typename VT > // Type of the right-hand side dense vector
2105 {
2107 
2108  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
2109 
2113 
2114  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2115 
2116  const AddType tmp( serial( *this + (~rhs) ) );
2117  matrix_.reset( row_ );
2118  assign( tmp );
2119 }
2120 //*************************************************************************************************
2121 
2122 
2123 //*************************************************************************************************
2134 template< typename MT // Type of the sparse matrix
2135  , bool SO // Storage order
2136  , bool SF > // Symmetry flag
2137 template< typename VT > // Type of the right-hand side sparse vector
2139 {
2141 
2142  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
2143 
2147 
2148  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2149 
2150  const AddType tmp( serial( *this + (~rhs) ) );
2151  matrix_.reset( row_ );
2152  matrix_.reserve( row_, tmp.nonZeros() );
2153  assign( tmp );
2154 }
2155 //*************************************************************************************************
2156 
2157 
2158 //*************************************************************************************************
2169 template< typename MT // Type of the sparse matrix
2170  , bool SO // Storage order
2171  , bool SF > // Symmetry flag
2172 template< typename VT > // Type of the right-hand side dense vector
2174 {
2176 
2177  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
2178 
2182 
2183  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2184 
2185  const SubType tmp( serial( *this - (~rhs) ) );
2186  matrix_.reset( row_ );
2187  assign( tmp );
2188 }
2189 //*************************************************************************************************
2190 
2191 
2192 //*************************************************************************************************
2203 template< typename MT // Type of the sparse matrix
2204  , bool SO // Storage order
2205  , bool SF > // Symmetry flag
2206 template< typename VT > // Type of the right-hand side sparse vector
2208 {
2210 
2211  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
2212 
2216 
2217  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2218 
2219  const SubType tmp( serial( *this - (~rhs) ) );
2220  matrix_.reset( row_ );
2221  matrix_.reserve( row_, tmp.nonZeros() );
2222  assign( tmp );
2223 }
2224 //*************************************************************************************************
2225 
2226 
2227 
2228 
2229 
2230 
2231 
2232 
2233 //=================================================================================================
2234 //
2235 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR MATRICES
2236 //
2237 //=================================================================================================
2238 
2239 //*************************************************************************************************
2247 template< typename MT > // Type of the sparse matrix
2248 class SparseRow<MT,false,false> : public SparseVector< SparseRow<MT,false,false>, true >
2249  , private Row
2250 {
2251  private:
2252  //**Type definitions****************************************************************************
2254  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
2255  //**********************************************************************************************
2256 
2257  //**********************************************************************************************
2259 
2265  enum { useConst = IsConst<MT>::value };
2266  //**********************************************************************************************
2267 
2268  public:
2269  //**Type definitions****************************************************************************
2270  typedef SparseRow<MT,false,false> This;
2271  typedef typename RowTrait<MT>::Type ResultType;
2272  typedef typename ResultType::TransposeType TransposeType;
2273  typedef typename MT::ElementType ElementType;
2274  typedef typename MT::ReturnType ReturnType;
2275  typedef const SparseRow& CompositeType;
2276 
2278  typedef typename MT::ConstReference ConstReference;
2279 
2281  typedef typename IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference;
2282  //**********************************************************************************************
2283 
2284  //**RowElement class definition*****************************************************************
2287  template< typename MatrixType // Type of the sparse matrix
2288  , typename IteratorType > // Type of the sparse matrix iterator
2289  class RowElement : private SparseElement
2290  {
2291  private:
2292  //*******************************************************************************************
2294 
2299  enum { returnConst = IsConst<MatrixType>::value };
2300  //*******************************************************************************************
2301 
2302  //**Type definitions*************************************************************************
2304  typedef typename std::iterator_traits<IteratorType>::value_type SET;
2305 
2306  typedef typename SET::Reference RT;
2307  typedef typename SET::ConstReference CRT;
2308  //*******************************************************************************************
2309 
2310  public:
2311  //**Type definitions*************************************************************************
2312  typedef typename SET::ValueType ValueType;
2313  typedef size_t IndexType;
2314  typedef typename IfTrue<returnConst,CRT,RT>::Type Reference;
2315  typedef CRT ConstReference;
2316  //*******************************************************************************************
2317 
2318  //**Constructor******************************************************************************
2324  inline RowElement( IteratorType pos, size_t column )
2325  : pos_ ( pos ) // Iterator to the current position within the sparse row
2326  , column_( column ) // Index of the according column
2327  {}
2328  //*******************************************************************************************
2329 
2330  //**Assignment operator**********************************************************************
2336  template< typename T > inline RowElement& operator=( const T& v ) {
2337  *pos_ = v;
2338  return *this;
2339  }
2340  //*******************************************************************************************
2341 
2342  //**Addition assignment operator*************************************************************
2348  template< typename T > inline RowElement& operator+=( const T& v ) {
2349  *pos_ += v;
2350  return *this;
2351  }
2352  //*******************************************************************************************
2353 
2354  //**Subtraction assignment operator**********************************************************
2360  template< typename T > inline RowElement& operator-=( const T& v ) {
2361  *pos_ -= v;
2362  return *this;
2363  }
2364  //*******************************************************************************************
2365 
2366  //**Multiplication assignment operator*******************************************************
2372  template< typename T > inline RowElement& operator*=( const T& v ) {
2373  *pos_ *= v;
2374  return *this;
2375  }
2376  //*******************************************************************************************
2377 
2378  //**Division assignment operator*************************************************************
2384  template< typename T > inline RowElement& operator/=( const T& v ) {
2385  *pos_ /= v;
2386  return *this;
2387  }
2388  //*******************************************************************************************
2389 
2390  //**Element access operator******************************************************************
2395  inline const RowElement* operator->() const {
2396  return this;
2397  }
2398  //*******************************************************************************************
2399 
2400  //**Value function***************************************************************************
2405  inline Reference value() const {
2406  return pos_->value();
2407  }
2408  //*******************************************************************************************
2409 
2410  //**Index function***************************************************************************
2415  inline IndexType index() const {
2416  return column_;
2417  }
2418  //*******************************************************************************************
2419 
2420  private:
2421  //**Member variables*************************************************************************
2422  IteratorType pos_;
2423  size_t column_;
2424  //*******************************************************************************************
2425  };
2426  //**********************************************************************************************
2427 
2428  //**RowIterator class definition****************************************************************
2431  template< typename MatrixType // Type of the sparse matrix
2432  , typename IteratorType > // Type of the sparse matrix iterator
2433  class RowIterator
2434  {
2435  public:
2436  //**Type definitions*************************************************************************
2437  typedef std::forward_iterator_tag IteratorCategory;
2438  typedef RowElement<MatrixType,IteratorType> ValueType;
2439  typedef ValueType PointerType;
2440  typedef ValueType ReferenceType;
2441  typedef ptrdiff_t DifferenceType;
2442 
2443  // STL iterator requirements
2444  typedef IteratorCategory iterator_category;
2445  typedef ValueType value_type;
2446  typedef PointerType pointer;
2447  typedef ReferenceType reference;
2448  typedef DifferenceType difference_type;
2449  //*******************************************************************************************
2450 
2451  //**Constructor******************************************************************************
2454  inline RowIterator()
2455  : matrix_( NULL ) // The sparse matrix containing the row.
2456  , row_ ( 0UL ) // The current row index.
2457  , column_( 0UL ) // The current column index.
2458  , pos_ () // Iterator to the current sparse element.
2459  {}
2460  //*******************************************************************************************
2461 
2462  //**Constructor******************************************************************************
2469  inline RowIterator( MatrixType& matrix, size_t row, size_t column )
2470  : matrix_( &matrix ) // The sparse matrix containing the row.
2471  , row_ ( row ) // The current row index.
2472  , column_( column ) // The current column index.
2473  , pos_ () // Iterator to the current sparse element.
2474  {
2475  for( ; column_<matrix_->columns(); ++column_ ) {
2476  pos_ = matrix_->find( row_, column_ );
2477  if( pos_ != matrix_->end( column_ ) ) break;
2478  }
2479  }
2480  //*******************************************************************************************
2481 
2482  //**Constructor******************************************************************************
2490  inline RowIterator( MatrixType& matrix, size_t row, size_t column, IteratorType pos )
2491  : matrix_( &matrix ) // The sparse matrix containing the row.
2492  , row_ ( row ) // The current row index.
2493  , column_( column ) // The current column index.
2494  , pos_ ( pos ) // Iterator to the current sparse element.
2495  {
2496  BLAZE_INTERNAL_ASSERT( matrix.find( row, column ) == pos, "Invalid initial iterator position" );
2497  }
2498  //*******************************************************************************************
2499 
2500  //**Constructor******************************************************************************
2505  template< typename MatrixType2, typename IteratorType2 >
2506  inline RowIterator( const RowIterator<MatrixType2,IteratorType2>& it )
2507  : matrix_( it.matrix_ ) // The sparse matrix containing the row.
2508  , row_ ( it.row_ ) // The current row index.
2509  , column_( it.column_ ) // The current column index.
2510  , pos_ ( it.pos_ ) // Iterator to the current sparse element.
2511  {}
2512  //*******************************************************************************************
2513 
2514  //**Prefix increment operator****************************************************************
2519  inline RowIterator& operator++() {
2520  ++column_;
2521  for( ; column_<matrix_->columns(); ++column_ ) {
2522  pos_ = matrix_->find( row_, column_ );
2523  if( pos_ != matrix_->end( column_ ) ) break;
2524  }
2525 
2526  return *this;
2527  }
2528  //*******************************************************************************************
2529 
2530  //**Postfix increment operator***************************************************************
2535  inline const RowIterator operator++( int ) {
2536  const RowIterator tmp( *this );
2537  ++(*this);
2538  return tmp;
2539  }
2540  //*******************************************************************************************
2541 
2542  //**Element access operator******************************************************************
2547  inline ReferenceType operator*() const {
2548  return ReferenceType( pos_, column_ );
2549  }
2550  //*******************************************************************************************
2551 
2552  //**Element access operator******************************************************************
2557  inline PointerType operator->() const {
2558  return PointerType( pos_, column_ );
2559  }
2560  //*******************************************************************************************
2561 
2562  //**Equality operator************************************************************************
2568  template< typename MatrixType2, typename IteratorType2 >
2569  inline bool operator==( const RowIterator<MatrixType2,IteratorType2>& rhs ) const {
2570  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
2571  }
2572  //*******************************************************************************************
2573 
2574  //**Inequality operator**********************************************************************
2580  template< typename MatrixType2, typename IteratorType2 >
2581  inline bool operator!=( const RowIterator<MatrixType2,IteratorType2>& rhs ) const {
2582  return !( *this == rhs );
2583  }
2584  //*******************************************************************************************
2585 
2586  //**Subtraction operator*********************************************************************
2592  inline DifferenceType operator-( const RowIterator& rhs ) const {
2593  size_t counter( 0UL );
2594  for( size_t j=rhs.column_; j<column_; ++j ) {
2595  if( matrix_->find( row_, j ) != matrix_->end( j ) )
2596  ++counter;
2597  }
2598  return counter;
2599  }
2600  //*******************************************************************************************
2601 
2602  private:
2603  //**Member variables*************************************************************************
2604  MatrixType* matrix_;
2605  size_t row_;
2606  size_t column_;
2607  IteratorType pos_;
2608  //*******************************************************************************************
2609 
2610  //**Friend declarations**********************************************************************
2611  template< typename MatrixType2, typename IteratorType2 > friend class RowIterator;
2612  template< typename MT2, bool SO2, bool SF2 > friend class SparseRow;
2613  //*******************************************************************************************
2614  };
2615  //**********************************************************************************************
2616 
2617  //**Type definitions****************************************************************************
2619  typedef RowIterator<const MT,typename MT::ConstIterator> ConstIterator;
2620 
2622  typedef typename IfTrue< useConst, ConstIterator, RowIterator<MT,typename MT::Iterator> >::Type Iterator;
2623  //**********************************************************************************************
2624 
2625  //**Compilation flags***************************************************************************
2627  enum { smpAssignable = 0 };
2628  //**********************************************************************************************
2629 
2630  //**Constructors********************************************************************************
2633  explicit inline SparseRow( MT& matrix, size_t index );
2634  // No explicitly declared copy constructor.
2636  //**********************************************************************************************
2637 
2638  //**Destructor**********************************************************************************
2639  // No explicitly declared destructor.
2640  //**********************************************************************************************
2641 
2642  //**Data access functions***********************************************************************
2645  inline Reference operator[]( size_t index );
2646  inline ConstReference operator[]( size_t index ) const;
2647  inline Iterator begin ();
2648  inline ConstIterator begin () const;
2649  inline ConstIterator cbegin() const;
2650  inline Iterator end ();
2651  inline ConstIterator end () const;
2652  inline ConstIterator cend () const;
2654  //**********************************************************************************************
2655 
2656  //**Assignment operators************************************************************************
2659  inline SparseRow& operator= ( const SparseRow& rhs );
2660  template< typename VT > inline SparseRow& operator= ( const Vector<VT,true>& rhs );
2661  template< typename VT > inline SparseRow& operator+=( const Vector<VT,true>& rhs );
2662  template< typename VT > inline SparseRow& operator-=( const Vector<VT,true>& rhs );
2663  template< typename VT > inline SparseRow& operator*=( const Vector<VT,true>& rhs );
2664 
2665  template< typename Other >
2666  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
2667  operator*=( Other rhs );
2668 
2669  template< typename Other >
2670  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
2671  operator/=( Other rhs );
2673  //**********************************************************************************************
2674 
2675  //**Utility functions***************************************************************************
2678  inline size_t size() const;
2679  inline size_t capacity() const;
2680  inline size_t nonZeros() const;
2681  inline void reset();
2682  inline Iterator set ( size_t index, const ElementType& value );
2683  inline Iterator insert ( size_t index, const ElementType& value );
2684  inline void erase ( size_t index );
2685  inline Iterator erase ( Iterator pos );
2686  inline Iterator erase ( Iterator first, Iterator last );
2687  inline void reserve( size_t n );
2688  template< typename Other > inline SparseRow& scale ( const Other& scalar );
2690  //**********************************************************************************************
2691 
2692  //**Lookup functions****************************************************************************
2695  inline Iterator find ( size_t index );
2696  inline ConstIterator find ( size_t index ) const;
2697  inline Iterator lowerBound( size_t index );
2698  inline ConstIterator lowerBound( size_t index ) const;
2699  inline Iterator upperBound( size_t index );
2700  inline ConstIterator upperBound( size_t index ) const;
2702  //**********************************************************************************************
2703 
2704  //**Low-level utility functions*****************************************************************
2707  inline void append( size_t index, const ElementType& value, bool check=false );
2709  //**********************************************************************************************
2710 
2711  //**Expression template evaluation functions****************************************************
2714  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2715  template< typename Other > inline bool isAliased( const Other* alias ) const;
2716 
2717  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
2718  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
2719  template< typename VT > inline void addAssign( const Vector<VT,true>& rhs );
2720  template< typename VT > inline void subAssign( const Vector<VT,true>& rhs );
2722  //**********************************************************************************************
2723 
2724  private:
2725  //**Utility functions***************************************************************************
2728  template< typename MT2, bool SO2, typename VT >
2729  inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
2730  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,true>& rhs );
2731 
2732  template< typename MT2, bool SO2, typename VT >
2733  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2734  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs );
2735 
2736  template< typename MT2, bool SO2, typename VT >
2737  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2738  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs );
2739 
2740  template< typename MT2, bool SO2, typename VT >
2741  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2742  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs );
2743 
2744  template< typename MT2, bool SO2, typename VT >
2745  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2746  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs );
2747 
2748  template< typename MT2, bool SO2, typename VT >
2749  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2750  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs );
2751 
2752  template< typename MT2, bool SO2, typename VT >
2753  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2754  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs );
2756  //**********************************************************************************************
2757 
2758  //**Member variables****************************************************************************
2761  Operand matrix_;
2762  const size_t row_;
2763 
2764  //**********************************************************************************************
2765 
2766  //**Friend declarations*************************************************************************
2767  template< typename MT2, bool SO2, bool SF2 >
2768  friend bool isSame( const SparseRow<MT2,SO2,SF2>& a, const SparseRow<MT2,SO2,SF2>& b );
2769 
2770  template< typename MT2, bool SO2, bool SF2 >
2771  friend typename DerestrictTrait< SparseRow<MT2,SO2,SF2> >::Type
2772  derestrict( SparseRow<MT2,SO2,SF2>& dm );
2773  //**********************************************************************************************
2774 
2775  //**Compile time checks*************************************************************************
2783  BLAZE_STATIC_ASSERT( !IsRestricted<MT>::value || IsLower<MT>::value || IsUpper<MT>::value );
2784  //**********************************************************************************************
2785 };
2787 //*************************************************************************************************
2788 
2789 
2790 
2791 
2792 //=================================================================================================
2793 //
2794 // CONSTRUCTOR
2795 //
2796 //=================================================================================================
2797 
2798 //*************************************************************************************************
2806 template< typename MT > // Type of the sparse matrix
2807 inline SparseRow<MT,false,false>::SparseRow( MT& matrix, size_t index )
2808  : matrix_( matrix ) // The sparse matrix containing the row
2809  , row_ ( index ) // The index of the row in the matrix
2810 {
2811  if( matrix_.rows() <= index )
2812  throw std::invalid_argument( "Invalid row access index" );
2813 }
2815 //*************************************************************************************************
2816 
2817 
2818 
2819 
2820 //=================================================================================================
2821 //
2822 // DATA ACCESS FUNCTIONS
2823 //
2824 //=================================================================================================
2825 
2826 //*************************************************************************************************
2833 template< typename MT > // Type of the sparse matrix
2836 {
2837  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2838  return matrix_(row_,index);
2839 }
2841 //*************************************************************************************************
2842 
2843 
2844 //*************************************************************************************************
2851 template< typename MT > // Type of the sparse matrix
2853  SparseRow<MT,false,false>::operator[]( size_t index ) const
2854 {
2855  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2856  return const_cast<const MT&>( matrix_ )(row_,index);
2857 }
2859 //*************************************************************************************************
2860 
2861 
2862 //*************************************************************************************************
2870 template< typename MT > // Type of the sparse matrix
2872 {
2873  return Iterator( matrix_, row_, 0UL );
2874 }
2876 //*************************************************************************************************
2877 
2878 
2879 //*************************************************************************************************
2887 template< typename MT > // Type of the sparse matrix
2889 {
2890  return ConstIterator( matrix_, row_, 0UL );
2891 }
2893 //*************************************************************************************************
2894 
2895 
2896 //*************************************************************************************************
2904 template< typename MT > // Type of the sparse matrix
2906 {
2907  return ConstIterator( matrix_, row_, 0UL );
2908 }
2910 //*************************************************************************************************
2911 
2912 
2913 //*************************************************************************************************
2921 template< typename MT > // Type of the sparse matrix
2923 {
2924  return Iterator( matrix_, row_, size() );
2925 }
2927 //*************************************************************************************************
2928 
2929 
2930 //*************************************************************************************************
2938 template< typename MT > // Type of the sparse matrix
2940 {
2941  return ConstIterator( matrix_, row_, size() );
2942 }
2944 //*************************************************************************************************
2945 
2946 
2947 //*************************************************************************************************
2955 template< typename MT > // Type of the sparse matrix
2957 {
2958  return ConstIterator( matrix_, row_, size() );
2959 }
2961 //*************************************************************************************************
2962 
2963 
2964 
2965 
2966 //=================================================================================================
2967 //
2968 // ASSIGNMENT OPERATORS
2969 //
2970 //=================================================================================================
2971 
2972 //*************************************************************************************************
2986 template< typename MT > // Type of the sparse matrix
2987 inline SparseRow<MT,false,false>& SparseRow<MT,false,false>::operator=( const SparseRow& rhs )
2988 {
2989  using blaze::assign;
2990 
2994 
2995  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
2996  return *this;
2997 
2998  if( size() != rhs.size() )
2999  throw std::invalid_argument( "Row sizes do not match" );
3000 
3001  if( !preservesInvariant( matrix_, rhs ) )
3002  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
3003 
3004  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3005 
3006  if( rhs.canAlias( &matrix_ ) ) {
3007  const ResultType tmp( rhs );
3008  assign( left, tmp );
3009  }
3010  else {
3011  assign( left, rhs );
3012  }
3013 
3014  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3015  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3016 
3017  return *this;
3018 }
3020 //*************************************************************************************************
3021 
3022 
3023 //*************************************************************************************************
3037 template< typename MT > // Type of the sparse matrix
3038 template< typename VT > // Type of the right-hand side vector
3039 inline SparseRow<MT,false,false>& SparseRow<MT,false,false>::operator=( const Vector<VT,true>& rhs )
3040 {
3041  using blaze::assign;
3042 
3043  if( size() != (~rhs).size() )
3044  throw std::invalid_argument( "Vector sizes do not match" );
3045 
3046  const typename VT::CompositeType tmp( ~rhs );
3047 
3048  if( !preservesInvariant( matrix_, tmp ) )
3049  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
3050 
3051  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3052 
3053  assign( left, tmp );
3054 
3055  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3056  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3057 
3058  return *this;
3059 }
3061 //*************************************************************************************************
3062 
3063 
3064 //*************************************************************************************************
3078 template< typename MT > // Type of the sparse matrix
3079 template< typename VT > // Type of the right-hand side vector
3080 inline SparseRow<MT,false,false>& SparseRow<MT,false,false>::operator+=( const Vector<VT,true>& rhs )
3081 {
3082  using blaze::assign;
3083 
3089 
3090  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
3091 
3094 
3095  if( size() != (~rhs).size() )
3096  throw std::invalid_argument( "Vector sizes do not match" );
3097 
3098  const AddType tmp( *this + (~rhs) );
3099 
3100  if( !preservesInvariant( matrix_, tmp ) )
3101  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
3102 
3103  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3104 
3105  assign( left, tmp );
3106 
3107  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3108  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3109 
3110  return *this;
3111 }
3113 //*************************************************************************************************
3114 
3115 
3116 //*************************************************************************************************
3130 template< typename MT > // Type of the sparse matrix
3131 template< typename VT > // Type of the right-hand side vector
3132 inline SparseRow<MT,false,false>& SparseRow<MT,false,false>::operator-=( const Vector<VT,true>& rhs )
3133 {
3134  using blaze::assign;
3135 
3141 
3142  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
3143 
3146 
3147  if( size() != (~rhs).size() )
3148  throw std::invalid_argument( "Vector sizes do not match" );
3149 
3150  const SubType tmp( *this - (~rhs) );
3151 
3152  if( !preservesInvariant( matrix_, tmp ) )
3153  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
3154 
3155  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3156 
3157  assign( left, tmp );
3158 
3159  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3160  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3161 
3162  return *this;
3163 }
3165 //*************************************************************************************************
3166 
3167 
3168 //*************************************************************************************************
3180 template< typename MT > // Type of the sparse matrix
3181 template< typename VT > // Type of the right-hand side vector
3182 inline SparseRow<MT,false,false>& SparseRow<MT,false,false>::operator*=( const Vector<VT,true>& rhs )
3183 {
3184  using blaze::assign;
3185 
3191 
3192  typedef typename MultTrait<ResultType,typename VT::ResultType>::Type MultType;
3193 
3196 
3197  if( size() != (~rhs).size() )
3198  throw std::invalid_argument( "Vector sizes do not match" );
3199 
3200  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3201 
3202  const MultType tmp( *this * (~rhs) );
3203  assign( left, tmp );
3204 
3205  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3206  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3207 
3208  return *this;
3209 }
3211 //*************************************************************************************************
3212 
3213 
3214 //*************************************************************************************************
3229 template< typename MT > // Type of the sparse matrix
3230 template< typename Other > // Data type of the right-hand side scalar
3231 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,false,false> >::Type&
3232  SparseRow<MT,false,false>::operator*=( Other rhs )
3233 {
3235 
3236  for( Iterator element=begin(); element!=end(); ++element )
3237  element->value() *= rhs;
3238  return *this;
3239 }
3241 //*************************************************************************************************
3242 
3243 
3244 //*************************************************************************************************
3262 template< typename MT > // Type of the sparse matrix
3263 template< typename Other > // Data type of the right-hand side scalar
3264 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,false,false> >::Type&
3265  SparseRow<MT,false,false>::operator/=( Other rhs )
3266 {
3268 
3269  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3270 
3271  typedef typename DivTrait<ElementType,Other>::Type DT;
3272  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3273 
3274  // Depending on the two involved data types, an integer division is applied or a
3275  // floating point division is selected.
3276  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3277  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3278  for( Iterator element=begin(); element!=end(); ++element )
3279  element->value() *= tmp;
3280  }
3281  else {
3282  for( Iterator element=begin(); element!=end(); ++element )
3283  element->value() /= rhs;
3284  }
3285 
3286  return *this;
3287 }
3289 //*************************************************************************************************
3290 
3291 
3292 
3293 
3294 //=================================================================================================
3295 //
3296 // UTILITY FUNCTIONS
3297 //
3298 //=================================================================================================
3299 
3300 //*************************************************************************************************
3306 template< typename MT > // Type of the sparse matrix
3307 inline size_t SparseRow<MT,false,false>::size() const
3308 {
3309  return matrix_.columns();
3310 }
3312 //*************************************************************************************************
3313 
3314 
3315 //*************************************************************************************************
3321 template< typename MT > // Type of the sparse matrix
3322 inline size_t SparseRow<MT,false,false>::capacity() const
3323 {
3324  return matrix_.columns();
3325 }
3327 //*************************************************************************************************
3328 
3329 
3330 //*************************************************************************************************
3339 template< typename MT > // Type of the sparse matrix
3340 inline size_t SparseRow<MT,false,false>::nonZeros() const
3341 {
3342  size_t counter( 0UL );
3343  for( ConstIterator element=begin(); element!=end(); ++element ) {
3344  ++counter;
3345  }
3346  return counter;
3347 }
3349 //*************************************************************************************************
3350 
3351 
3352 //*************************************************************************************************
3358 template< typename MT > // Type of the sparse matrix
3360 {
3361  const size_t jbegin( ( IsUpper<MT>::value )
3362  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3363  ?( row_+1UL )
3364  :( row_ ) )
3365  :( 0UL ) );
3366  const size_t jend ( ( IsLower<MT>::value )
3367  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3368  ?( row_ )
3369  :( row_+1UL ) )
3370  :( size() ) );
3371 
3372  for( size_t j=jbegin; j<jend; ++j ) {
3373  matrix_.erase( row_, j );
3374  }
3375 }
3377 //*************************************************************************************************
3378 
3379 
3380 //*************************************************************************************************
3393 template< typename MT > // Type of the sparse matrix
3395  SparseRow<MT,false,false>::insert( size_t index, const ElementType& value )
3396 {
3397  return Iterator( matrix_, row_, index, matrix_.insert( row_, index, value ) );
3398 }
3400 //*************************************************************************************************
3401 
3402 
3403 //*************************************************************************************************
3415 template< typename MT > // Type of the sparse matrix
3417  SparseRow<MT,false,false>::set( size_t index, const ElementType& value )
3418 {
3419  return Iterator( matrix_, row_, index, matrix_.set( row_, index, value ) );
3420 }
3422 //*************************************************************************************************
3423 
3424 
3425 //*************************************************************************************************
3434 template< typename MT > // Type of the sparse matrix
3435 inline void SparseRow<MT,false,false>::erase( size_t index )
3436 {
3437  matrix_.erase( row_, index );
3438 }
3440 //*************************************************************************************************
3441 
3442 
3443 //*************************************************************************************************
3452 template< typename MT > // Type of the sparse matrix
3454 {
3455  const size_t column( pos.column_ );
3456 
3457  if( column == size() )
3458  return pos;
3459 
3460  matrix_.erase( column, pos.pos_ );
3461  return Iterator( matrix_, row_, column+1UL );
3462 }
3464 //*************************************************************************************************
3465 
3466 
3467 //*************************************************************************************************
3477 template< typename MT > // Type of the sparse matrix
3480 {
3481  for( ; first!=last; ++first ) {
3482  matrix_.erase( first.column_, first.pos_ );
3483  }
3484  return last;
3485 }
3487 //*************************************************************************************************
3488 
3489 
3490 //*************************************************************************************************
3500 template< typename MT > // Type of the sparse matrix
3501 void SparseRow<MT,false,false>::reserve( size_t n )
3502 {
3503  UNUSED_PARAMETER( n );
3504 
3505  return;
3506 }
3508 //*************************************************************************************************
3509 
3510 
3511 //*************************************************************************************************
3522 template< typename MT > // Type of the sparse matrix
3523 template< typename Other > // Data type of the scalar value
3524 inline SparseRow<MT,false,false>& SparseRow<MT,false,false>::scale( const Other& scalar )
3525 {
3527 
3528  for( Iterator element=begin(); element!=end(); ++element )
3529  element->value() *= scalar;
3530  return *this;
3531 }
3533 //*************************************************************************************************
3534 
3535 
3536 //*************************************************************************************************
3548 template< typename MT > // Type of the sparse matrix
3549 template< typename MT2 // Type of the left-hand side sparse matrix
3550  , bool SO2 // Storage order of the left-hand side sparse matrix
3551  , typename VT > // Type of the right-hand side vector
3552 inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
3553  SparseRow<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,true>& rhs )
3554 {
3555  UNUSED_PARAMETER( lhs, rhs );
3556 
3557  return true;
3558 }
3560 //*************************************************************************************************
3561 
3562 
3563 //*************************************************************************************************
3575 template< typename MT > // Type of the sparse matrix
3576 template< typename MT2 // Type of the left-hand side sparse matrix
3577  , bool SO2 // Storage order of the left-hand side sparse matrix
3578  , typename VT > // Type of the right-hand side dense vector
3579 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3580  SparseRow<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs )
3581 {
3583 
3584  UNUSED_PARAMETER( lhs );
3585 
3586  if( IsUniLower<MT2>::value && !isOne( (~rhs)[row_] ) )
3587  return false;
3588 
3589  const size_t ibegin( ( IsStrictlyLower<MT2>::value )?( row_ ):( row_+1UL ) );
3590 
3591  for( size_t i=ibegin; i<size(); ++i ) {
3592  if( !isDefault( (~rhs)[i] ) )
3593  return false;
3594  }
3595 
3596  return true;
3597 }
3599 //*************************************************************************************************
3600 
3601 
3602 //*************************************************************************************************
3614 template< typename MT > // Type of the sparse matrix
3615 template< typename MT2 // Type of the left-hand side sparse matrix
3616  , bool SO2 // Storage order of the left-hand side sparse matrix
3617  , typename VT > // Type of the right-hand side sparse vector
3618 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3619  SparseRow<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs )
3620 {
3622 
3623  UNUSED_PARAMETER( lhs );
3624 
3625  typedef typename VT::ConstIterator RhsIterator;
3626 
3627  const bool checkDiagonal( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value );
3628  const RhsIterator last( (~rhs).end() );
3629  RhsIterator element( (~rhs).lowerBound( ( checkDiagonal )?( row_ ):( row_+1UL ) ) );
3630 
3631  if( IsUniLower<MT2>::value ) {
3632  if( element == last || element->index() != row_ || !isOne( element->value() ) )
3633  return false;
3634  ++element;
3635  }
3636 
3637  for( ; element!=last; ++element ) {
3638  if( !isDefault( element->value() ) )
3639  return false;
3640  }
3641 
3642  return true;
3643 }
3645 //*************************************************************************************************
3646 
3647 
3648 //*************************************************************************************************
3660 template< typename MT > // Type of the sparse matrix
3661 template< typename MT2 // Type of the left-hand side sparse matrix
3662  , bool SO2 // Storage order of the left-hand side sparse matrix
3663  , typename VT > // Type of the right-hand side dense vector
3664 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3665  SparseRow<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs )
3666 {
3668 
3669  UNUSED_PARAMETER( lhs );
3670 
3671  const size_t iend( ( IsStrictlyUpper<MT2>::value )?( row_+1UL ):( row_ ) );
3672 
3673  for( size_t i=0UL; i<iend; ++i ) {
3674  if( !isDefault( (~rhs)[i] ) )
3675  return false;
3676  }
3677 
3678  if( IsUniUpper<MT2>::value && !isOne( (~rhs)[row_] ) )
3679  return false;
3680 
3681  return true;
3682 }
3684 //*************************************************************************************************
3685 
3686 
3687 //*************************************************************************************************
3699 template< typename MT > // Type of the sparse matrix
3700 template< typename MT2 // Type of the left-hand side sparse matrix
3701  , bool SO2 // Storage order of the left-hand side sparse matrix
3702  , typename VT > // Type of the right-hand side sparse vector
3703 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3704  SparseRow<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs )
3705 {
3707 
3708  UNUSED_PARAMETER( lhs );
3709 
3710  typedef typename VT::ConstIterator RhsIterator;
3711 
3712  const RhsIterator last( (~rhs).lowerBound( ( IsStrictlyUpper<MT2>::value )?( row_+1UL ):( row_ ) ) );
3713 
3714  if( IsUniUpper<MT2>::value && ( last == (~rhs).end() || last->index() != row_ || !isOne( last->value() ) ) )
3715  return false;
3716 
3717  for( RhsIterator element=(~rhs).begin(); element!=last; ++element ) {
3718  if( !isDefault( element->value() ) )
3719  return false;
3720  }
3721 
3722  return true;
3723 }
3725 //*************************************************************************************************
3726 
3727 
3728 //*************************************************************************************************
3740 template< typename MT > // Type of the sparse matrix
3741 template< typename MT2 // Type of the left-hand side sparse matrix
3742  , bool SO2 // Storage order of the left-hand side sparse matrix
3743  , typename VT > // Type of the right-hand side dense vector
3744 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
3745  SparseRow<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs )
3746 {
3748 
3749  UNUSED_PARAMETER( lhs );
3750 
3751  for( size_t i=0UL; i<row_; ++i ) {
3752  if( !isDefault( (~rhs)[i] ) )
3753  return false;
3754  }
3755 
3756  for( size_t i=row_+1UL; i<size(); ++i ) {
3757  if( !isDefault( (~rhs)[i] ) )
3758  return false;
3759  }
3760 
3761  return true;
3762 }
3764 //*************************************************************************************************
3765 
3766 
3767 //*************************************************************************************************
3779 template< typename MT > // Type of the sparse matrix
3780 template< typename MT2 // Type of the left-hand side sparse matrix
3781  , bool SO2 // Storage order of the left-hand side sparse matrix
3782  , typename VT > // Type of the right-hand side sparse vector
3783 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
3784  SparseRow<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs )
3785 {
3787 
3788  UNUSED_PARAMETER( lhs );
3789 
3790  typedef typename VT::ConstIterator RhsIterator;
3791 
3792  for( RhsIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
3793  if( element->index() != row_ && !isDefault( element->value() ) )
3794  return false;
3795  }
3796 
3797  return true;
3798 }
3800 //*************************************************************************************************
3801 
3802 
3803 
3804 
3805 //=================================================================================================
3806 //
3807 // LOOKUP FUNCTIONS
3808 //
3809 //=================================================================================================
3810 
3811 //*************************************************************************************************
3825 template< typename MT > // Type of the sparse matrix
3827 {
3828  const typename MT::Iterator pos( matrix_.find( row_, index ) );
3829 
3830  if( pos != matrix_.end( index ) )
3831  return Iterator( matrix_, row_, index, pos );
3832  else
3833  return end();
3834 }
3836 //*************************************************************************************************
3837 
3838 
3839 //*************************************************************************************************
3853 template< typename MT > // Type of the sparse matrix
3855  SparseRow<MT,false,false>::find( size_t index ) const
3856 {
3857  const typename MT::ConstIterator pos( matrix_.find( row_, index ) );
3858 
3859  if( pos != matrix_.end( index ) )
3860  return ConstIterator( matrix_, row_, index, pos );
3861  else
3862  return end();
3863 }
3865 //*************************************************************************************************
3866 
3867 
3868 //*************************************************************************************************
3881 template< typename MT > // Type of the sparse matrix
3884 {
3885  for( size_t i=index; i<size(); ++i )
3886  {
3887  const typename MT::Iterator pos( matrix_.find( row_, i ) );
3888 
3889  if( pos != matrix_.end( i ) )
3890  return Iterator( matrix_, row_, i, pos );
3891  }
3892 
3893  return end();
3894 }
3896 //*************************************************************************************************
3897 
3898 
3899 //*************************************************************************************************
3912 template< typename MT > // Type of the sparse matrix
3914  SparseRow<MT,false,false>::lowerBound( size_t index ) const
3915 {
3916  for( size_t i=index; i<size(); ++i )
3917  {
3918  const typename MT::ConstIterator pos( matrix_.find( row_, i ) );
3919 
3920  if( pos != matrix_.end( i ) )
3921  return ConstIterator( matrix_, row_, i, pos );
3922  }
3923 
3924  return end();
3925 }
3927 //*************************************************************************************************
3928 
3929 
3930 //*************************************************************************************************
3943 template< typename MT > // Type of the sparse matrix
3946 {
3947  for( size_t i=index+1UL; i<size(); ++i )
3948  {
3949  const typename MT::Iterator pos( matrix_.find( row_, i ) );
3950 
3951  if( pos != matrix_.end( i ) )
3952  return Iterator( matrix_, row_, i, pos );
3953  }
3954 
3955  return end();
3956 }
3958 //*************************************************************************************************
3959 
3960 
3961 //*************************************************************************************************
3974 template< typename MT > // Type of the sparse matrix
3976  SparseRow<MT,false,false>::upperBound( size_t index ) const
3977 {
3978  for( size_t i=index+1UL; i<size(); ++i )
3979  {
3980  const typename MT::ConstIterator pos( matrix_.find( row_, i ) );
3981 
3982  if( pos != matrix_.end( i ) )
3983  return ConstIterator( matrix_, row_, i, pos );
3984  }
3985 
3986  return end();
3987 }
3989 //*************************************************************************************************
3990 
3991 
3992 
3993 
3994 //=================================================================================================
3995 //
3996 // LOW-LEVEL UTILITY FUNCTIONS
3997 //
3998 //=================================================================================================
3999 
4000 //*************************************************************************************************
4025 template< typename MT > // Type of the sparse matrix
4026 inline void SparseRow<MT,false,false>::append( size_t index, const ElementType& value, bool check )
4027 {
4028  if( !check || !isDefault( value ) )
4029  matrix_.insert( row_, index, value );
4030 }
4032 //*************************************************************************************************
4033 
4034 
4035 
4036 
4037 //=================================================================================================
4038 //
4039 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4040 //
4041 //=================================================================================================
4042 
4043 //*************************************************************************************************
4054 template< typename MT > // Type of the sparse matrix
4055 template< typename Other > // Data type of the foreign expression
4056 inline bool SparseRow<MT,false,false>::canAlias( const Other* alias ) const
4057 {
4058  return matrix_.isAliased( alias );
4059 }
4061 //*************************************************************************************************
4062 
4063 
4064 //*************************************************************************************************
4071 template< typename MT > // Type of the sparse matrix
4072 template< typename Other > // Data type of the foreign expression
4073 inline bool SparseRow<MT,false,false>::isAliased( const Other* alias ) const
4074 {
4075  return matrix_.isAliased( alias );
4076 }
4078 //*************************************************************************************************
4079 
4080 
4081 //*************************************************************************************************
4093 template< typename MT > // Type of the sparse matrix
4094 template< typename VT > // Type of the right-hand side dense vector
4095 inline void SparseRow<MT,false,false>::assign( const DenseVector<VT,true>& rhs )
4096 {
4098 
4099  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4100 
4101  for( size_t j=0UL; j<(~rhs).size(); ++j ) {
4102  matrix_(row_,j) = (~rhs)[j];
4103  }
4104 }
4106 //*************************************************************************************************
4107 
4108 
4109 //*************************************************************************************************
4121 template< typename MT > // Type of the sparse matrix
4122 template< typename VT > // Type of the right-hand side sparse vector
4123 inline void SparseRow<MT,false,false>::assign( const SparseVector<VT,true>& rhs )
4124 {
4126 
4127  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4128 
4129  size_t j( 0UL );
4130 
4131  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
4132  for( ; j<element->index(); ++j )
4133  matrix_.erase( row_, j );
4134  matrix_(row_,j++) = element->value();
4135  }
4136  for( ; j<size(); ++j ) {
4137  matrix_.erase( row_, j );
4138  }
4139 }
4141 //*************************************************************************************************
4142 
4143 
4144 //*************************************************************************************************
4156 template< typename MT > // Type of the sparse matrix
4157 template< typename VT > // Type of the right-hand side vector
4158 inline void SparseRow<MT,false,false>::addAssign( const Vector<VT,true>& rhs )
4159 {
4161 
4162  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
4163 
4166 
4167  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4168 
4169  const AddType tmp( serial( *this + (~rhs) ) );
4170  assign( tmp );
4171 }
4173 //*************************************************************************************************
4174 
4175 
4176 //*************************************************************************************************
4188 template< typename MT > // Type of the sparse matrix
4189 template< typename VT > // Type of the right-hand side vector
4190 inline void SparseRow<MT,false,false>::subAssign( const Vector<VT,true>& rhs )
4191 {
4193 
4194  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
4195 
4198 
4199  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4200 
4201  const SubType tmp( serial( *this - (~rhs) ) );
4202  assign( tmp );
4203 }
4205 //*************************************************************************************************
4206 
4207 
4208 
4209 
4210 
4211 
4212 
4213 
4214 //=================================================================================================
4215 //
4216 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR MATRICES
4217 //
4218 //=================================================================================================
4219 
4220 //*************************************************************************************************
4228 template< typename MT > // Type of the sparse matrix
4229 class SparseRow<MT,false,true> : public SparseVector< SparseRow<MT,false,true>, true >
4230  , private Row
4231 {
4232  private:
4233  //**Type definitions****************************************************************************
4235  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
4236  //**********************************************************************************************
4237 
4238  //**********************************************************************************************
4240 
4246  enum { useConst = IsConst<MT>::value };
4247  //**********************************************************************************************
4248 
4249  public:
4250  //**Type definitions****************************************************************************
4251  typedef SparseRow<MT,false,true> This;
4252  typedef typename RowTrait<MT>::Type ResultType;
4253  typedef typename ResultType::TransposeType TransposeType;
4254  typedef typename MT::ElementType ElementType;
4255  typedef typename MT::ReturnType ReturnType;
4256  typedef const SparseRow& CompositeType;
4257 
4259  typedef typename MT::ConstReference ConstReference;
4260 
4262  typedef typename IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference;
4263 
4265  typedef typename MT::ConstIterator ConstIterator;
4266 
4268  typedef typename IfTrue< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
4269  //**********************************************************************************************
4270 
4271  //**Compilation flags***************************************************************************
4273  enum { smpAssignable = 0 };
4274  //**********************************************************************************************
4275 
4276  //**Constructors********************************************************************************
4279  explicit inline SparseRow( MT& matrix, size_t index );
4280  // No explicitly declared copy constructor.
4282  //**********************************************************************************************
4283 
4284  //**Destructor**********************************************************************************
4285  // No explicitly declared destructor.
4286  //**********************************************************************************************
4287 
4288  //**Data access functions***********************************************************************
4291  inline Reference operator[]( size_t index );
4292  inline ConstReference operator[]( size_t index ) const;
4293  inline Iterator begin ();
4294  inline ConstIterator begin () const;
4295  inline ConstIterator cbegin() const;
4296  inline Iterator end ();
4297  inline ConstIterator end () const;
4298  inline ConstIterator cend () const;
4300  //**********************************************************************************************
4301 
4302  //**Assignment operators************************************************************************
4305  inline SparseRow& operator=( const SparseRow& rhs );
4306 
4307  template< typename VT > inline SparseRow& operator= ( const DenseVector<VT,true>& rhs );
4308  template< typename VT > inline SparseRow& operator= ( const SparseVector<VT,true>& rhs );
4309  template< typename VT > inline SparseRow& operator+=( const DenseVector<VT,true>& rhs );
4310  template< typename VT > inline SparseRow& operator+=( const SparseVector<VT,true>& rhs );
4311  template< typename VT > inline SparseRow& operator-=( const DenseVector<VT,true>& rhs );
4312  template< typename VT > inline SparseRow& operator-=( const SparseVector<VT,true>& rhs );
4313  template< typename VT > inline SparseRow& operator*=( const Vector<VT,true>& rhs );
4314 
4315  template< typename Other >
4316  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
4317  operator*=( Other rhs );
4318 
4319  template< typename Other >
4320  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
4321  operator/=( Other rhs );
4323  //**********************************************************************************************
4324 
4325  //**Utility functions***************************************************************************
4328  inline size_t size() const;
4329  inline size_t capacity() const;
4330  inline size_t nonZeros() const;
4331  inline void reset();
4332  inline Iterator set ( size_t index, const ElementType& value );
4333  inline Iterator insert ( size_t index, const ElementType& value );
4334  inline void erase ( size_t index );
4335  inline Iterator erase ( Iterator pos );
4336  inline Iterator erase ( Iterator first, Iterator last );
4337  inline void reserve( size_t n );
4338  template< typename Other > inline SparseRow& scale ( const Other& scalar );
4340  //**********************************************************************************************
4341 
4342  //**Lookup functions****************************************************************************
4345  inline Iterator find ( size_t index );
4346  inline ConstIterator find ( size_t index ) const;
4347  inline Iterator lowerBound( size_t index );
4348  inline ConstIterator lowerBound( size_t index ) const;
4349  inline Iterator upperBound( size_t index );
4350  inline ConstIterator upperBound( size_t index ) const;
4352  //**********************************************************************************************
4353 
4354  //**Low-level utility functions*****************************************************************
4357  inline void append( size_t index, const ElementType& value, bool check=false );
4359  //**********************************************************************************************
4360 
4361  //**Expression template evaluation functions****************************************************
4364  template< typename Other > inline bool canAlias ( const Other* alias ) const;
4365  template< typename Other > inline bool isAliased( const Other* alias ) const;
4366 
4367  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
4368  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
4369  template< typename VT > inline void addAssign( const DenseVector <VT,true>& rhs );
4370  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
4371  template< typename VT > inline void subAssign( const DenseVector <VT,true>& rhs );
4372  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
4374  //**********************************************************************************************
4375 
4376  private:
4377  //**Utility functions***************************************************************************
4380  inline size_t extendCapacity() const;
4381 
4382  template< typename MT2, bool SO2, typename VT >
4383  inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
4384  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,true>& rhs );
4385 
4386  template< typename MT2, bool SO2, typename VT >
4387  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4388  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs );
4389 
4390  template< typename MT2, bool SO2, typename VT >
4391  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4392  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs );
4393 
4394  template< typename MT2, bool SO2, typename VT >
4395  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4396  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs );
4397 
4398  template< typename MT2, bool SO2, typename VT >
4399  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4400  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs );
4401 
4402  template< typename MT2, bool SO2, typename VT >
4403  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4404  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs );
4405 
4406  template< typename MT2, bool SO2, typename VT >
4407  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4408  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs );
4410  //**********************************************************************************************
4411 
4412  //**Member variables****************************************************************************
4415  Operand matrix_;
4416  const size_t row_;
4417 
4418  //**********************************************************************************************
4419 
4420  //**Friend declarations*************************************************************************
4421  template< typename MT2, bool SO2, bool SF2 >
4422  friend bool isSame( const SparseRow<MT2,SO2,SF2>& a, const SparseRow<MT2,SO2,SF2>& b );
4423 
4424  template< typename MT2, bool SO2, bool SF2 >
4425  friend typename DerestrictTrait< SparseRow<MT2,SO2,SF2> >::Type
4426  derestrict( SparseRow<MT2,SO2,SF2>& dm );
4427  //**********************************************************************************************
4428 
4429  //**Compile time checks*************************************************************************
4437  BLAZE_STATIC_ASSERT( !IsRestricted<MT>::value || IsLower<MT>::value || IsUpper<MT>::value );
4438  //**********************************************************************************************
4439 };
4441 //*************************************************************************************************
4442 
4443 
4444 
4445 
4446 //=================================================================================================
4447 //
4448 // CONSTRUCTOR
4449 //
4450 //=================================================================================================
4451 
4452 //*************************************************************************************************
4460 template< typename MT > // Type of the sparse matrix
4461 inline SparseRow<MT,false,true>::SparseRow( MT& matrix, size_t index )
4462  : matrix_( matrix ) // The sparse matrix containing the row
4463  , row_ ( index ) // The index of the row in the matrix
4464 {
4465  if( matrix_.rows() <= index )
4466  throw std::invalid_argument( "Invalid row access index" );
4467 }
4469 //*************************************************************************************************
4470 
4471 
4472 
4473 
4474 //=================================================================================================
4475 //
4476 // DATA ACCESS FUNCTIONS
4477 //
4478 //=================================================================================================
4479 
4480 //*************************************************************************************************
4487 template< typename MT > // Type of the sparse matrix
4489  SparseRow<MT,false,true>::operator[]( size_t index )
4490 {
4491  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4492  return matrix_(index,row_);
4493 }
4495 //*************************************************************************************************
4496 
4497 
4498 //*************************************************************************************************
4505 template< typename MT > // Type of the sparse matrix
4507  SparseRow<MT,false,true>::operator[]( size_t index ) const
4508 {
4509  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4510  return const_cast<const MT&>( matrix_ )(index,row_);
4511 }
4513 //*************************************************************************************************
4514 
4515 
4516 //*************************************************************************************************
4524 template< typename MT > // Type of the sparse matrix
4526 {
4527  return matrix_.begin( row_ );
4528 }
4530 //*************************************************************************************************
4531 
4532 
4533 //*************************************************************************************************
4541 template< typename MT > // Type of the sparse matrix
4543 {
4544  return matrix_.cbegin( row_ );
4545 }
4547 //*************************************************************************************************
4548 
4549 
4550 //*************************************************************************************************
4558 template< typename MT > // Type of the sparse matrix
4560 {
4561  return matrix_.cbegin( row_ );
4562 }
4564 //*************************************************************************************************
4565 
4566 
4567 //*************************************************************************************************
4575 template< typename MT > // Type of the sparse matrix
4577 {
4578  return matrix_.end( row_ );
4579 }
4581 //*************************************************************************************************
4582 
4583 
4584 //*************************************************************************************************
4592 template< typename MT > // Type of the sparse matrix
4594 {
4595  return matrix_.cend( row_ );
4596 }
4598 //*************************************************************************************************
4599 
4600 
4601 //*************************************************************************************************
4609 template< typename MT > // Type of the sparse matrix
4611 {
4612  return matrix_.cend( row_ );
4613 }
4615 //*************************************************************************************************
4616 
4617 
4618 
4619 
4620 //=================================================================================================
4621 //
4622 // ASSIGNMENT OPERATORS
4623 //
4624 //=================================================================================================
4625 
4626 //*************************************************************************************************
4640 template< typename MT > // Type of the sparse matrix
4641 inline SparseRow<MT,false,true>& SparseRow<MT,false,true>::operator=( const SparseRow& rhs )
4642 {
4643  using blaze::assign;
4644 
4648 
4649  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
4650  return *this;
4651 
4652  if( size() != rhs.size() )
4653  throw std::invalid_argument( "Row sizes do not match" );
4654 
4655  if( !preservesInvariant( matrix_, rhs ) )
4656  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4657 
4658  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4659 
4660  if( rhs.canAlias( &matrix_ ) ) {
4661  const ResultType tmp( rhs );
4662  left.reset();
4663  left.reserve( tmp.nonZeros() );
4664  assign( left, tmp );
4665  }
4666  else {
4667  left.reset();
4668  left.reserve( rhs.nonZeros() );
4669  assign( left, rhs );
4670  }
4671 
4672  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4673  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4674 
4675  return *this;
4676 }
4678 //*************************************************************************************************
4679 
4680 
4681 //*************************************************************************************************
4695 template< typename MT > // Type of the sparse matrix
4696 template< typename VT > // Type of the right-hand side dense vector
4697 inline SparseRow<MT,false,true>&
4698  SparseRow<MT,false,true>::operator=( const DenseVector<VT,true>& rhs )
4699 {
4700  using blaze::assign;
4701 
4705 
4706  if( size() != (~rhs).size() )
4707  throw std::invalid_argument( "Vector sizes do not match" );
4708 
4709  typedef typename If< IsRestricted<MT>, typename VT::CompositeType, const VT& >::Type Right;
4710  Right right( ~rhs );
4711 
4712  if( !preservesInvariant( matrix_, right ) )
4713  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4714 
4715  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4716 
4717  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4718  const typename VT::ResultType tmp( right );
4719  left.reset();
4720  assign( left, tmp );
4721  }
4722  else {
4723  left.reset();
4724  assign( left, right );
4725  }
4726 
4727  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4728  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4729 
4730  return *this;
4731 }
4733 //*************************************************************************************************
4734 
4735 
4736 //*************************************************************************************************
4750 template< typename MT > // Type of the sparse matrix
4751 template< typename VT > // Type of the right-hand side sparse vector
4752 inline SparseRow<MT,false,true>&
4753  SparseRow<MT,false,true>::operator=( const SparseVector<VT,true>& rhs )
4754 {
4755  using blaze::assign;
4756 
4760 
4761  if( size() != (~rhs).size() )
4762  throw std::invalid_argument( "Vector sizes do not match" );
4763 
4764  typedef typename If< IsRestricted<MT>, typename VT::CompositeType, const VT& >::Type Right;
4765  Right right( ~rhs );
4766 
4767  if( !preservesInvariant( matrix_, right ) )
4768  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4769 
4770  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4771 
4772  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4773  const typename VT::ResultType tmp( right );
4774  left.reset();
4775  left.reserve( tmp.nonZeros() );
4776  assign( left, tmp );
4777  }
4778  else {
4779  left.reset();
4780  left.reserve( right.nonZeros() );
4781  assign( left, right );
4782  }
4783 
4784  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4785  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4786 
4787  return *this;
4788 }
4790 //*************************************************************************************************
4791 
4792 
4793 //*************************************************************************************************
4807 template< typename MT > // Type of the sparse matrix
4808 template< typename VT > // Type of the right-hand side dense vector
4809 inline SparseRow<MT,false,true>&
4810  SparseRow<MT,false,true>::operator+=( const DenseVector<VT,true>& rhs )
4811 {
4812  using blaze::assign;
4813 
4820 
4821  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
4822 
4826 
4827  if( size() != (~rhs).size() )
4828  throw std::invalid_argument( "Vector sizes do not match" );
4829 
4830  const AddType tmp( *this + (~rhs) );
4831 
4832  if( !preservesInvariant( matrix_, tmp ) )
4833  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4834 
4835  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4836 
4837  left.reset();
4838  assign( left, tmp );
4839 
4840  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4841  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4842 
4843  return *this;
4844 }
4846 //*************************************************************************************************
4847 
4848 
4849 //*************************************************************************************************
4863 template< typename MT > // Type of the sparse matrix
4864 template< typename VT > // Type of the right-hand side sparse vector
4865 inline SparseRow<MT,false,true>&
4866  SparseRow<MT,false,true>::operator+=( const SparseVector<VT,true>& rhs )
4867 {
4868  using blaze::assign;
4869 
4876 
4877  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
4878 
4882 
4883  if( size() != (~rhs).size() )
4884  throw std::invalid_argument( "Vector sizes do not match" );
4885 
4886  const AddType tmp( *this + (~rhs) );
4887 
4888  if( !preservesInvariant( matrix_, tmp ) )
4889  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4890 
4891  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4892 
4893  left.reset();
4894  left.reserve( tmp.nonZeros() );
4895  assign( left, tmp );
4896 
4897  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4898  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4899 
4900  return *this;
4901 }
4903 //*************************************************************************************************
4904 
4905 
4906 //*************************************************************************************************
4921 template< typename MT > // Type of the sparse matrix
4922 template< typename VT > // Type of the right-hand side dense vector
4923 inline SparseRow<MT,false,true>&
4924  SparseRow<MT,false,true>::operator-=( const DenseVector<VT,true>& rhs )
4925 {
4926  using blaze::assign;
4927 
4934 
4935  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
4936 
4940 
4941  if( size() != (~rhs).size() )
4942  throw std::invalid_argument( "Vector sizes do not match" );
4943 
4944  const SubType tmp( *this - (~rhs) );
4945 
4946  if( !preservesInvariant( matrix_, tmp ) )
4947  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4948 
4949  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4950 
4951  left.reset();
4952  assign( left, tmp );
4953 
4954  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4955  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4956 
4957  return *this;
4958 }
4960 //*************************************************************************************************
4961 
4962 
4963 //*************************************************************************************************
4978 template< typename MT > // Type of the sparse matrix
4979 template< typename VT > // Type of the right-hand side sparse vector
4980 inline SparseRow<MT,false,true>&
4981  SparseRow<MT,false,true>::operator-=( const SparseVector<VT,true>& rhs )
4982 {
4983  using blaze::assign;
4984 
4991 
4992  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
4993 
4997 
4998  if( size() != (~rhs).size() )
4999  throw std::invalid_argument( "Vector sizes do not match" );
5000 
5001  const SubType tmp( *this - (~rhs) );
5002 
5003  if( !preservesInvariant( matrix_, tmp ) )
5004  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
5005 
5006  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5007 
5008  left.reset();
5009  left.reserve( tmp.nonZeros() );
5010  assign( left, tmp );
5011 
5012  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
5013  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
5014 
5015  return *this;
5016 }
5018 //*************************************************************************************************
5019 
5020 
5021 //*************************************************************************************************
5033 template< typename MT > // Type of the sparse matrix
5034 template< typename VT > // Type of the right-hand side vector
5035 inline SparseRow<MT,false,true>&
5036  SparseRow<MT,false,true>::operator*=( const Vector<VT,true>& rhs )
5037 {
5038  using blaze::assign;
5039 
5045 
5046  typedef typename MultTrait<ResultType,typename VT::ResultType>::Type MultType;
5047 
5050 
5051  if( size() != (~rhs).size() )
5052  throw std::invalid_argument( "Vector sizes do not match" );
5053 
5054  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5055 
5056  const MultType tmp( *this * (~rhs) );
5057  left.reset();
5058  assign( left, tmp );
5059 
5060  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
5061  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
5062 
5063  return *this;
5064 }
5066 //*************************************************************************************************
5067 
5068 
5069 //*************************************************************************************************
5084 template< typename MT > // Type of the sparse matrix
5085 template< typename Other > // Data type of the right-hand side scalar
5086 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,false,true> >::Type&
5087  SparseRow<MT,false,true>::operator*=( Other rhs )
5088 {
5090 
5091  for( Iterator element=begin(); element!=end(); ++element )
5092  element->value() *= rhs;
5093  return *this;
5094 }
5096 //*************************************************************************************************
5097 
5098 
5099 //*************************************************************************************************
5117 template< typename MT > // Type of the sparse matrix
5118 template< typename Other > // Data type of the right-hand side scalar
5119 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,false,true> >::Type&
5120  SparseRow<MT,false,true>::operator/=( Other rhs )
5121 {
5123 
5124  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
5125 
5126  typedef typename DivTrait<ElementType,Other>::Type DT;
5127  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
5128 
5129  // Depending on the two involved data types, an integer division is applied or a
5130  // floating point division is selected.
5131  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
5132  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
5133  for( Iterator element=begin(); element!=end(); ++element )
5134  element->value() *= tmp;
5135  }
5136  else {
5137  for( Iterator element=begin(); element!=end(); ++element )
5138  element->value() /= rhs;
5139  }
5140 
5141  return *this;
5142 }
5144 //*************************************************************************************************
5145 
5146 
5147 
5148 
5149 //=================================================================================================
5150 //
5151 // UTILITY FUNCTIONS
5152 //
5153 //=================================================================================================
5154 
5155 //*************************************************************************************************
5161 template< typename MT > // Type of the sparse matrix
5162 inline size_t SparseRow<MT,false,true>::size() const
5163 {
5164  return matrix_.columns();
5165 }
5167 //*************************************************************************************************
5168 
5169 
5170 //*************************************************************************************************
5176 template< typename MT > // Type of the sparse matrix
5177 inline size_t SparseRow<MT,false,true>::capacity() const
5178 {
5179  return matrix_.capacity( row_ );
5180 }
5182 //*************************************************************************************************
5183 
5184 
5185 //*************************************************************************************************
5194 template< typename MT > // Type of the sparse matrix
5195 inline size_t SparseRow<MT,false,true>::nonZeros() const
5196 {
5197  return matrix_.nonZeros( row_ );
5198 }
5200 //*************************************************************************************************
5201 
5202 
5203 //*************************************************************************************************
5209 template< typename MT > // Type of the sparse matrix
5210 inline void SparseRow<MT,false,true>::reset()
5211 {
5212  matrix_.reset( row_ );
5213 }
5215 //*************************************************************************************************
5216 
5217 
5218 //*************************************************************************************************
5230 template< typename MT > // Type of the sparse matrix
5231 inline typename SparseRow<MT,false,true>::Iterator
5232  SparseRow<MT,false,true>::set( size_t index, const ElementType& value )
5233 {
5234  return matrix_.set( index, row_, value );
5235 }
5237 //*************************************************************************************************
5238 
5239 
5240 //*************************************************************************************************
5253 template< typename MT > // Type of the sparse matrix
5254 inline typename SparseRow<MT,false,true>::Iterator
5255  SparseRow<MT,false,true>::insert( size_t index, const ElementType& value )
5256 {
5257  return matrix_.insert( index, row_, value );
5258 }
5260 //*************************************************************************************************
5261 
5262 
5263 //*************************************************************************************************
5272 template< typename MT > // Type of the sparse matrix
5273 inline void SparseRow<MT,false,true>::erase( size_t index )
5274 {
5275  matrix_.erase( index, row_ );
5276 }
5278 //*************************************************************************************************
5279 
5280 
5281 //*************************************************************************************************
5290 template< typename MT > // Type of the sparse matrix
5291 inline typename SparseRow<MT,false,true>::Iterator
5293 {
5294  return matrix_.erase( row_, pos );
5295 }
5297 //*************************************************************************************************
5298 
5299 
5300 //*************************************************************************************************
5310 template< typename MT > // Type of the sparse matrix
5311 inline typename SparseRow<MT,false,true>::Iterator
5313 {
5314  return matrix_.erase( row_, first, last );
5315 }
5317 //*************************************************************************************************
5318 
5319 
5320 //*************************************************************************************************
5330 template< typename MT > // Type of the sparse matrix
5331 void SparseRow<MT,false,true>::reserve( size_t n )
5332 {
5333  matrix_.reserve( row_, n );
5334 }
5336 //*************************************************************************************************
5337 
5338 
5339 //*************************************************************************************************
5350 template< typename MT > // Type of the sparse matrix
5351 template< typename Other > // Data type of the scalar value
5352 inline SparseRow<MT,false,true>& SparseRow<MT,false,true>::scale( const Other& scalar )
5353 {
5355 
5356  for( Iterator element=begin(); element!=end(); ++element )
5357  element->value() *= scalar;
5358  return *this;
5359 }
5361 //*************************************************************************************************
5362 
5363 
5364 //*************************************************************************************************
5373 template< typename MT > // Type of the sparse matrix
5374 inline size_t SparseRow<MT,false,true>::extendCapacity() const
5375 {
5376  using blaze::max;
5377  using blaze::min;
5378 
5379  size_t nonzeros( 2UL*capacity()+1UL );
5380  nonzeros = max( nonzeros, 7UL );
5381  nonzeros = min( nonzeros, size() );
5382 
5383  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
5384 
5385  return nonzeros;
5386 }
5388 //*************************************************************************************************
5389 
5390 
5391 //*************************************************************************************************
5403 template< typename MT > // Type of the sparse matrix
5404 template< typename MT2 // Type of the left-hand side sparse matrix
5405  , bool SO2 // Storage order of the left-hand side sparse matrix
5406  , typename VT > // Type of the right-hand side vector
5407 inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
5408  SparseRow<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,true>& rhs )
5409 {
5410  UNUSED_PARAMETER( lhs, rhs );
5411 
5412  return true;
5413 }
5415 //*************************************************************************************************
5416 
5417 
5418 //*************************************************************************************************
5430 template< typename MT > // Type of the sparse matrix
5431 template< typename MT2 // Type of the left-hand side sparse matrix
5432  , bool SO2 // Storage order of the left-hand side sparse matrix
5433  , typename VT > // Type of the right-hand side dense vector
5434 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5435  SparseRow<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs )
5436 {
5438 
5439  UNUSED_PARAMETER( lhs );
5440 
5441  if( IsUniLower<MT2>::value && !isOne( (~rhs)[row_] ) )
5442  return false;
5443 
5444  const size_t ibegin( ( IsStrictlyLower<MT2>::value )?( row_ ):( row_+1UL ) );
5445 
5446  for( size_t i=ibegin; i<size(); ++i ) {
5447  if( !isDefault( (~rhs)[i] ) )
5448  return false;
5449  }
5450 
5451  return true;
5452 }
5454 //*************************************************************************************************
5455 
5456 
5457 //*************************************************************************************************
5469 template< typename MT > // Type of the sparse matrix
5470 template< typename MT2 // Type of the left-hand side sparse matrix
5471  , bool SO2 // Storage order of the left-hand side sparse matrix
5472  , typename VT > // Type of the right-hand side sparse vector
5473 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5474  SparseRow<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs )
5475 {
5477 
5478  UNUSED_PARAMETER( lhs );
5479 
5480  typedef typename VT::ConstIterator RhsIterator;
5481 
5482  const bool checkDiagonal( IsUniLower<MT2>::value || IsStrictlyLower<MT2>::value );
5483  const RhsIterator last( (~rhs).end() );
5484  RhsIterator element( (~rhs).lowerBound( ( checkDiagonal )?( row_ ):( row_+1UL ) ) );
5485 
5486  if( IsUniLower<MT2>::value ) {
5487  if( element == last || element->index() != row_ || !isOne( element->value() ) )
5488  return false;
5489  ++element;
5490  }
5491 
5492  for( ; element!=last; ++element ) {
5493  if( !isDefault( element->value() ) )
5494  return false;
5495  }
5496 
5497  return true;
5498 }
5500 //*************************************************************************************************
5501 
5502 
5503 //*************************************************************************************************
5515 template< typename MT > // Type of the sparse matrix
5516 template< typename MT2 // Type of the left-hand side sparse matrix
5517  , bool SO2 // Storage order of the left-hand side sparse matrix
5518  , typename VT > // Type of the right-hand side dense vector
5519 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5520  SparseRow<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs )
5521 {
5523 
5524  UNUSED_PARAMETER( lhs );
5525 
5526  const size_t iend( ( IsStrictlyUpper<MT2>::value )?( row_+1UL ):( row_ ) );
5527 
5528  for( size_t i=0UL; i<iend; ++i ) {
5529  if( !isDefault( (~rhs)[i] ) )
5530  return false;
5531  }
5532 
5533  if( IsUniUpper<MT2>::value && !isOne( (~rhs)[row_] ) )
5534  return false;
5535 
5536  return true;
5537 }
5539 //*************************************************************************************************
5540 
5541 
5542 //*************************************************************************************************
5554 template< typename MT > // Type of the sparse matrix
5555 template< typename MT2 // Type of the left-hand side sparse matrix
5556  , bool SO2 // Storage order of the left-hand side sparse matrix
5557  , typename VT > // Type of the right-hand side sparse vector
5558 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5559  SparseRow<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs )
5560 {
5562 
5563  UNUSED_PARAMETER( lhs );
5564 
5565  typedef typename VT::ConstIterator RhsIterator;
5566 
5567  const RhsIterator last( (~rhs).lowerBound( ( IsStrictlyUpper<MT2>::value )?( row_+1UL ):( row_ ) ) );
5568 
5569  if( IsUniUpper<MT2>::value && ( last == (~rhs).end() || last->index() != row_ || !isOne( last->value() ) ) )
5570  return false;
5571 
5572  for( RhsIterator element=(~rhs).begin(); element!=last; ++element ) {
5573  if( !isDefault( element->value() ) )
5574  return false;
5575  }
5576 
5577  return true;
5578 }
5580 //*************************************************************************************************
5581 
5582 
5583 //*************************************************************************************************
5595 template< typename MT > // Type of the sparse matrix
5596 template< typename MT2 // Type of the left-hand side sparse matrix
5597  , bool SO2 // Storage order of the left-hand side sparse matrix
5598  , typename VT > // Type of the right-hand side dense vector
5599 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
5600  SparseRow<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,true>& rhs )
5601 {
5603 
5604  UNUSED_PARAMETER( lhs );
5605 
5606  for( size_t i=0UL; i<row_; ++i ) {
5607  if( !isDefault( (~rhs)[i] ) )
5608  return false;
5609  }
5610 
5611  for( size_t i=row_+1UL; i<size(); ++i ) {
5612  if( !isDefault( (~rhs)[i] ) )
5613  return false;
5614  }
5615 
5616  return true;
5617 }
5619 //*************************************************************************************************
5620 
5621 
5622 //*************************************************************************************************
5634 template< typename MT > // Type of the sparse matrix
5635 template< typename MT2 // Type of the left-hand side sparse matrix
5636  , bool SO2 // Storage order of the left-hand side sparse matrix
5637  , typename VT > // Type of the right-hand side sparse vector
5638 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
5639  SparseRow<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,true>& rhs )
5640 {
5642 
5643  UNUSED_PARAMETER( lhs );
5644 
5645  typedef typename VT::ConstIterator RhsIterator;
5646 
5647  for( RhsIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
5648  if( element->index() != row_ && !isDefault( element->value() ) )
5649  return false;
5650  }
5651 
5652  return true;
5653 }
5655 //*************************************************************************************************
5656 
5657 
5658 
5659 
5660 //=================================================================================================
5661 //
5662 // LOOKUP FUNCTIONS
5663 //
5664 //=================================================================================================
5665 
5666 //*************************************************************************************************
5680 template< typename MT > // Type of the sparse matrix
5681 inline typename SparseRow<MT,false,true>::Iterator
5682  SparseRow<MT,false,true>::find( size_t index )
5683 {
5684  return matrix_.find( index, row_ );
5685 }
5687 //*************************************************************************************************
5688 
5689 
5690 //*************************************************************************************************
5704 template< typename MT > // Type of the sparse matrix
5706  SparseRow<MT,false,true>::find( size_t index ) const
5707 {
5708  return matrix_.find( index, row_ );
5709 }
5711 //*************************************************************************************************
5712 
5713 
5714 //*************************************************************************************************
5727 template< typename MT > // Type of the sparse matrix
5728 inline typename SparseRow<MT,false,true>::Iterator
5729  SparseRow<MT,false,true>::lowerBound( size_t index )
5730 {
5731  return matrix_.lowerBound( index, row_ );
5732 }
5734 //*************************************************************************************************
5735 
5736 
5737 //*************************************************************************************************
5750 template< typename MT > // Type of the sparse matrix
5752  SparseRow<MT,false,true>::lowerBound( size_t index ) const
5753 {
5754  return matrix_.lowerBound( index, row_ );
5755 }
5757 //*************************************************************************************************
5758 
5759 
5760 //*************************************************************************************************
5773 template< typename MT > // Type of the sparse matrix
5774 inline typename SparseRow<MT,false,true>::Iterator
5775  SparseRow<MT,false,true>::upperBound( size_t index )
5776 {
5777  return matrix_.upperBound( index, row_ );
5778 }
5780 //*************************************************************************************************
5781 
5782 
5783 //*************************************************************************************************
5796 template< typename MT > // Type of the sparse matrix
5798  SparseRow<MT,false,true>::upperBound( size_t index ) const
5799 {
5800  return matrix_.upperBound( index, row_ );
5801 }
5803 //*************************************************************************************************
5804 
5805 
5806 
5807 
5808 //=================================================================================================
5809 //
5810 // LOW-LEVEL UTILITY FUNCTIONS
5811 //
5812 //=================================================================================================
5813 
5814 //*************************************************************************************************
5839 template< typename MT > // Type of the sparse matrix
5840 inline void SparseRow<MT,false,true>::append( size_t index, const ElementType& value, bool check )
5841 {
5842  matrix_.append( index, row_, value, check );
5843 }
5845 //*************************************************************************************************
5846 
5847 
5848 
5849 
5850 //=================================================================================================
5851 //
5852 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5853 //
5854 //=================================================================================================
5855 
5856 //*************************************************************************************************
5867 template< typename MT > // Type of the sparse matrix
5868 template< typename Other > // Data type of the foreign expression
5869 inline bool SparseRow<MT,false,true>::canAlias( const Other* alias ) const
5870 {
5871  return matrix_.isAliased( alias );
5872 }
5874 //*************************************************************************************************
5875 
5876 
5877 //*************************************************************************************************
5888 template< typename MT > // Type of the sparse matrix
5889 template< typename Other > // Data type of the foreign expression
5890 inline bool SparseRow<MT,false,true>::isAliased( const Other* alias ) const
5891 {
5892  return matrix_.isAliased( alias );
5893 }
5895 //*************************************************************************************************
5896 
5897 
5898 //*************************************************************************************************
5910 template< typename MT > // Type of the sparse matrix
5911 template< typename VT > // Type of the right-hand side dense vector
5912 inline void SparseRow<MT,false,true>::assign( const DenseVector<VT,true>& rhs )
5913 {
5915 
5916  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5917  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5918 
5919  for( size_t i=0UL; i<size(); ++i )
5920  {
5921  if( matrix_.nonZeros( row_ ) == matrix_.capacity( row_ ) )
5922  matrix_.reserve( row_, extendCapacity() );
5923 
5924  matrix_.append( i, row_, (~rhs)[i], true );
5925  }
5926 }
5928 //*************************************************************************************************
5929 
5930 
5931 //*************************************************************************************************
5943 template< typename MT > // Type of the sparse matrix
5944 template< typename VT > // Type of the right-hand side sparse vector
5945 inline void SparseRow<MT,false,true>::assign( const SparseVector<VT,true>& rhs )
5946 {
5948 
5949  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5950  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5951 
5952  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
5953  matrix_.append( element->index(), row_, element->value(), true );
5954  }
5955 }
5957 //*************************************************************************************************
5958 
5959 
5960 //*************************************************************************************************
5972 template< typename MT > // Type of the sparse matrix
5973 template< typename VT > // Type of the right-hand side dense vector
5974 inline void SparseRow<MT,false,true>::addAssign( const DenseVector<VT,true>& rhs )
5975 {
5977 
5978  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
5979 
5983 
5984  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5985 
5986  const AddType tmp( serial( *this + (~rhs) ) );
5987  matrix_.reset( row_ );
5988  assign( tmp );
5989 }
5991 //*************************************************************************************************
5992 
5993 
5994 //*************************************************************************************************
6006 template< typename MT > // Type of the sparse matrix
6007 template< typename VT > // Type of the right-hand side sparse vector
6008 inline void SparseRow<MT,false,true>::addAssign( const SparseVector<VT,true>& rhs )
6009 {
6011 
6012  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
6013 
6017 
6018  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6019 
6020  const AddType tmp( serial( *this + (~rhs) ) );
6021  matrix_.reset( row_ );
6022  matrix_.reserve( row_, tmp.nonZeros() );
6023  assign( tmp );
6024 }
6026 //*************************************************************************************************
6027 
6028 
6029 //*************************************************************************************************
6041 template< typename MT > // Type of the sparse matrix
6042 template< typename VT > // Type of the right-hand side dense vector
6043 inline void SparseRow<MT,false,true>::subAssign( const DenseVector<VT,true>& rhs )
6044 {
6046 
6047  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
6048 
6052 
6053  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6054 
6055  const SubType tmp( serial( *this - (~rhs) ) );
6056  matrix_.reset( row_ );
6057  assign( tmp );
6058 }
6060 //*************************************************************************************************
6061 
6062 
6063 //*************************************************************************************************
6075 template< typename MT > // Type of the sparse matrix
6076 template< typename VT > // Type of the right-hand side sparse vector
6077 inline void SparseRow<MT,false,true>::subAssign( const SparseVector<VT,true>& rhs )
6078 {
6080 
6081  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
6082 
6086 
6087  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6088 
6089  const SubType tmp( serial( *this - (~rhs) ) );
6090  matrix_.reset( row_ );
6091  matrix_.reserve( row_, tmp.nonZeros() );
6092  assign( tmp );
6093 }
6095 //*************************************************************************************************
6096 
6097 
6098 
6099 
6100 
6101 
6102 
6103 
6104 //=================================================================================================
6105 //
6106 // SPARSEROW OPERATORS
6107 //
6108 //=================================================================================================
6109 
6110 //*************************************************************************************************
6113 template< typename MT, bool SO, bool SF >
6114 inline void reset( SparseRow<MT,SO,SF>& row );
6115 
6116 template< typename MT, bool SO, bool SF >
6117 inline void clear( SparseRow<MT,SO,SF>& row );
6118 
6119 template< typename MT, bool SO, bool SF >
6120 inline bool isDefault( const SparseRow<MT,SO,SF>& row );
6121 
6122 template< typename MT, bool SO, bool SF >
6123 inline bool isSame( const SparseRow<MT,SO,SF>& a, const SparseRow<MT,SO,SF>& b );
6125 //*************************************************************************************************
6126 
6127 
6128 //*************************************************************************************************
6135 template< typename MT // Type of the sparse matrix
6136  , bool SO // Storage order
6137  , bool SF > // Symmetry flag
6138 inline void reset( SparseRow<MT,SO,SF>& row )
6139 {
6140  row.reset();
6141 }
6142 //*************************************************************************************************
6143 
6144 
6145 //*************************************************************************************************
6154 template< typename MT // Type of the sparse matrix
6155  , bool SO // Storage order
6156  , bool SF > // Symmetry flag
6157 inline void clear( SparseRow<MT,SO,SF>& row )
6158 {
6159  row.reset();
6160 }
6161 //*************************************************************************************************
6162 
6163 
6164 //*************************************************************************************************
6182 template< typename MT // Type of the sparse matrix
6183  , bool SO // Storage order
6184  , bool SF > // Symmetry flag
6185 inline bool isDefault( const SparseRow<MT,SO,SF>& row )
6186 {
6188 
6189  const ConstIterator end( row.end() );
6190  for( ConstIterator element=row.begin(); element!=end; ++element )
6191  if( !isDefault( element->value() ) ) return false;
6192  return true;
6193 }
6194 //*************************************************************************************************
6195 
6196 
6197 //*************************************************************************************************
6209 template< typename MT // Type of the sparse matrix
6210  , bool SO // Storage order
6211  , bool SF > // Symmetry flag
6212 inline bool isSame( const SparseRow<MT,SO,SF>& a, const SparseRow<MT,SO,SF>& b )
6213 {
6214  return ( isSame( a.matrix_, b.matrix_ ) && ( a.row_ == b.row_ ) );
6215 }
6216 //*************************************************************************************************
6217 
6218 
6219 //*************************************************************************************************
6234 template< typename MT // Type of the sparse matrix
6235  , bool SO // Storage order
6236  , bool SF > // Symmetry flag
6237 inline typename DerestrictTrait< SparseRow<MT,SO,SF> >::Type
6238  derestrict( SparseRow<MT,SO,SF>& row )
6239 {
6240  typedef typename DerestrictTrait< SparseRow<MT,SO,SF> >::Type ReturnType;
6241  return ReturnType( derestrict( row.matrix_ ), row.row_ );
6242 }
6244 //*************************************************************************************************
6245 
6246 
6247 
6248 
6249 //=================================================================================================
6250 //
6251 // ISRESTRICTED SPECIALIZATIONS
6252 //
6253 //=================================================================================================
6254 
6255 //*************************************************************************************************
6257 template< typename MT, bool SO, bool SF >
6258 struct IsRestricted< SparseRow<MT,SO,SF> > : public If< IsRestricted<MT>, TrueType, FalseType >::Type
6259 {
6260  enum { value = IsRestricted<MT>::value };
6261  typedef typename If< IsRestricted<MT>, TrueType, FalseType >::Type Type;
6262 };
6264 //*************************************************************************************************
6265 
6266 
6267 
6268 
6269 //=================================================================================================
6270 //
6271 // DERESTRICTTRAIT SPECIALIZATIONS
6272 //
6273 //=================================================================================================
6274 
6275 //*************************************************************************************************
6277 template< typename MT, bool SO, bool SF >
6278 struct DerestrictTrait< SparseRow<MT,SO,SF> >
6279 {
6280  typedef SparseRow< typename RemoveReference< typename DerestrictTrait<MT>::Type >::Type > Type;
6281 };
6283 //*************************************************************************************************
6284 
6285 
6286 
6287 
6288 //=================================================================================================
6289 //
6290 // SUBVECTORTRAIT SPECIALIZATIONS
6291 //
6292 //=================================================================================================
6293 
6294 //*************************************************************************************************
6296 template< typename MT, bool SO, bool SF >
6297 struct SubvectorTrait< SparseRow<MT,SO,SF> >
6298 {
6299  typedef typename SubvectorTrait< typename SparseRow<MT,SO,SF>::ResultType >::Type Type;
6300 };
6302 //*************************************************************************************************
6303 
6304 } // namespace blaze
6305 
6306 #endif
Constraint on the data type.
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Header file for mathematical functions.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8247
Header file for the subtraction trait.
SparseRow< MT, SO, SF > This
Type of this SparseRow instance.
Definition: SparseRow.h:393
Header file for basic type definitions.
Header file for the SparseVector base class.
SparseRow & operator=(const SparseRow &rhs)
Copy assignment operator for SparseRow.
Definition: SparseRow.h:785
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:264
Header file for the row trait.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:258
void append(size_t index, const ElementType &value, bool check=false)
Appending an element to the sparse row.
Definition: SparseRow.h:1970
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:209
Header file for the row base class.
Header file for the IsDiagonal type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:118
size_t size() const
Returns the current size/dimension of the sparse row.
Definition: SparseRow.h:1299
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b)
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:946
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:821
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2507
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:348
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename ColumnExprTrait< MT >::Type >::Type column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:103
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the And class template.
bool canAlias(const Other *alias) const
Returns whether the sparse row can alias with the given address alias.
Definition: SparseRow.h:1999
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:118
size_t nonZeros() const
Returns the number of non-zero elements in the row.
Definition: SparseRow.h:1332
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:699
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:386
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a symmetric matrix type...
Definition: Symmetric.h:78
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:118
Header file for the RequiresEvaluation type trait.
Header file for the IsUniLower type trait.
size_t extendCapacity() const
Calculating a new sparse row capacity.
Definition: SparseRow.h:1510
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:964
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:861
Constraint on the data type.
void subAssign(const DenseVector< VT, true > &rhs)
Default implementation of the subtraction assignment of a dense vector.
Definition: SparseRow.h:2173
Compile time check for data types with restricted data access.This type trait tests whether the given...
Definition: IsRestricted.h:82
Constraint on the data type.
Base template for the RowTrait class.
Definition: RowTrait.h:115
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:85
IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant row value.
Definition: SparseRow.h:404
ConstIterator cbegin() const
Returns an iterator to the first element of the row.
Definition: SparseRow.h:703
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
Compile time assertion.
Constraint on the data type.
Header file for the IsFloatingPoint type trait.
void erase(size_t index)
Erasing an element from the sparse row.
Definition: SparseRow.h:1410
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
const SparseRow & CompositeType
Data type for composite expression templates.
Definition: SparseRow.h:398
Operand matrix_
The sparse matrix containing the row.
Definition: SparseRow.h:557
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2511
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:116
Header file for the Or class template.
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: SparseRow.h:397
void reset()
Reset to the default initial values.
Definition: SparseRow.h:1347
void reserve(size_t n)
Setting the minimum capacity of the sparse row.
Definition: SparseRow.h:1467
size_t capacity() const
Returns the maximum capacity of the sparse row.
Definition: SparseRow.h:1314
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1602
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
Header file for the subvector trait.
RowTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: SparseRow.h:394
MT::ConstIterator ConstIterator
Iterator over constant elements.
Definition: SparseRow.h:407
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
Header file for the IsLower type trait.
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:79
Constraint on the data type.
MT::ConstReference ConstReference
Reference to a constant row value.
Definition: SparseRow.h:401
Header file for the SparseElement base class.
Constraint on the data type.
MT::ElementType ElementType
Type of the row elements.
Definition: SparseRow.h:396
void addAssign(const DenseVector< VT, true > &rhs)
Default implementation of the addition assignment of a dense vector.
Definition: SparseRow.h:2104
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1197
Constraints on the storage order of matrix types.
Constraint on the data type.
Reference operator[](size_t index)
Subscript operator for the direct access to the row elements.
Definition: SparseRow.h:633
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:195
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
SparseRow(MT &matrix, size_t index)
The constructor for SparseRow.
Definition: SparseRow.h:606
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2505
Constraint on the data type.
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2509
Iterator insert(size_t index, const ElementType &value)
Inserting an element into the sparse row.
Definition: SparseRow.h:1392
If< IsExpression< MT >, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: SparseRow.h:377
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:841
Iterator set(size_t index, const ElementType &value)
Setting an element of the sparse row.
Definition: SparseRow.h:1369
Header file for the serial shim.
Header file for the isOne shim.
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:85
Header file for the DerestrictTrait class template.
Constraint on the data type.
Header file for the IsNumeric type trait.
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename RowExprTrait< MT >::Type >::Type row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:103
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2506
Header file for the IsConst type trait.
Iterator end()
Returns an iterator just past the last element of the row.
Definition: SparseRow.h:720
Base class for all rows.The Row class serves as a tag for all rows (i.e. dense and sparse rows)...
Definition: Row.h:63
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:150
Base template for the MultTrait class.
Definition: MultTrait.h:150
Header file for the addition trait.
Reference to a specific row of a sparse matrix.The SparseRow template represents a reference to a spe...
Definition: Forward.h:52
Header file for the division trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_RESTRICTED(T)
Constraint on the data type.In case the given data type T does have a restricted data access...
Definition: Restricted.h:118
const DenseIterator< Type > operator-(const DenseIterator< Type > &it, ptrdiff_t inc)
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:585
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Header file for the reset shim.
Compile time type negation.The Not class template negates the given compile time condition. In case the given condition would evaluate to true, the nested member enumeration is set to false and vice versa:
Definition: Not.h:70
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:116
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2510
Header file for the isDefault shim.
Constraint on the data type.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:118
Evaluation of the return type of the derestrict function.Via this type trait it is possible to evalua...
Definition: DerestrictTrait.h:74
Header file for the IsReference type trait.
Header file for the RemoveReference type trait.
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
Base template for the DivTrait class.
Definition: DivTrait.h:150
Iterator find(size_t index)
Searches for a specific row element.
Definition: SparseRow.h:1817
bool isAliased(const Other *alias) const
Returns whether the sparse row is aliased with the given address alias.
Definition: SparseRow.h:2020
Iterator lowerBound(size_t index)
Returns an iterator to the first index not less then the given index.
Definition: SparseRow.h:1862
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:79
IfTrue< useConst, ConstIterator, typename MT::Iterator >::Type Iterator
Iterator over non-constant elements.
Definition: SparseRow.h:410
Header file for the IsRowMajorMatrix type trait.
Base class for N-dimensional vectors.The Vector class is a base class for all arbitrarily sized (N-di...
Definition: Forward.h:151
boost::false_type FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:260
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:108
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2502
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
Compile time type check.This class tests whether the given template parameter T is a reference type (...
Definition: IsReference.h:94
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a row dense or sparse vector type (i...
Definition: TransposeFlag.h:81
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SparseRow.h:395
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2508
Base template for the SubTrait class.
Definition: SubTrait.h:150
Header file for the IsUpper type trait.
boost::true_type TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
ConstIterator cend() const
Returns an iterator just past the last element of the row.
Definition: SparseRow.h:754
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:143
EnableIf< IsNumeric< Type >, bool >::Type isOne(const Type &v)
Returns whether the given value/object represents the numeric value 1.
Definition: IsOne.h:80
Header file for the IsRestricted type trait.
Iterator begin()
Returns an iterator to the first element of the row.
Definition: SparseRow.h:669
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Iterator upperBound(size_t index)
Returns an iterator to the first index greater then the given index.
Definition: SparseRow.h:1906
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
const size_t row_
The index of the row in the matrix.
Definition: SparseRow.h:558
Compile time type selection.The IfTrue class template selects one of the two given types T1 and T2 de...
Definition: If.h:59
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
Header file for a safe C++ NULL pointer implementation.
void assign(const DenseVector< VT, true > &rhs)
Default implementation of the assignment of a dense vector.
Definition: SparseRow.h:2042