All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SparseRow.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_VIEWS_SPARSEROW_H_
23 #define _BLAZE_MATH_VIEWS_SPARSEROW_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <iterator>
31 #include <stdexcept>
39 #include <blaze/math/Forward.h>
40 #include <blaze/math/Functions.h>
42 #include <blaze/math/shims/Reset.h>
60 #include <blaze/util/Assert.h>
61 #include <blaze/util/DisableIf.h>
62 #include <blaze/util/EnableIf.h>
64 #include <blaze/util/mpl/If.h>
65 #include <blaze/util/SelectType.h>
66 #include <blaze/util/Types.h>
70 
71 
72 namespace blaze {
73 
74 //=================================================================================================
75 //
76 // CLASS DEFINITION
77 //
78 //=================================================================================================
79 
80 //*************************************************************************************************
330 template< typename MT // Type of the sparse matrix
331  , bool SO = IsRowMajorMatrix<MT>::value > // Storage order
332 class SparseRow : public SparseVector< SparseRow<MT,SO>, true >
333  , private Expression
334 {
335  private:
336  //**********************************************************************************************
338 
344  enum { useConst = IsConst<MT>::value };
345  //**********************************************************************************************
346 
347  public:
348  //**Type definitions****************************************************************************
350  typedef typename RowTrait<MT>::Type ResultType;
351  typedef typename ResultType::TransposeType TransposeType;
352  typedef typename MT::ElementType ElementType;
353  typedef typename MT::ReturnType ReturnType;
354  typedef const SparseRow& CompositeType;
355 
357  typedef typename MT::ConstReference ConstReference;
358 
361 
363  typedef typename MT::ConstIterator ConstIterator;
364 
367  //**********************************************************************************************
368 
369  //**Constructors********************************************************************************
372  explicit inline SparseRow( MT& matrix, size_t index );
373  // No explicitly declared copy constructor.
375  //**********************************************************************************************
376 
377  //**Destructor**********************************************************************************
378  // No explicitly declared destructor.
379  //**********************************************************************************************
380 
381  //**Data access functions***********************************************************************
384  inline Reference operator[]( size_t index );
385  inline ConstReference operator[]( size_t index ) const;
386  inline Iterator begin ();
387  inline ConstIterator begin () const;
388  inline ConstIterator cbegin() const;
389  inline Iterator end ();
390  inline ConstIterator end () const;
391  inline ConstIterator cend () const;
393  //**********************************************************************************************
394 
395  //**Assignment operators************************************************************************
398  inline SparseRow& operator= ( const SparseRow& rhs );
399  template< typename VT > inline SparseRow& operator= ( const DenseVector <VT,true>& rhs );
400  template< typename VT > inline SparseRow& operator= ( const SparseVector<VT,true>& rhs );
401  template< typename VT > inline SparseRow& operator+=( const Vector<VT,true>& rhs );
402  template< typename VT > inline SparseRow& operator-=( const Vector<VT,true>& rhs );
403  template< typename VT > inline SparseRow& operator*=( const Vector<VT,true>& rhs );
404 
405  template< typename Other >
406  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
407  operator*=( Other rhs );
408 
409  template< typename Other >
410  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
411  operator/=( Other rhs );
413  //**********************************************************************************************
414 
415  //**Utility functions***************************************************************************
418  inline size_t size() const;
419  inline size_t capacity() const;
420  inline size_t nonZeros() const;
421  inline void reset();
422  inline ElementType& insert ( size_t index, const ElementType& value );
423  inline void erase ( size_t index );
424  inline Iterator erase ( Iterator pos );
425  inline Iterator find ( size_t index );
426  inline ConstIterator find ( size_t index ) const;
427  inline void reserve( size_t n );
428  template< typename Other > inline SparseRow& scale ( Other scalar );
430  //**********************************************************************************************
431 
432  //**Low-level utility functions*****************************************************************
435  inline void append( size_t index, const ElementType& value, bool check=false );
437  //**********************************************************************************************
438 
439  //**Expression template evaluation functions****************************************************
442  template< typename Other > inline bool canAlias ( const Other* alias ) const;
443  template< typename Other > inline bool isAliased( const Other* alias ) const;
444  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
445  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
446  template< typename VT > inline void addAssign( const DenseVector <VT,true>& rhs );
447  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
448  template< typename VT > inline void subAssign( const DenseVector <VT,true>& rhs );
449  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
451  //**********************************************************************************************
452 
453  private:
454  //**Utility functions***************************************************************************
457  inline size_t extendCapacity() const;
459  //**********************************************************************************************
460 
461  //**Member variables****************************************************************************
464  MT& matrix_;
465  const size_t row_;
466 
467  //**********************************************************************************************
468 
469  //**Compile time checks*************************************************************************
475  //**********************************************************************************************
476 };
477 //*************************************************************************************************
478 
479 
480 
481 
482 //=================================================================================================
483 //
484 // CONSTRUCTOR
485 //
486 //=================================================================================================
487 
488 //*************************************************************************************************
495 template< typename MT // Type of the sparse matrix
496  , bool SO > // Storage order
497 inline SparseRow<MT,SO>::SparseRow( MT& matrix, size_t index )
498  : matrix_( matrix ) // The sparse matrix containing the row
499  , row_ ( index ) // The index of the row in the matrix
500 {
501  if( matrix_.rows() <= index )
502  throw std::invalid_argument( "Invalid row access index" );
503 }
504 //*************************************************************************************************
505 
506 
507 
508 
509 //=================================================================================================
510 //
511 // DATA ACCESS FUNCTIONS
512 //
513 //=================================================================================================
514 
515 //*************************************************************************************************
521 template< typename MT // Type of the sparse matrix
522  , bool SO > // Storage order
524 {
525  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
526  return matrix_(row_,index);
527 }
528 //*************************************************************************************************
529 
530 
531 //*************************************************************************************************
537 template< typename MT // Type of the sparse matrix
538  , bool SO > // Storage order
540 {
541  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
542  return const_cast<const MT&>( matrix_ )(row_,index);
543 }
544 //*************************************************************************************************
545 
546 
547 //*************************************************************************************************
554 template< typename MT // Type of the sparse matrix
555  , bool SO > // Storage order
557 {
558  return matrix_.begin( row_ );
559 }
560 //*************************************************************************************************
561 
562 
563 //*************************************************************************************************
570 template< typename MT // Type of the sparse matrix
571  , bool SO > // Storage order
573 {
574  return matrix_.begin( row_ );
575 }
576 //*************************************************************************************************
577 
578 
579 //*************************************************************************************************
586 template< typename MT // Type of the sparse matrix
587  , bool SO > // Storage order
589 {
590  return matrix_.begin( row_ );
591 }
592 //*************************************************************************************************
593 
594 
595 //*************************************************************************************************
602 template< typename MT // Type of the sparse matrix
603  , bool SO > // Storage order
605 {
606  return matrix_.end( row_ );
607 }
608 //*************************************************************************************************
609 
610 
611 //*************************************************************************************************
618 template< typename MT // Type of the sparse matrix
619  , bool SO > // Storage order
621 {
622  return matrix_.end( row_ );
623 }
624 //*************************************************************************************************
625 
626 
627 //*************************************************************************************************
634 template< typename MT // Type of the sparse matrix
635  , bool SO > // Storage order
637 {
638  return matrix_.end( row_ );
639 }
640 //*************************************************************************************************
641 
642 
643 
644 
645 //=================================================================================================
646 //
647 // ASSIGNMENT OPERATORS
648 //
649 //=================================================================================================
650 
651 //*************************************************************************************************
661 template< typename MT // Type of the sparse matrix
662  , bool SO > // Storage order
664 {
665  using blaze::assign;
666 
667  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
668  return *this;
669 
670  if( size() != rhs.size() )
671  throw std::invalid_argument( "Row sizes do not match" );
672 
673  if( rhs.canAlias( &matrix_ ) ) {
674  const ResultType tmp( rhs );
675  matrix_.reset ( row_ );
676  matrix_.reserve( row_, tmp.nonZeros() );
677  assign( *this, tmp );
678  }
679  else {
680  matrix_.reset ( row_ );
681  matrix_.reserve( row_, rhs.nonZeros() );
682  assign( *this, rhs );
683  }
684 
685  return *this;
686 }
687 //*************************************************************************************************
688 
689 
690 //*************************************************************************************************
700 template< typename MT // Type of the sparse matrix
701  , bool SO > // Storage order
702 template< typename VT > // Type of the right-hand side dense vector
704 {
705  using blaze::assign;
706 
707  if( size() != (~rhs).size() )
708  throw std::invalid_argument( "Vector sizes do not match" );
709 
710  if( (~rhs).canAlias( &matrix_ ) ) {
711  const typename VT::ResultType tmp( ~rhs );
712  matrix_.reset( row_ );
713  assign( *this, tmp );
714  }
715  else {
716  matrix_.reset( row_ );
717  assign( *this, ~rhs );
718  }
719 
720  return *this;
721 }
722 //*************************************************************************************************
723 
724 
725 //*************************************************************************************************
735 template< typename MT // Type of the sparse matrix
736  , bool SO > // Storage order
737 template< typename VT > // Type of the right-hand side sparse vector
739 {
740  using blaze::assign;
741 
742  if( size() != (~rhs).size() )
743  throw std::invalid_argument( "Vector sizes do not match" );
744 
745  if( (~rhs).canAlias( &matrix_ ) ) {
746  const typename VT::ResultType tmp( ~rhs );
747  matrix_.reset ( row_ );
748  matrix_.reserve( row_, tmp.nonZeros() );
749  assign( *this, tmp );
750  }
751  else {
752  matrix_.reset ( row_ );
753  matrix_.reserve( row_, (~rhs).nonZeros() );
754  assign( *this, ~rhs );
755  }
756 
757  return *this;
758 }
759 //*************************************************************************************************
760 
761 
762 //*************************************************************************************************
772 template< typename MT // Type of the sparse matrix
773  , bool SO > // Storage order
774 template< typename VT > // Type of the right-hand side vector
776 {
777  using blaze::addAssign;
778 
779  if( (~rhs).size() != size() )
780  throw std::invalid_argument( "Vector sizes do not match" );
781 
782  addAssign( *this, ~rhs );
783 
784  return *this;
785 }
786 //*************************************************************************************************
787 
788 
789 //*************************************************************************************************
799 template< typename MT // Type of the sparse matrix
800  , bool SO > // Storage order
801 template< typename VT > // Type of the right-hand side vector
803 {
804  using blaze::subAssign;
805 
806  if( (~rhs).size() != size() )
807  throw std::invalid_argument( "Vector sizes do not match" );
808 
809  subAssign( *this, ~rhs );
810 
811  return *this;
812 }
813 //*************************************************************************************************
814 
815 
816 //*************************************************************************************************
827 template< typename MT // Type of the sparse matrix
828  , bool SO > // Storage order
829 template< typename VT > // Type of the right-hand side vector
831 {
832  if( (~rhs).size() != size() )
833  throw std::invalid_argument( "Vector sizes do not match" );
834 
835  typedef typename MultTrait<This,typename VT::ResultType>::Type MultType;
836 
839 
840  const MultType tmp( *this * (~rhs) );
841  matrix_.reset( row_ );
842  assign( tmp );
843 
844  return *this;
845 }
846 //*************************************************************************************************
847 
848 
849 //*************************************************************************************************
860 template< typename MT // Type of the sparse matrix
861  , bool SO > // Storage order
862 template< typename Other > // Data type of the right-hand side scalar
863 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,SO> >::Type&
865 {
866  for( Iterator element=begin(); element!=end(); ++element )
867  element->value() *= rhs;
868  return *this;
869 }
870 //*************************************************************************************************
871 
872 
873 //*************************************************************************************************
885 template< typename MT // Type of the sparse matrix
886  , bool SO > // Storage order
887 template< typename Other > // Data type of the right-hand side scalar
888 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,SO> >::Type&
890 {
891  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
892 
893  typedef typename DivTrait<ElementType,Other>::Type DT;
894  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
895 
896  // Depending on the two involved data types, an integer division is applied or a
897  // floating point division is selected.
899  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
900  for( Iterator element=begin(); element!=end(); ++element )
901  element->value() *= tmp;
902  }
903  else {
904  for( Iterator element=begin(); element!=end(); ++element )
905  element->value() /= rhs;
906  }
907 
908  return *this;
909 }
910 //*************************************************************************************************
911 
912 
913 
914 
915 //=================================================================================================
916 //
917 // UTILITY FUNCTIONS
918 //
919 //=================================================================================================
920 
921 //*************************************************************************************************
926 template< typename MT // Type of the sparse matrix
927  , bool SO > // Storage order
928 inline size_t SparseRow<MT,SO>::size() const
929 {
930  return matrix_.columns();
931 }
932 //*************************************************************************************************
933 
934 
935 //*************************************************************************************************
940 template< typename MT // Type of the sparse matrix
941  , bool SO > // Storage order
942 inline size_t SparseRow<MT,SO>::capacity() const
943 {
944  return matrix_.capacity( row_ );
945 }
946 //*************************************************************************************************
947 
948 
949 //*************************************************************************************************
957 template< typename MT // Type of the sparse matrix
958  , bool SO > // Storage order
959 inline size_t SparseRow<MT,SO>::nonZeros() const
960 {
961  return matrix_.nonZeros( row_ );
962 }
963 //*************************************************************************************************
964 
965 
966 //*************************************************************************************************
971 template< typename MT // Type of the sparse matrix
972  , bool SO > // Storage order
974 {
975  matrix_.reset( row_ );
976 }
977 //*************************************************************************************************
978 
979 
980 //*************************************************************************************************
992 template< typename MT // Type of the sparse matrix
993  , bool SO > // Storage order
994 inline typename SparseRow<MT,SO>::ElementType&
995  SparseRow<MT,SO>::insert( size_t index, const ElementType& value )
996 {
997  return matrix_.insert( row_, index, value )->value();
998 }
999 //*************************************************************************************************
1000 
1001 
1002 //*************************************************************************************************
1010 template< typename MT // Type of the sparse matrix
1011  , bool SO > // Storage order
1012 inline void SparseRow<MT,SO>::erase( size_t index )
1013 {
1014  matrix_.erase( row_, index );
1015 }
1016 //*************************************************************************************************
1017 
1018 
1019 //*************************************************************************************************
1027 template< typename MT // Type of the sparse matrix
1028  , bool SO > // Storage order
1030 {
1031  return matrix_.erase( row_, pos );
1032 }
1033 //*************************************************************************************************
1034 
1035 
1036 //*************************************************************************************************
1049 template< typename MT // Type of the sparse matrix
1050  , bool SO > // Storage order
1052 {
1053  return matrix_.find( row_, index );
1054 }
1055 //*************************************************************************************************
1056 
1057 
1058 //*************************************************************************************************
1071 template< typename MT // Type of the sparse matrix
1072  , bool SO > // Storage order
1073 inline typename SparseRow<MT,SO>::ConstIterator SparseRow<MT,SO>::find( size_t index ) const
1074 {
1075  return matrix_.find( row_, index );
1076 }
1077 //*************************************************************************************************
1078 
1079 
1080 //*************************************************************************************************
1089 template< typename MT // Type of the sparse matrix
1090  , bool SO > // Storage order
1092 {
1093  matrix_.reserve( row_, n );
1094 }
1095 //*************************************************************************************************
1096 
1097 
1098 //*************************************************************************************************
1104 template< typename MT // Type of the sparse matrix
1105  , bool SO > // Storage order
1106 template< typename Other > // Data type of the scalar value
1108 {
1109  for( Iterator element=begin(); element!=end(); ++element )
1110  element->value() *= scalar;
1111  return *this;
1112 }
1113 //*************************************************************************************************
1114 
1115 
1116 //*************************************************************************************************
1124 template< typename MT // Type of the sparse matrix
1125  , bool SO > // Storage order
1127 {
1128  using blaze::max;
1129  using blaze::min;
1130 
1131  size_t nonzeros( 2UL*capacity()+1UL );
1132  nonzeros = max( nonzeros, 7UL );
1133  nonzeros = min( nonzeros, size() );
1134 
1135  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1136 
1137  return nonzeros;
1138 }
1139 //*************************************************************************************************
1140 
1141 
1142 
1143 
1144 //=================================================================================================
1145 //
1146 // LOW-LEVEL UTILITY FUNCTIONS
1147 //
1148 //=================================================================================================
1149 
1150 //*************************************************************************************************
1174 template< typename MT // Type of the sparse matrix
1175  , bool SO > // Storage order
1176 inline void SparseRow<MT,SO>::append( size_t index, const ElementType& value, bool check )
1177 {
1178  matrix_.append( row_, index, value, check );
1179 }
1180 //*************************************************************************************************
1181 
1182 
1183 
1184 
1185 //=================================================================================================
1186 //
1187 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1188 //
1189 //=================================================================================================
1190 
1191 //*************************************************************************************************
1201 template< typename MT // Type of the sparse matrix
1202  , bool SO > // Storage order
1203 template< typename Other > // Data type of the foreign expression
1204 inline bool SparseRow<MT,SO>::canAlias( const Other* alias ) const
1205 {
1206  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1207 }
1208 //*************************************************************************************************
1209 
1210 
1211 //*************************************************************************************************
1221 template< typename MT // Type of the sparse matrix
1222  , bool SO > // Storage order
1223 template< typename Other > // Data type of the foreign expression
1224 inline bool SparseRow<MT,SO>::isAliased( const Other* alias ) const
1225 {
1226  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1227 }
1228 //*************************************************************************************************
1229 
1230 
1231 //*************************************************************************************************
1242 template< typename MT // Type of the sparse matrix
1243  , bool SO > // Storage order
1244 template< typename VT > // Type of the right-hand side dense vector
1246 {
1247  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1248 
1249  size_t nonzeros( 0UL );
1250 
1251  for( size_t j=0UL; j<size(); ++j )
1252  {
1253  if( matrix_.nonZeros( row_ ) == matrix_.capacity( row_ ) )
1254  matrix_.reserve( row_, extendCapacity() );
1255 
1256  matrix_.append( row_, j, (~rhs)[j], true );
1257  }
1258 }
1259 //*************************************************************************************************
1260 
1261 
1262 //*************************************************************************************************
1273 template< typename MT // Type of the sparse matrix
1274  , bool SO > // Storage order
1275 template< typename VT > // Type of the right-hand side sparse vector
1277 {
1278  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1279 
1280  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
1281  matrix_.append( row_, element->index(), element->value() );
1282  }
1283 }
1284 //*************************************************************************************************
1285 
1286 
1287 //*************************************************************************************************
1298 template< typename MT // Type of the sparse matrix
1299  , bool SO > // Storage order
1300 template< typename VT > // Type of the right-hand side dense vector
1302 {
1303  typedef typename AddTrait<This,typename VT::ResultType>::Type AddType;
1304 
1308 
1309  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1310 
1311  const AddType tmp( *this + (~rhs) );
1312  matrix_.reset( row_ );
1313  assign( tmp );
1314 }
1315 //*************************************************************************************************
1316 
1317 
1318 //*************************************************************************************************
1329 template< typename MT // Type of the sparse matrix
1330  , bool SO > // Storage order
1331 template< typename VT > // Type of the right-hand side sparse vector
1333 {
1334  typedef typename AddTrait<This,typename VT::ResultType>::Type AddType;
1335 
1339 
1340  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1341 
1342  const AddType tmp( *this + (~rhs) );
1343  matrix_.reset ( row_ );
1344  matrix_.reserve( row_, tmp.nonZeros() );
1345  assign( tmp );
1346 }
1347 //*************************************************************************************************
1348 
1349 
1350 //*************************************************************************************************
1361 template< typename MT // Type of the sparse matrix
1362  , bool SO > // Storage order
1363 template< typename VT > // Type of the right-hand side dense vector
1365 {
1366  typedef typename SubTrait<This,typename VT::ResultType>::Type SubType;
1367 
1371 
1372  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1373 
1374  const SubType tmp( *this - (~rhs) );
1375  matrix_.reset ( row_ );
1376  assign( tmp );
1377 }
1378 //*************************************************************************************************
1379 
1380 
1381 //*************************************************************************************************
1392 template< typename MT // Type of the sparse matrix
1393  , bool SO > // Storage order
1394 template< typename VT > // Type of the right-hand side sparse vector
1396 {
1397  typedef typename SubTrait<This,typename VT::ResultType>::Type SubType;
1398 
1402 
1403  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1404 
1405  const SubType tmp( *this - (~rhs) );
1406  matrix_.reset ( row_ );
1407  matrix_.reserve( row_, tmp.nonZeros() );
1408  assign( tmp );
1409 }
1410 //*************************************************************************************************
1411 
1412 
1413 
1414 
1415 
1416 
1417 
1418 
1419 //=================================================================================================
1420 //
1421 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
1422 //
1423 //=================================================================================================
1424 
1425 //*************************************************************************************************
1433 template< typename MT > // Type of the sparse matrix
1434 class SparseRow<MT,false> : public SparseVector< SparseRow<MT,false>, true >
1435  , private Expression
1436 {
1437  private:
1438  //**********************************************************************************************
1440 
1446  enum { useConst = IsConst<MT>::value };
1447  //**********************************************************************************************
1448 
1449  public:
1450  //**Type definitions****************************************************************************
1451  typedef SparseRow<MT,false> This;
1452  typedef typename RowTrait<MT>::Type ResultType;
1453  typedef typename ResultType::TransposeType TransposeType;
1454  typedef typename MT::ElementType ElementType;
1455  typedef typename MT::ReturnType ReturnType;
1456  typedef const ResultType CompositeType;
1457 
1459  typedef typename MT::ConstReference ConstReference;
1460 
1462  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
1463  //**********************************************************************************************
1464 
1465  //**RowElement class definition*****************************************************************
1468  template< typename MatrixType // Type of the sparse matrix
1469  , typename IteratorType > // Type of the sparse matrix iterator
1470  class RowElement
1471  {
1472  private:
1473  //*******************************************************************************************
1475 
1480  enum { returnConst = IsConst<MatrixType>::value };
1481  //*******************************************************************************************
1482 
1483  public:
1484  //**Type definitions*************************************************************************
1485  typedef typename SelectType< returnConst, const ElementType&, ElementType& >::Type ReferenceType;
1486  //*******************************************************************************************
1487 
1488  //**Constructor******************************************************************************
1494  inline RowElement( IteratorType pos, size_t column )
1495  : pos_ ( pos ) // Iterator to the current position within the sparse row
1496  , column_( column ) // Index of the according column
1497  {}
1498  //*******************************************************************************************
1499 
1500  //**Assignment operator**********************************************************************
1506  template< typename T > inline RowElement& operator=( const T& v ) {
1507  *pos_ = v;
1508  return *this;
1509  }
1510  //*******************************************************************************************
1511 
1512  //**Addition assignment operator*************************************************************
1518  template< typename T > inline RowElement& operator+=( const T& v ) {
1519  *pos_ += v;
1520  return *this;
1521  }
1522  //*******************************************************************************************
1523 
1524  //**Subtraction assignment operator**********************************************************
1530  template< typename T > inline RowElement& operator-=( const T& v ) {
1531  *pos_ -= v;
1532  return *this;
1533  }
1534  //*******************************************************************************************
1535 
1536  //**Multiplication assignment operator*******************************************************
1542  template< typename T > inline RowElement& operator*=( const T& v ) {
1543  *pos_ *= v;
1544  return *this;
1545  }
1546  //*******************************************************************************************
1547 
1548  //**Division assignment operator*************************************************************
1554  template< typename T > inline RowElement& operator/=( const T& v ) {
1555  *pos_ /= v;
1556  return *this;
1557  }
1558  //*******************************************************************************************
1559 
1560  //**Element access operator******************************************************************
1565  inline const RowElement* operator->() const {
1566  return this;
1567  }
1568  //*******************************************************************************************
1569 
1570  //**Value function***************************************************************************
1575  inline ReferenceType value() const {
1576  return pos_->value();
1577  }
1578  //*******************************************************************************************
1579 
1580  //**Index function***************************************************************************
1585  inline size_t index() const {
1586  return column_;
1587  }
1588  //*******************************************************************************************
1589 
1590  private:
1591  //**Member variables*************************************************************************
1592  IteratorType pos_;
1593  size_t column_;
1594  //*******************************************************************************************
1595  };
1596  //**********************************************************************************************
1597 
1598  //**RowIterator class definition****************************************************************
1601  template< typename MatrixType // Type of the sparse matrix
1602  , typename IteratorType > // Type of the sparse matrix iterator
1603  class RowIterator
1604  {
1605  private:
1606  //*******************************************************************************************
1608 
1613  enum { returnConst = IsConst<MatrixType>::value };
1614  //*******************************************************************************************
1615 
1616  public:
1617  //**Type definitions*************************************************************************
1618  typedef std::forward_iterator_tag IteratorCategory;
1619  typedef RowElement<MatrixType,IteratorType> ValueType;
1620  typedef ValueType PointerType;
1621  typedef ValueType ReferenceType;
1622  typedef ptrdiff_t DifferenceType;
1623 
1624  // STL iterator requirements
1625  typedef IteratorCategory iterator_category;
1626  typedef ValueType value_type;
1627  typedef PointerType pointer;
1628  typedef ReferenceType reference;
1629  typedef DifferenceType difference_type;
1630 
1632  typedef typename SelectType< returnConst, ReturnType, ElementType& >::Type Value;
1633  //*******************************************************************************************
1634 
1635  //**Constructor******************************************************************************
1642  inline RowIterator( MatrixType& matrix, size_t row, size_t column )
1643  : matrix_( matrix ) // The sparse matrix containing the row.
1644  , row_ ( row ) // The current row index.
1645  , column_( column ) // The current column index.
1646  , pos_ () // Iterator to the current sparse element.
1647  {
1648  for( ; column_<matrix_.columns(); ++column_ ) {
1649  pos_ = matrix_.find( row_, column_ );
1650  if( pos_ != matrix_.end( column_ ) ) break;
1651  }
1652  }
1653  //*******************************************************************************************
1654 
1655  //**Constructor******************************************************************************
1663  inline RowIterator( MatrixType& matrix, size_t row, size_t column, IteratorType pos )
1664  : matrix_( matrix ) // The sparse matrix containing the row.
1665  , row_ ( row ) // The current row index.
1666  , column_( column ) // The current column index.
1667  , pos_ ( pos ) // Iterator to the current sparse element.
1668  {
1669  BLAZE_INTERNAL_ASSERT( matrix.find( row, column ) == pos, "Invalid initial iterator position" );
1670  }
1671  //*******************************************************************************************
1672 
1673  //**Constructor******************************************************************************
1678  template< typename MatrixType2, typename IteratorType2 >
1679  inline RowIterator( const RowIterator<MatrixType2,IteratorType2>& it )
1680  : matrix_( it.matrix_ ) // The sparse matrix containing the row.
1681  , row_ ( it.row_ ) // The current row index.
1682  , column_( it.column_ ) // The current column index.
1683  , pos_ ( it.pos_ ) // Iterator to the current sparse element.
1684  {}
1685  //*******************************************************************************************
1686 
1687  //**Prefix increment operator****************************************************************
1692  inline RowIterator& operator++() {
1693  ++column_;
1694  for( ; column_<matrix_.columns(); ++column_ ) {
1695  pos_ = matrix_.find( row_, column_ );
1696  if( pos_ != matrix_.end( column_ ) ) break;
1697  }
1698 
1699  return *this;
1700  }
1701  //*******************************************************************************************
1702 
1703  //**Postfix increment operator***************************************************************
1708  inline const RowIterator operator++( int ) {
1709  const RowIterator tmp( *this );
1710  ++(*this);
1711  return tmp;
1712  }
1713  //*******************************************************************************************
1714 
1715  //**Element access operator******************************************************************
1720  inline ReferenceType operator*() const {
1721  return ReferenceType( pos_, column_ );
1722  }
1723  //*******************************************************************************************
1724 
1725  //**Element access operator******************************************************************
1730  inline PointerType operator->() const {
1731  return PointerType( pos_, column_ );
1732  }
1733  //*******************************************************************************************
1734 
1735  //**Equality operator************************************************************************
1741  template< typename MatrixType2, typename IteratorType2 >
1742  inline bool operator==( const RowIterator<MatrixType2,IteratorType2>& rhs ) const {
1743  return ( &matrix_ == &rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
1744  }
1745  //*******************************************************************************************
1746 
1747  //**Inequality operator**********************************************************************
1753  template< typename MatrixType2, typename IteratorType2 >
1754  inline bool operator!=( const RowIterator<MatrixType2,IteratorType2>& rhs ) const {
1755  return !( *this == rhs );
1756  }
1757  //*******************************************************************************************
1758 
1759  //**Subtraction operator*********************************************************************
1765  inline DifferenceType operator-( const RowIterator& rhs ) const {
1766  size_t counter( 0UL );
1767  for( size_t j=rhs.column_; j<column_; ++j ) {
1768  if( matrix_.find( row_, j ) != matrix_.end( j ) )
1769  ++counter;
1770  }
1771  return counter;
1772  }
1773  //*******************************************************************************************
1774 
1775  private:
1776  //**Member variables*************************************************************************
1777  MatrixType& matrix_;
1778  size_t row_;
1779  size_t column_;
1780  IteratorType pos_;
1781  //*******************************************************************************************
1782 
1783  //**Friend declarations**********************************************************************
1785  template< typename MatrixType2, typename IteratorType2 > friend class RowIterator;
1786  template< typename MT2, bool SO2 > friend class SparseRow;
1788  //*******************************************************************************************
1789  };
1790  //**********************************************************************************************
1791 
1792  //**Type definitions****************************************************************************
1794  typedef RowIterator<const MT,typename MT::ConstIterator> ConstIterator;
1795 
1797  typedef typename SelectType< useConst, ConstIterator, RowIterator<MT,typename MT::Iterator> >::Type Iterator;
1798  //**********************************************************************************************
1799 
1800  //**Constructors********************************************************************************
1803  explicit inline SparseRow( MT& matrix, size_t index );
1804  // No explicitly declared copy constructor.
1806  //**********************************************************************************************
1807 
1808  //**Destructor**********************************************************************************
1809  // No explicitly declared destructor.
1810  //**********************************************************************************************
1811 
1812  //**Data access functions***********************************************************************
1815  inline Reference operator[]( size_t index );
1816  inline ConstReference operator[]( size_t index ) const;
1817  inline Iterator begin ();
1818  inline ConstIterator begin () const;
1819  inline ConstIterator cbegin() const;
1820  inline Iterator end ();
1821  inline ConstIterator end () const;
1822  inline ConstIterator cend () const;
1824  //**********************************************************************************************
1825 
1826  //**Assignment operators************************************************************************
1829  inline SparseRow& operator= ( const SparseRow& rhs );
1830  template< typename VT > inline SparseRow& operator= ( const Vector<VT,true>& rhs );
1831  template< typename VT > inline SparseRow& operator+=( const Vector<VT,true>& rhs );
1832  template< typename VT > inline SparseRow& operator-=( const Vector<VT,true>& rhs );
1833  template< typename VT > inline SparseRow& operator*=( const Vector<VT,true>& rhs );
1834 
1835  template< typename Other >
1836  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
1837  operator*=( Other rhs );
1838 
1839  template< typename Other >
1840  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
1841  operator/=( Other rhs );
1843  //**********************************************************************************************
1844 
1845  //**Utility functions***************************************************************************
1848  inline size_t size() const;
1849  inline size_t capacity() const;
1850  inline size_t nonZeros() const;
1851  inline void reset();
1852  inline ElementType& insert ( size_t index, const ElementType& value );
1853  inline void erase ( size_t index );
1854  inline Iterator erase ( Iterator pos );
1855  inline Iterator find ( size_t index );
1856  inline ConstIterator find ( size_t index ) const;
1857  inline void reserve( size_t n );
1858  template< typename Other > inline SparseRow& scale ( Other scalar );
1860  //**********************************************************************************************
1861 
1862  //**Low-level utility functions*****************************************************************
1865  inline void append( size_t index, const ElementType& value, bool check=false );
1867  //**********************************************************************************************
1868 
1869  //**Expression template evaluation functions****************************************************
1872  template< typename Other > inline bool canAlias ( const Other* alias ) const;
1873  template< typename Other > inline bool isAliased( const Other* alias ) const;
1874  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
1875  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
1876  template< typename VT > inline void addAssign( const Vector<VT,true>& rhs );
1877  template< typename VT > inline void subAssign( const Vector<VT,true>& rhs );
1879  //**********************************************************************************************
1880 
1881  private:
1882  //**Member variables****************************************************************************
1885  MT& matrix_;
1886  const size_t row_;
1887 
1888  //**********************************************************************************************
1889 
1890  //**Compile time checks*************************************************************************
1896  //**********************************************************************************************
1897 };
1899 //*************************************************************************************************
1900 
1901 
1902 
1903 
1904 //=================================================================================================
1905 //
1906 // CONSTRUCTOR
1907 //
1908 //=================================================================================================
1909 
1910 //*************************************************************************************************
1918 template< typename MT > // Type of the sparse matrix
1919 inline SparseRow<MT,false>::SparseRow( MT& matrix, size_t index )
1920  : matrix_( matrix ) // The sparse matrix containing the row
1921  , row_ ( index ) // The index of the row in the matrix
1922 {
1923  if( matrix_.rows() <= index )
1924  throw std::invalid_argument( "Invalid row access index" );
1925 }
1927 //*************************************************************************************************
1928 
1929 
1930 
1931 
1932 //=================================================================================================
1933 //
1934 // DATA ACCESS FUNCTIONS
1935 //
1936 //=================================================================================================
1937 
1938 //*************************************************************************************************
1945 template< typename MT > // Type of the sparse matrix
1946 inline typename SparseRow<MT,false>::Reference SparseRow<MT,false>::operator[]( size_t index )
1947 {
1948  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
1949  return matrix_(row_,index);
1950 }
1952 //*************************************************************************************************
1953 
1954 
1955 //*************************************************************************************************
1962 template< typename MT > // Type of the sparse matrix
1963 inline typename SparseRow<MT,false>::ConstReference SparseRow<MT,false>::operator[]( size_t index ) const
1964 {
1965  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
1966  return const_cast<const MT&>( matrix_ )(row_,index);
1967 }
1969 //*************************************************************************************************
1970 
1971 
1972 //*************************************************************************************************
1980 template< typename MT > // Type of the sparse matrix
1981 inline typename SparseRow<MT,false>::Iterator SparseRow<MT,false>::begin()
1982 {
1983  return Iterator( matrix_, row_, 0UL );
1984 }
1986 //*************************************************************************************************
1987 
1988 
1989 //*************************************************************************************************
1997 template< typename MT > // Type of the sparse matrix
1998 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::begin() const
1999 {
2000  return ConstIterator( matrix_, row_, 0UL );
2001 }
2003 //*************************************************************************************************
2004 
2005 
2006 //*************************************************************************************************
2014 template< typename MT > // Type of the sparse matrix
2015 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::cbegin() const
2016 {
2017  return ConstIterator( matrix_, row_, 0UL );
2018 }
2020 //*************************************************************************************************
2021 
2022 
2023 //*************************************************************************************************
2031 template< typename MT > // Type of the sparse matrix
2032 inline typename SparseRow<MT,false>::Iterator SparseRow<MT,false>::end()
2033 {
2034  return Iterator( matrix_, row_, size() );
2035 }
2037 //*************************************************************************************************
2038 
2039 
2040 //*************************************************************************************************
2048 template< typename MT > // Type of the sparse matrix
2049 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::end() const
2050 {
2051  return ConstIterator( matrix_, row_, size() );
2052 }
2054 //*************************************************************************************************
2055 
2056 
2057 //*************************************************************************************************
2065 template< typename MT > // Type of the sparse matrix
2066 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::cend() const
2067 {
2068  return ConstIterator( matrix_, row_, size() );
2069 }
2071 //*************************************************************************************************
2072 
2073 
2074 
2075 
2076 //=================================================================================================
2077 //
2078 // ASSIGNMENT OPERATORS
2079 //
2080 //=================================================================================================
2081 
2082 //*************************************************************************************************
2093 template< typename MT > // Type of the sparse matrix
2094 inline SparseRow<MT,false>& SparseRow<MT,false>::operator=( const SparseRow& rhs )
2095 {
2096  using blaze::assign;
2097 
2098  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
2099  return *this;
2100 
2101  if( size() != rhs.size() )
2102  throw std::invalid_argument( "Row sizes do not match" );
2103 
2104  if( rhs.canAlias( &matrix_ ) ) {
2105  const ResultType tmp( rhs );
2106  assign( *this, tmp );
2107  }
2108  else {
2109  assign( *this, rhs );
2110  }
2111 
2112  return *this;
2113 }
2115 //*************************************************************************************************
2116 
2117 
2118 //*************************************************************************************************
2129 template< typename MT > // Type of the sparse matrix
2130 template< typename VT > // Type of the right-hand side vector
2131 inline SparseRow<MT,false>& SparseRow<MT,false>::operator=( const Vector<VT,true>& rhs )
2132 {
2133  using blaze::assign;
2134 
2135  if( size() != (~rhs).size() )
2136  throw std::invalid_argument( "Vector sizes do not match" );
2137 
2138  const typename VT::CompositeType tmp( ~rhs );
2139  assign( *this, tmp );
2140 
2141  return *this;
2142 }
2144 //*************************************************************************************************
2145 
2146 
2147 //*************************************************************************************************
2158 template< typename MT > // Type of the sparse matrix
2159 template< typename VT > // Type of the right-hand side vector
2160 inline SparseRow<MT,false>& SparseRow<MT,false>::operator+=( const Vector<VT,true>& rhs )
2161 {
2162  using blaze::addAssign;
2163 
2164  if( (~rhs).size() != size() )
2165  throw std::invalid_argument( "Vector sizes do not match" );
2166 
2167  addAssign( *this, ~rhs );
2168 
2169  return *this;
2170 }
2172 //*************************************************************************************************
2173 
2174 
2175 //*************************************************************************************************
2186 template< typename MT > // Type of the sparse matrix
2187 template< typename VT > // Type of the right-hand side vector
2188 inline SparseRow<MT,false>& SparseRow<MT,false>::operator-=( const Vector<VT,true>& rhs )
2189 {
2190  using blaze::subAssign;
2191 
2192  if( (~rhs).size() != size() )
2193  throw std::invalid_argument( "Vector sizes do not match" );
2194 
2195  subAssign( *this, ~rhs );
2196 
2197  return *this;
2198 }
2200 //*************************************************************************************************
2201 
2202 
2203 //*************************************************************************************************
2215 template< typename MT > // Type of the sparse matrix
2216 template< typename VT > // Type of the right-hand side vector
2217 inline SparseRow<MT,false>& SparseRow<MT,false>::operator*=( const Vector<VT,true>& rhs )
2218 {
2219  if( (~rhs).size() != size() )
2220  throw std::invalid_argument( "Vector sizes do not match" );
2221 
2222  typedef typename MultTrait<This,typename VT::ResultType>::Type MultType;
2223 
2226 
2227  const MultType tmp( *this * (~rhs) );
2228  assign( tmp );
2229 
2230  return *this;
2231 }
2233 //*************************************************************************************************
2234 
2235 
2236 //*************************************************************************************************
2248 template< typename MT > // Type of the sparse matrix
2249 template< typename Other > // Data type of the right-hand side scalar
2250 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,false> >::Type&
2251  SparseRow<MT,false>::operator*=( Other rhs )
2252 {
2253  for( Iterator element=begin(); element!=end(); ++element )
2254  element->value() *= rhs;
2255  return *this;
2256 }
2258 //*************************************************************************************************
2259 
2260 
2261 //*************************************************************************************************
2274 template< typename MT > // Type of the sparse matrix
2275 template< typename Other > // Data type of the right-hand side scalar
2276 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,false> >::Type&
2277  SparseRow<MT,false>::operator/=( Other rhs )
2278 {
2279  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
2280 
2281  typedef typename DivTrait<ElementType,Other>::Type DT;
2282  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
2283 
2284  // Depending on the two involved data types, an integer division is applied or a
2285  // floating point division is selected.
2286  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
2287  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
2288  for( Iterator element=begin(); element!=end(); ++element )
2289  element->value() *= tmp;
2290  }
2291  else {
2292  for( Iterator element=begin(); element!=end(); ++element )
2293  element->value() /= rhs;
2294  }
2295 
2296  return *this;
2297 }
2299 //*************************************************************************************************
2300 
2301 
2302 
2303 
2304 //=================================================================================================
2305 //
2306 // UTILITY FUNCTIONS
2307 //
2308 //=================================================================================================
2309 
2310 //*************************************************************************************************
2316 template< typename MT > // Type of the sparse matrix
2317 inline size_t SparseRow<MT,false>::size() const
2318 {
2319  return matrix_.columns();
2320 }
2322 //*************************************************************************************************
2323 
2324 
2325 //*************************************************************************************************
2331 template< typename MT > // Type of the sparse matrix
2332 inline size_t SparseRow<MT,false>::capacity() const
2333 {
2334  return matrix_.columns();
2335 }
2337 //*************************************************************************************************
2338 
2339 
2340 //*************************************************************************************************
2349 template< typename MT > // Type of the sparse matrix
2350 inline size_t SparseRow<MT,false>::nonZeros() const
2351 {
2352  size_t counter( 0UL );
2353  for( ConstIterator element=begin(); element!=end(); ++element ) {
2354  ++counter;
2355  }
2356  return counter;
2357 }
2359 //*************************************************************************************************
2360 
2361 
2362 //*************************************************************************************************
2368 template< typename MT > // Type of the sparse matrix
2369 inline void SparseRow<MT,false>::reset()
2370 {
2371  for( size_t j=0UL; j<size(); ++j ) {
2372  matrix_.erase( row_, j );
2373  }
2374 }
2376 //*************************************************************************************************
2377 
2378 
2379 //*************************************************************************************************
2392 template< typename MT > // Type of the sparse matrix
2393 inline typename SparseRow<MT,false>::ElementType&
2394  SparseRow<MT,false>::insert( size_t index, const ElementType& value )
2395 {
2396  return matrix_.insert( row_, index, value )->value();
2397 }
2399 //*************************************************************************************************
2400 
2401 
2402 //*************************************************************************************************
2411 template< typename MT > // Type of the sparse matrix
2412 inline void SparseRow<MT,false>::erase( size_t index )
2413 {
2414  matrix_.erase( row_, index );
2415 }
2417 //*************************************************************************************************
2418 
2419 
2420 //*************************************************************************************************
2429 template< typename MT > // Type of the sparse matrix
2430 inline typename SparseRow<MT,false>::Iterator SparseRow<MT,false>::erase( Iterator pos )
2431 {
2432  const size_t column( pos.column_ );
2433 
2434  if( column == size() )
2435  return pos;
2436 
2437  matrix_.erase( column, pos.pos_ );
2438  return Iterator( matrix_, row_, column+1UL );
2439 }
2441 //*************************************************************************************************
2442 
2443 
2444 //*************************************************************************************************
2458 template< typename MT > // Type of the sparse matrix
2459 inline typename SparseRow<MT,false>::Iterator SparseRow<MT,false>::find( size_t index )
2460 {
2461  const typename MT::Iterator pos( matrix_.find( row_, index ) );
2462 
2463  if( pos != matrix_.end( index ) )
2464  return Iterator( matrix_, row_, index, pos );
2465  else
2466  return end();
2467 }
2469 //*************************************************************************************************
2470 
2471 
2472 //*************************************************************************************************
2486 template< typename MT > // Type of the sparse matrix
2487 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::find( size_t index ) const
2488 {
2489  const typename MT::ConstIterator pos( matrix_.find( row_, index ) );
2490 
2491  if( pos != matrix_.end( index ) )
2492  return ConstIterator( matrix_, row_, index, pos );
2493  else
2494  return end();
2495 }
2497 //*************************************************************************************************
2498 
2499 
2500 //*************************************************************************************************
2510 template< typename MT > // Type of the sparse matrix
2511 void SparseRow<MT,false>::reserve( size_t n )
2512 {
2513  return;
2514 }
2516 //*************************************************************************************************
2517 
2518 
2519 //*************************************************************************************************
2526 template< typename MT > // Type of the sparse matrix
2527 template< typename Other > // Data type of the scalar value
2528 inline SparseRow<MT,false>& SparseRow<MT,false>::scale( Other scalar )
2529 {
2530  for( Iterator element=begin(); element!=end(); ++element )
2531  element->value() *= scalar;
2532  return *this;
2533 }
2535 //*************************************************************************************************
2536 
2537 
2538 
2539 
2540 //=================================================================================================
2541 //
2542 // LOW-LEVEL UTILITY FUNCTIONS
2543 //
2544 //=================================================================================================
2545 
2546 //*************************************************************************************************
2571 template< typename MT > // Type of the sparse matrix
2572 inline void SparseRow<MT,false>::append( size_t index, const ElementType& value, bool /*check*/ )
2573 {
2574  matrix_.insert( row_, index, value );
2575 }
2577 //*************************************************************************************************
2578 
2579 
2580 
2581 
2582 //=================================================================================================
2583 //
2584 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2585 //
2586 //=================================================================================================
2587 
2588 //*************************************************************************************************
2599 template< typename MT > // Type of the sparse matrix
2600 template< typename Other > // Data type of the foreign expression
2601 inline bool SparseRow<MT,false>::canAlias( const Other* alias ) const
2602 {
2603  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
2604 }
2606 //*************************************************************************************************
2607 
2608 
2609 //*************************************************************************************************
2616 template< typename MT > // Type of the sparse matrix
2617 template< typename Other > // Data type of the foreign expression
2618 inline bool SparseRow<MT,false>::isAliased( const Other* alias ) const
2619 {
2620  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
2621 }
2623 //*************************************************************************************************
2624 
2625 
2626 //*************************************************************************************************
2638 template< typename MT > // Type of the sparse matrix
2639 template< typename VT > // Type of the right-hand side dense vector
2640 inline void SparseRow<MT,false>::assign( const DenseVector<VT,true>& rhs )
2641 {
2642  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2643 
2644  for( size_t j=0UL; j<(~rhs).size(); ++j ) {
2645  matrix_(row_,j) = (~rhs)[j];
2646  }
2647 }
2649 //*************************************************************************************************
2650 
2651 
2652 //*************************************************************************************************
2664 template< typename MT > // Type of the sparse matrix
2665 template< typename VT > // Type of the right-hand side sparse vector
2666 inline void SparseRow<MT,false>::assign( const SparseVector<VT,true>& rhs )
2667 {
2668  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2669 
2670  size_t j( 0UL );
2671 
2672  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2673  for( ; j<element->index(); ++j )
2674  matrix_.erase( row_, j );
2675  matrix_(row_,j++) = element->value();
2676  }
2677  for( ; j<size(); ++j ) {
2678  matrix_.erase( row_, j );
2679  }
2680 }
2682 //*************************************************************************************************
2683 
2684 
2685 //*************************************************************************************************
2697 template< typename MT > // Type of the sparse matrix
2698 template< typename VT > // Type of the right-hand side vector
2699 inline void SparseRow<MT,false>::addAssign( const Vector<VT,true>& rhs )
2700 {
2701  typedef typename AddTrait<This,typename VT::ResultType>::Type AddType;
2702 
2705 
2706  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2707 
2708  const AddType tmp( *this + (~rhs) );
2709  assign( tmp );
2710 }
2712 //*************************************************************************************************
2713 
2714 
2715 //*************************************************************************************************
2727 template< typename MT > // Type of the sparse matrix
2728 template< typename VT > // Type of the right-hand side vector
2729 inline void SparseRow<MT,false>::subAssign( const Vector<VT,true>& rhs )
2730 {
2731  typedef typename SubTrait<This,typename VT::ResultType>::Type SubType;
2732 
2735 
2736  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2737 
2738  const SubType tmp( *this - (~rhs) );
2739  assign( tmp );
2740 }
2742 //*************************************************************************************************
2743 
2744 
2745 
2746 
2747 
2748 
2749 
2750 
2751 //=================================================================================================
2752 //
2753 // SPARSEROW OPERATORS
2754 //
2755 //=================================================================================================
2756 
2757 //*************************************************************************************************
2760 template< typename MT, bool SO >
2761 inline void reset( SparseRow<MT,SO>& row );
2762 
2763 template< typename MT, bool SO >
2764 inline void clear( SparseRow<MT,SO>& row );
2765 
2766 template< typename MT, bool SO >
2767 inline bool isnan( const SparseRow<MT,SO>& row );
2768 
2769 template< typename MT, bool SO >
2770 inline bool isDefault( const SparseRow<MT,SO>& row );
2772 //*************************************************************************************************
2773 
2774 
2775 //*************************************************************************************************
2782 template< typename MT // Type of the sparse matrix
2783  , bool SO > // Storage order
2784 inline void reset( SparseRow<MT,SO>& row )
2785 {
2786  row.reset();
2787 }
2788 //*************************************************************************************************
2789 
2790 
2791 //*************************************************************************************************
2798 template< typename MT // Type of the sparse matrix
2799  , bool SO > // Storage order
2800 inline void clear( SparseRow<MT,SO>& row )
2801 {
2802  row.reset();
2803 }
2804 //*************************************************************************************************
2805 
2806 
2807 //*************************************************************************************************
2823 template< typename MT // Type of the sparse matrix
2824  , bool SO > // Storage order
2825 inline bool isnan( const SparseRow<MT,SO>& row )
2826 {
2827  typedef typename SparseRow<MT,SO>::ConstIterator ConstIterator;
2828 
2829  const ConstIterator end( row.end() );
2830  for( ConstIterator element=row.begin(); element!=end; ++element ) {
2831  if( isnan( element->value() ) ) return true;
2832  }
2833  return false;
2834 }
2835 //*************************************************************************************************
2836 
2837 
2838 //*************************************************************************************************
2856 template< typename MT // Type of the sparse matrix
2857  , bool SO > // Storage order
2858 inline bool isDefault( const SparseRow<MT,SO>& row )
2859 {
2860  typedef typename SparseRow<MT,SO>::ConstIterator ConstIterator;
2861 
2862  const ConstIterator end( row.end() );
2863  for( ConstIterator element=row.begin(); element!=end; ++element )
2864  if( !isDefault( element->value() ) ) return false;
2865  return true;
2866 }
2867 //*************************************************************************************************
2868 
2869 
2870 
2871 
2872 //=================================================================================================
2873 //
2874 // GLOBAL OPERATORS
2875 //
2876 //=================================================================================================
2877 
2878 //*************************************************************************************************
2897 template< typename MT // Type of the sparse matrix
2898  , bool SO > // Storage order
2899 inline typename DisableIf< IsExpression<MT>, SparseRow<MT> >::Type
2900  row( SparseMatrix<MT,SO>& sm, size_t index )
2901 {
2903 
2904  return SparseRow<MT>( ~sm, index );
2905 }
2906 //*************************************************************************************************
2907 
2908 
2909 //*************************************************************************************************
2928 template< typename MT // Type of the sparse matrix
2929  , bool SO > // Storage order
2930 inline typename DisableIf< IsExpression<MT>, SparseRow<const MT> >::Type
2931  row( const SparseMatrix<MT,SO>& sm, size_t index )
2932 {
2934 
2935  return SparseRow<const MT>( ~sm, index );
2936 }
2937 //*************************************************************************************************
2938 
2939 
2940 
2941 
2942 //=================================================================================================
2943 //
2944 // GLOBAL RESTRUCTURING OPERATORS
2945 //
2946 //=================================================================================================
2947 
2948 //*************************************************************************************************
2960 template< typename MT // Type of the sparse matrix
2961  , bool SO > // Storage order
2962 inline typename EnableIf< IsMatMatAddExpr<MT>, typename RowExprTrait<MT>::Type >::Type
2963  row( const SparseMatrix<MT,SO>& dm, size_t index )
2964 {
2966 
2967  return row( (~dm).leftOperand(), index ) + row( (~dm).rightOperand(), index );
2968 }
2970 //*************************************************************************************************
2971 
2972 
2973 //*************************************************************************************************
2985 template< typename MT // Type of the sparse matrix
2986  , bool SO > // Storage order
2987 inline typename EnableIf< IsMatMatSubExpr<MT>, typename RowExprTrait<MT>::Type >::Type
2988  row( const SparseMatrix<MT,SO>& dm, size_t index )
2989 {
2991 
2992  return row( (~dm).leftOperand(), index ) - row( (~dm).rightOperand(), index );
2993 }
2995 //*************************************************************************************************
2996 
2997 
2998 //*************************************************************************************************
3010 template< typename MT // Type of the sparse matrix
3011  , bool SO > // Storage order
3012 inline typename EnableIf< IsMatMatMultExpr<MT>, typename RowExprTrait<MT>::Type >::Type
3013  row( const SparseMatrix<MT,SO>& dm, size_t index )
3014 {
3016 
3017  return row( (~dm).leftOperand(), index ) * (~dm).rightOperand();
3018 }
3020 //*************************************************************************************************
3021 
3022 
3023 //*************************************************************************************************
3034 template< typename MT // Type of the sparse matrix
3035  , bool SO > // Storage order
3036 inline typename EnableIf< IsVecTVecMultExpr<MT>, typename RowExprTrait<MT>::Type >::Type
3037  row( const SparseMatrix<MT,SO>& dm, size_t index )
3038 {
3040 
3041  return (~dm).leftOperand()[index] * (~dm).rightOperand();
3042 }
3044 //*************************************************************************************************
3045 
3046 
3047 //*************************************************************************************************
3059 template< typename MT // Type of the sparse matrix
3060  , bool SO > // Storage order
3061 inline typename EnableIf< IsMatScalarMultExpr<MT>, typename RowExprTrait<MT>::Type >::Type
3062  row( const SparseMatrix<MT,SO>& dm, size_t index )
3063 {
3065 
3066  return row( (~dm).leftOperand(), index ) * (~dm).rightOperand();
3067 }
3069 //*************************************************************************************************
3070 
3071 
3072 //*************************************************************************************************
3084 template< typename MT // Type of the sparse matrix
3085  , bool SO > // Storage order
3086 inline typename EnableIf< IsMatScalarDivExpr<MT>, typename RowExprTrait<MT>::Type >::Type
3087  row( const SparseMatrix<MT,SO>& dm, size_t index )
3088 {
3090 
3091  return row( (~dm).leftOperand(), index ) / (~dm).rightOperand();
3092 }
3094 //*************************************************************************************************
3095 
3096 
3097 //*************************************************************************************************
3109 template< typename MT // Type of the sparse matrix
3110  , bool SO > // Storage order
3111 inline typename EnableIf< IsMatAbsExpr<MT>, typename RowExprTrait<MT>::Type >::Type
3112  row( const SparseMatrix<MT,SO>& dm, size_t index )
3113 {
3115 
3116  return abs( row( (~dm).operand(), index ) );
3117 }
3119 //*************************************************************************************************
3120 
3121 
3122 //*************************************************************************************************
3134 template< typename MT // Type of the sparse matrix
3135  , bool SO > // Storage order
3136 inline typename EnableIf< IsMatEvalExpr<MT>, typename RowExprTrait<MT>::Type >::Type
3137  row( const SparseMatrix<MT,SO>& dm, size_t index )
3138 {
3140 
3141  return eval( row( (~dm).operand(), index ) );
3142 }
3144 //*************************************************************************************************
3145 
3146 
3147 //*************************************************************************************************
3159 template< typename MT // Type of the sparse matrix
3160  , bool SO > // Storage order
3161 inline typename EnableIf< IsMatTransExpr<MT>, typename RowExprTrait<MT>::Type >::Type
3162  row( const SparseMatrix<MT,SO>& dm, size_t index )
3163 {
3165 
3166  return trans( column( (~dm).operand(), index ) );
3167 }
3169 //*************************************************************************************************
3170 
3171 
3172 
3173 
3174 //=================================================================================================
3175 //
3176 // ADDTRAIT SPECIALIZATIONS
3177 //
3178 //=================================================================================================
3179 
3180 //*************************************************************************************************
3182 template< typename T1, bool SO, typename T2, size_t N >
3183 struct AddTrait< SparseRow<T1,SO>, StaticVector<T2,N,true> >
3184 {
3185  typedef typename AddTrait< typename SparseRow<T1,SO>::ResultType,
3186  StaticVector<T2,N,true> >::Type Type;
3187 };
3188 
3189 template< typename T1, size_t N, typename T2, bool SO >
3190 struct AddTrait< StaticVector<T1,N,true>, SparseRow<T2,SO> >
3191 {
3192  typedef typename AddTrait< StaticVector<T1,N,true>,
3193  typename SparseRow<T2,SO>::ResultType >::Type Type;
3194 };
3195 
3196 template< typename T1, bool SO, typename T2 >
3197 struct AddTrait< SparseRow<T1,SO>, DynamicVector<T2,true> >
3198 {
3199  typedef typename AddTrait< typename SparseRow<T1,SO>::ResultType,
3200  DynamicVector<T2,true> >::Type Type;
3201 };
3202 
3203 template< typename T1, typename T2, bool SO >
3204 struct AddTrait< DynamicVector<T1,true>, SparseRow<T2,SO> >
3205 {
3206  typedef typename AddTrait< DynamicVector<T1,true>,
3207  typename SparseRow<T2,SO>::ResultType >::Type Type;
3208 };
3209 
3210 template< typename T1, bool SO1, typename T2, bool SO2 >
3211 struct AddTrait< SparseRow<T1,SO1>, DenseRow<T2,SO2> >
3212 {
3213  typedef typename AddTrait< typename SparseRow<T1,SO1>::ResultType,
3214  typename DenseRow <T2,SO2>::ResultType >::Type Type;
3215 };
3216 
3217 template< typename T1, bool SO1, typename T2, bool SO2 >
3218 struct AddTrait< DenseRow<T1,SO1>, SparseRow<T2,SO2> >
3219 {
3220  typedef typename AddTrait< typename DenseRow <T1,SO1>::ResultType,
3221  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3222 };
3223 
3224 template< typename T1, bool SO, typename T2 >
3225 struct AddTrait< SparseRow<T1,SO>, CompressedVector<T2,true> >
3226 {
3227  typedef typename AddTrait< typename SparseRow<T1,SO>::ResultType,
3228  CompressedVector<T2,true> >::Type Type;
3229 };
3230 
3231 template< typename T1, typename T2, bool SO >
3232 struct AddTrait< CompressedVector<T1,true>, SparseRow<T2,SO> >
3233 {
3234  typedef typename AddTrait< CompressedVector<T1,true>,
3235  typename SparseRow<T2,SO>::ResultType >::Type Type;
3236 };
3237 
3238 template< typename T1, bool SO1, typename T2, bool SO2 >
3239 struct AddTrait< SparseRow<T1,SO1>, SparseRow<T2,SO2> >
3240 {
3241  typedef typename AddTrait< typename SparseRow<T1,SO1>::ResultType,
3242  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3243 };
3245 //*************************************************************************************************
3246 
3247 
3248 
3249 
3250 //=================================================================================================
3251 //
3252 // SUBTRAIT SPECIALIZATIONS
3253 //
3254 //=================================================================================================
3255 
3256 //*************************************************************************************************
3258 template< typename T1, bool SO, typename T2, size_t N >
3259 struct SubTrait< SparseRow<T1,SO>, StaticVector<T2,N,true> >
3260 {
3261  typedef typename SubTrait< typename SparseRow<T1,SO>::ResultType,
3262  StaticVector<T2,N,true> >::Type Type;
3263 };
3264 
3265 template< typename T1, size_t N, typename T2, bool SO >
3266 struct SubTrait< StaticVector<T1,N,true>, SparseRow<T2,SO> >
3267 {
3268  typedef typename SubTrait< StaticVector<T1,N,true>,
3269  typename SparseRow<T2,SO>::ResultType >::Type Type;
3270 };
3271 
3272 template< typename T1, bool SO, typename T2 >
3273 struct SubTrait< SparseRow<T1,SO>, DynamicVector<T2,true> >
3274 {
3275  typedef typename SubTrait< typename SparseRow<T1,SO>::ResultType,
3276  DynamicVector<T2,true> >::Type Type;
3277 };
3278 
3279 template< typename T1, typename T2, bool SO >
3280 struct SubTrait< DynamicVector<T1,true>, SparseRow<T2,SO> >
3281 {
3282  typedef typename SubTrait< DynamicVector<T1,true>,
3283  typename SparseRow<T2,SO>::ResultType >::Type Type;
3284 };
3285 
3286 template< typename T1, bool SO1, typename T2, bool SO2 >
3287 struct SubTrait< SparseRow<T1,SO1>, DenseRow<T2,SO2> >
3288 {
3289  typedef typename SubTrait< typename SparseRow<T1,SO1>::ResultType,
3290  typename DenseRow <T2,SO2>::ResultType >::Type Type;
3291 };
3292 
3293 template< typename T1, bool SO1, typename T2, bool SO2 >
3294 struct SubTrait< DenseRow<T1,SO1>, SparseRow<T2,SO2> >
3295 {
3296  typedef typename SubTrait< typename DenseRow <T1,SO1>::ResultType,
3297  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3298 };
3299 
3300 template< typename T1, bool SO, typename T2 >
3301 struct SubTrait< SparseRow<T1,SO>, CompressedVector<T2,true> >
3302 {
3303  typedef typename SubTrait< typename SparseRow<T1,SO>::ResultType,
3304  CompressedVector<T2,true> >::Type Type;
3305 };
3306 
3307 template< typename T1, typename T2, bool SO >
3308 struct SubTrait< CompressedVector<T1,true>, SparseRow<T2,SO> >
3309 {
3310  typedef typename SubTrait< CompressedVector<T1,true>,
3311  typename SparseRow<T2,SO>::ResultType >::Type Type;
3312 };
3313 
3314 template< typename T1, bool SO1, typename T2, bool SO2 >
3315 struct SubTrait< SparseRow<T1,SO1>, SparseRow<T2,SO2> >
3316 {
3317  typedef typename SubTrait< typename SparseRow<T1,SO1>::ResultType,
3318  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3319 };
3321 //*************************************************************************************************
3322 
3323 
3324 
3325 
3326 //=================================================================================================
3327 //
3328 // MULTTRAIT SPECIALIZATIONS
3329 //
3330 //=================================================================================================
3331 
3332 //*************************************************************************************************
3334 template< typename T1, bool SO, typename T2 >
3335 struct MultTrait< SparseRow<T1,SO>, T2 >
3336 {
3337  typedef typename MultTrait< typename SparseRow<T1,SO>::ResultType, T2 >::Type Type;
3339 };
3340 
3341 template< typename T1, typename T2, bool SO >
3342 struct MultTrait< T1, SparseRow<T2,SO> >
3343 {
3344  typedef typename MultTrait< T1, typename SparseRow<T2,SO>::ResultType >::Type Type;
3346 };
3347 
3348 template< typename T1, bool SO, typename T2, size_t N, bool TF >
3349 struct MultTrait< SparseRow<T1,SO>, StaticVector<T2,N,TF> >
3350 {
3351  typedef typename MultTrait< typename SparseRow<T1,SO>::ResultType,
3352  StaticVector<T2,N,TF> >::Type Type;
3353 };
3354 
3355 template< typename T1, size_t N, bool TF, typename T2, bool SO >
3356 struct MultTrait< StaticVector<T1,N,TF>, SparseRow<T2,SO> >
3357 {
3358  typedef typename MultTrait< StaticVector<T1,N,TF>,
3359  typename SparseRow<T2,SO>::ResultType >::Type Type;
3360 };
3361 
3362 template< typename T1, bool SO, typename T2, bool TF >
3363 struct MultTrait< SparseRow<T1,SO>, DynamicVector<T2,TF> >
3364 {
3365  typedef typename MultTrait< typename SparseRow<T1,SO>::ResultType,
3366  DynamicVector<T2,TF> >::Type Type;
3367 };
3368 
3369 template< typename T1, bool TF, typename T2, bool SO >
3370 struct MultTrait< DynamicVector<T1,TF>, SparseRow<T2,SO> >
3371 {
3372  typedef typename MultTrait< DynamicVector<T1,TF>,
3373  typename SparseRow<T2,SO>::ResultType >::Type Type;
3374 };
3375 
3376 template< typename T1, bool SO1, typename T2, bool SO2 >
3377 struct MultTrait< SparseRow<T1,SO1>, DenseRow<T2,SO2> >
3378 {
3379  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3380  typename DenseRow <T2,SO2>::ResultType >::Type Type;
3381 };
3382 
3383 template< typename T1, bool SO1, typename T2, bool SO2 >
3384 struct MultTrait< DenseRow<T1,SO1>, SparseRow<T2,SO2> >
3385 {
3386  typedef typename MultTrait< typename DenseRow <T1,SO1>::ResultType,
3387  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3388 };
3389 
3390 template< typename T1, bool SO, typename T2, bool TF >
3391 struct MultTrait< SparseRow<T1,SO>, CompressedVector<T2,TF> >
3392 {
3393  typedef typename MultTrait< typename SparseRow<T1,SO>::ResultType,
3394  CompressedVector<T2,TF> >::Type Type;
3395 };
3396 
3397 template< typename T1, bool TF, typename T2, bool SO >
3398 struct MultTrait< CompressedVector<T1,TF>, SparseRow<T2,SO> >
3399 {
3400  typedef typename MultTrait< CompressedVector<T1,TF>,
3401  typename SparseRow<T2,SO>::ResultType >::Type Type;
3402 };
3403 
3404 template< typename T1, bool SO1, typename T2, bool SO2 >
3405 struct MultTrait< SparseRow<T1,SO1>, SparseRow<T2,SO2> >
3406 {
3407  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3408  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3409 };
3410 
3411 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
3412 struct MultTrait< SparseRow<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
3413 {
3414  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3415  StaticMatrix<T2,M,N,SO2> >::Type Type;
3416 };
3417 
3418 template< typename T1, bool SO1, typename T2, bool SO2 >
3419 struct MultTrait< SparseRow<T1,SO1>, DynamicMatrix<T2,SO2> >
3420 {
3421  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3422  DynamicMatrix<T2,SO2> >::Type Type;
3423 };
3424 
3425 template< typename T1, bool SO1, typename T2, bool SO2 >
3426 struct MultTrait< SparseRow<T1,SO1>, CompressedMatrix<T2,SO2> >
3427 {
3428  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3429  CompressedMatrix<T2,SO2> >::Type Type;
3430 };
3432 //*************************************************************************************************
3433 
3434 
3435 
3436 
3437 //=================================================================================================
3438 //
3439 // DIVTRAIT SPECIALIZATIONS
3440 //
3441 //=================================================================================================
3442 
3443 //*************************************************************************************************
3445 template< typename T1, bool SO, typename T2 >
3446 struct DivTrait< SparseRow<T1,SO>, T2 >
3447 {
3448  typedef typename DivTrait< typename SparseRow<T1,SO>::ResultType, T2 >::Type Type;
3450 };
3452 //*************************************************************************************************
3453 
3454 } // namespace blaze
3455 
3456 #endif