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>
51 #include <blaze/util/Assert.h>
52 #include <blaze/util/DisableIf.h>
53 #include <blaze/util/EnableIf.h>
55 #include <blaze/util/mpl/If.h>
56 #include <blaze/util/SelectType.h>
57 #include <blaze/util/Types.h>
61 
62 
63 namespace blaze {
64 
65 //=================================================================================================
66 //
67 // CLASS DEFINITION
68 //
69 //=================================================================================================
70 
71 //*************************************************************************************************
321 template< typename MT // Type of the sparse matrix
322  , bool SO = IsRowMajorMatrix<MT>::value > // Storage order
323 class SparseRow : public SparseVector< SparseRow<MT,SO>, true >
324  , private Expression
325 {
326  private:
327  //**********************************************************************************************
329 
335  enum { useConst = IsConst<MT>::value };
336  //**********************************************************************************************
337 
338  public:
339  //**Type definitions****************************************************************************
341  typedef typename RowTrait<MT>::Type ResultType;
342  typedef typename ResultType::TransposeType TransposeType;
343  typedef typename MT::ElementType ElementType;
344  typedef typename MT::ReturnType ReturnType;
345  typedef const SparseRow& CompositeType;
346 
348  typedef typename MT::ConstReference ConstReference;
349 
352 
354  typedef typename MT::ConstIterator ConstIterator;
355 
358  //**********************************************************************************************
359 
360  //**Constructors********************************************************************************
363  explicit inline SparseRow( MT& matrix, size_t index );
364  // No explicitly declared copy constructor.
366  //**********************************************************************************************
367 
368  //**Destructor**********************************************************************************
369  // No explicitly declared destructor.
370  //**********************************************************************************************
371 
372  //**Data access functions***********************************************************************
375  inline Reference operator[]( size_t index );
376  inline ConstReference operator[]( size_t index ) const;
377  inline Iterator begin ();
378  inline ConstIterator begin () const;
379  inline ConstIterator cbegin() const;
380  inline Iterator end ();
381  inline ConstIterator end () const;
382  inline ConstIterator cend () const;
384  //**********************************************************************************************
385 
386  //**Assignment operators************************************************************************
389  inline SparseRow& operator= ( const SparseRow& rhs );
390  template< typename VT > inline SparseRow& operator= ( const DenseVector <VT,true>& rhs );
391  template< typename VT > inline SparseRow& operator= ( const SparseVector<VT,true>& rhs );
392  template< typename VT > inline SparseRow& operator+=( const Vector<VT,true>& rhs );
393  template< typename VT > inline SparseRow& operator-=( const Vector<VT,true>& rhs );
394  template< typename VT > inline SparseRow& operator*=( const Vector<VT,true>& rhs );
395 
396  template< typename Other >
397  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
398  operator*=( Other rhs );
399 
400  template< typename Other >
401  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
402  operator/=( Other rhs );
404  //**********************************************************************************************
405 
406  //**Utility functions***************************************************************************
409  inline size_t size() const;
410  inline size_t capacity() const;
411  inline size_t nonZeros() const;
412  inline void reset();
413  inline ElementType& insert ( size_t index, const ElementType& value );
414  inline void erase ( size_t index );
415  inline Iterator erase ( Iterator pos );
416  inline Iterator find ( size_t index );
417  inline ConstIterator find ( size_t index ) const;
418  inline void reserve( size_t n );
419  template< typename Other > inline SparseRow& scale ( Other scalar );
421  //**********************************************************************************************
422 
423  //**Low-level utility functions*****************************************************************
426  inline void append( size_t index, const ElementType& value, bool check=false );
428  //**********************************************************************************************
429 
430  //**Expression template evaluation functions****************************************************
433  template< typename Other > inline bool canAlias ( const Other* alias ) const;
434  template< typename Other > inline bool isAliased( const Other* alias ) const;
435  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
436  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
437  template< typename VT > inline void addAssign( const DenseVector <VT,true>& rhs );
438  template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
439  template< typename VT > inline void subAssign( const DenseVector <VT,true>& rhs );
440  template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
442  //**********************************************************************************************
443 
444  private:
445  //**Utility functions***************************************************************************
448  inline size_t extendCapacity() const;
450  //**********************************************************************************************
451 
452  //**Member variables****************************************************************************
455  MT& matrix_;
456  const size_t row_;
457 
458  //**********************************************************************************************
459 
460  //**Compile time checks*************************************************************************
466  //**********************************************************************************************
467 };
468 //*************************************************************************************************
469 
470 
471 
472 
473 //=================================================================================================
474 //
475 // CONSTRUCTOR
476 //
477 //=================================================================================================
478 
479 //*************************************************************************************************
486 template< typename MT // Type of the sparse matrix
487  , bool SO > // Storage order
488 inline SparseRow<MT,SO>::SparseRow( MT& matrix, size_t index )
489  : matrix_( matrix ) // The sparse matrix containing the row
490  , row_ ( index ) // The index of the row in the matrix
491 {
492  if( matrix_.rows() <= index )
493  throw std::invalid_argument( "Invalid row access index" );
494 }
495 //*************************************************************************************************
496 
497 
498 
499 
500 //=================================================================================================
501 //
502 // DATA ACCESS FUNCTIONS
503 //
504 //=================================================================================================
505 
506 //*************************************************************************************************
512 template< typename MT // Type of the sparse matrix
513  , bool SO > // Storage order
515 {
516  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
517  return matrix_(row_,index);
518 }
519 //*************************************************************************************************
520 
521 
522 //*************************************************************************************************
528 template< typename MT // Type of the sparse matrix
529  , bool SO > // Storage order
531 {
532  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
533  return const_cast<const MT&>( matrix_ )(row_,index);
534 }
535 //*************************************************************************************************
536 
537 
538 //*************************************************************************************************
545 template< typename MT // Type of the sparse matrix
546  , bool SO > // Storage order
548 {
549  return matrix_.begin( row_ );
550 }
551 //*************************************************************************************************
552 
553 
554 //*************************************************************************************************
561 template< typename MT // Type of the sparse matrix
562  , bool SO > // Storage order
564 {
565  return matrix_.begin( row_ );
566 }
567 //*************************************************************************************************
568 
569 
570 //*************************************************************************************************
577 template< typename MT // Type of the sparse matrix
578  , bool SO > // Storage order
580 {
581  return matrix_.begin( row_ );
582 }
583 //*************************************************************************************************
584 
585 
586 //*************************************************************************************************
593 template< typename MT // Type of the sparse matrix
594  , bool SO > // Storage order
596 {
597  return matrix_.end( row_ );
598 }
599 //*************************************************************************************************
600 
601 
602 //*************************************************************************************************
609 template< typename MT // Type of the sparse matrix
610  , bool SO > // Storage order
612 {
613  return matrix_.end( row_ );
614 }
615 //*************************************************************************************************
616 
617 
618 //*************************************************************************************************
625 template< typename MT // Type of the sparse matrix
626  , bool SO > // Storage order
628 {
629  return matrix_.end( row_ );
630 }
631 //*************************************************************************************************
632 
633 
634 
635 
636 //=================================================================================================
637 //
638 // ASSIGNMENT OPERATORS
639 //
640 //=================================================================================================
641 
642 //*************************************************************************************************
652 template< typename MT // Type of the sparse matrix
653  , bool SO > // Storage order
655 {
656  using blaze::assign;
657 
658  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
659  return *this;
660 
661  if( size() != rhs.size() )
662  throw std::invalid_argument( "Row sizes do not match" );
663 
664  if( rhs.canAlias( &matrix_ ) ) {
665  const ResultType tmp( rhs );
666  matrix_.reset ( row_ );
667  matrix_.reserve( row_, tmp.nonZeros() );
668  assign( *this, tmp );
669  }
670  else {
671  matrix_.reset ( row_ );
672  matrix_.reserve( row_, rhs.nonZeros() );
673  assign( *this, rhs );
674  }
675 
676  return *this;
677 }
678 //*************************************************************************************************
679 
680 
681 //*************************************************************************************************
691 template< typename MT // Type of the sparse matrix
692  , bool SO > // Storage order
693 template< typename VT > // Type of the right-hand side dense vector
695 {
696  using blaze::assign;
697 
698  if( size() != (~rhs).size() )
699  throw std::invalid_argument( "Vector sizes do not match" );
700 
701  if( (~rhs).canAlias( &matrix_ ) ) {
702  const typename VT::ResultType tmp( ~rhs );
703  matrix_.reset( row_ );
704  assign( *this, tmp );
705  }
706  else {
707  matrix_.reset( row_ );
708  assign( *this, ~rhs );
709  }
710 
711  return *this;
712 }
713 //*************************************************************************************************
714 
715 
716 //*************************************************************************************************
726 template< typename MT // Type of the sparse matrix
727  , bool SO > // Storage order
728 template< typename VT > // Type of the right-hand side sparse vector
730 {
731  using blaze::assign;
732 
733  if( size() != (~rhs).size() )
734  throw std::invalid_argument( "Vector sizes do not match" );
735 
736  if( (~rhs).canAlias( &matrix_ ) ) {
737  const typename VT::ResultType tmp( ~rhs );
738  matrix_.reset ( row_ );
739  matrix_.reserve( row_, tmp.nonZeros() );
740  assign( *this, tmp );
741  }
742  else {
743  matrix_.reset ( row_ );
744  matrix_.reserve( row_, (~rhs).nonZeros() );
745  assign( *this, ~rhs );
746  }
747 
748  return *this;
749 }
750 //*************************************************************************************************
751 
752 
753 //*************************************************************************************************
763 template< typename MT // Type of the sparse matrix
764  , bool SO > // Storage order
765 template< typename VT > // Type of the right-hand side vector
767 {
768  using blaze::addAssign;
769 
770  if( (~rhs).size() != size() )
771  throw std::invalid_argument( "Vector sizes do not match" );
772 
773  addAssign( *this, ~rhs );
774 
775  return *this;
776 }
777 //*************************************************************************************************
778 
779 
780 //*************************************************************************************************
790 template< typename MT // Type of the sparse matrix
791  , bool SO > // Storage order
792 template< typename VT > // Type of the right-hand side vector
794 {
795  using blaze::subAssign;
796 
797  if( (~rhs).size() != size() )
798  throw std::invalid_argument( "Vector sizes do not match" );
799 
800  subAssign( *this, ~rhs );
801 
802  return *this;
803 }
804 //*************************************************************************************************
805 
806 
807 //*************************************************************************************************
818 template< typename MT // Type of the sparse matrix
819  , bool SO > // Storage order
820 template< typename VT > // Type of the right-hand side vector
822 {
823  if( (~rhs).size() != size() )
824  throw std::invalid_argument( "Vector sizes do not match" );
825 
826  typedef typename MultTrait<This,typename VT::ResultType>::Type MultType;
827 
830 
831  const MultType tmp( *this * (~rhs) );
832  matrix_.reset( row_ );
833  assign( tmp );
834 
835  return *this;
836 }
837 //*************************************************************************************************
838 
839 
840 //*************************************************************************************************
851 template< typename MT // Type of the sparse matrix
852  , bool SO > // Storage order
853 template< typename Other > // Data type of the right-hand side scalar
854 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,SO> >::Type&
856 {
857  for( Iterator element=begin(); element!=end(); ++element )
858  element->value() *= rhs;
859  return *this;
860 }
861 //*************************************************************************************************
862 
863 
864 //*************************************************************************************************
876 template< typename MT // Type of the sparse matrix
877  , bool SO > // Storage order
878 template< typename Other > // Data type of the right-hand side scalar
879 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,SO> >::Type&
881 {
882  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
883 
884  typedef typename DivTrait<ElementType,Other>::Type DT;
885  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
886 
887  // Depending on the two involved data types, an integer division is applied or a
888  // floating point division is selected.
890  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
891  for( Iterator element=begin(); element!=end(); ++element )
892  element->value() *= tmp;
893  }
894  else {
895  for( Iterator element=begin(); element!=end(); ++element )
896  element->value() /= rhs;
897  }
898 
899  return *this;
900 }
901 //*************************************************************************************************
902 
903 
904 
905 
906 //=================================================================================================
907 //
908 // UTILITY FUNCTIONS
909 //
910 //=================================================================================================
911 
912 //*************************************************************************************************
917 template< typename MT // Type of the sparse matrix
918  , bool SO > // Storage order
919 inline size_t SparseRow<MT,SO>::size() const
920 {
921  return matrix_.columns();
922 }
923 //*************************************************************************************************
924 
925 
926 //*************************************************************************************************
931 template< typename MT // Type of the sparse matrix
932  , bool SO > // Storage order
933 inline size_t SparseRow<MT,SO>::capacity() const
934 {
935  return matrix_.capacity( row_ );
936 }
937 //*************************************************************************************************
938 
939 
940 //*************************************************************************************************
948 template< typename MT // Type of the sparse matrix
949  , bool SO > // Storage order
950 inline size_t SparseRow<MT,SO>::nonZeros() const
951 {
952  return matrix_.nonZeros( row_ );
953 }
954 //*************************************************************************************************
955 
956 
957 //*************************************************************************************************
962 template< typename MT // Type of the sparse matrix
963  , bool SO > // Storage order
965 {
966  matrix_.reset( row_ );
967 }
968 //*************************************************************************************************
969 
970 
971 //*************************************************************************************************
983 template< typename MT // Type of the sparse matrix
984  , bool SO > // Storage order
985 inline typename SparseRow<MT,SO>::ElementType&
986  SparseRow<MT,SO>::insert( size_t index, const ElementType& value )
987 {
988  return matrix_.insert( row_, index, value )->value();
989 }
990 //*************************************************************************************************
991 
992 
993 //*************************************************************************************************
1001 template< typename MT // Type of the sparse matrix
1002  , bool SO > // Storage order
1003 inline void SparseRow<MT,SO>::erase( size_t index )
1004 {
1005  matrix_.erase( row_, index );
1006 }
1007 //*************************************************************************************************
1008 
1009 
1010 //*************************************************************************************************
1018 template< typename MT // Type of the sparse matrix
1019  , bool SO > // Storage order
1021 {
1022  return matrix_.erase( row_, pos );
1023 }
1024 //*************************************************************************************************
1025 
1026 
1027 //*************************************************************************************************
1040 template< typename MT // Type of the sparse matrix
1041  , bool SO > // Storage order
1043 {
1044  return matrix_.find( row_, index );
1045 }
1046 //*************************************************************************************************
1047 
1048 
1049 //*************************************************************************************************
1062 template< typename MT // Type of the sparse matrix
1063  , bool SO > // Storage order
1064 inline typename SparseRow<MT,SO>::ConstIterator SparseRow<MT,SO>::find( size_t index ) const
1065 {
1066  return matrix_.find( row_, index );
1067 }
1068 //*************************************************************************************************
1069 
1070 
1071 //*************************************************************************************************
1080 template< typename MT // Type of the sparse matrix
1081  , bool SO > // Storage order
1083 {
1084  matrix_.reserve( row_, n );
1085 }
1086 //*************************************************************************************************
1087 
1088 
1089 //*************************************************************************************************
1095 template< typename MT // Type of the sparse matrix
1096  , bool SO > // Storage order
1097 template< typename Other > // Data type of the scalar value
1099 {
1100  for( Iterator element=begin(); element!=end(); ++element )
1101  element->value() *= scalar;
1102  return *this;
1103 }
1104 //*************************************************************************************************
1105 
1106 
1107 //*************************************************************************************************
1115 template< typename MT // Type of the sparse matrix
1116  , bool SO > // Storage order
1118 {
1119  using blaze::max;
1120  using blaze::min;
1121 
1122  size_t nonzeros( 2UL*capacity()+1UL );
1123  nonzeros = max( nonzeros, 7UL );
1124  nonzeros = min( nonzeros, size() );
1125 
1126  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1127 
1128  return nonzeros;
1129 }
1130 //*************************************************************************************************
1131 
1132 
1133 
1134 
1135 //=================================================================================================
1136 //
1137 // LOW-LEVEL UTILITY FUNCTIONS
1138 //
1139 //=================================================================================================
1140 
1141 //*************************************************************************************************
1165 template< typename MT // Type of the sparse matrix
1166  , bool SO > // Storage order
1167 inline void SparseRow<MT,SO>::append( size_t index, const ElementType& value, bool check )
1168 {
1169  matrix_.append( row_, index, value, check );
1170 }
1171 //*************************************************************************************************
1172 
1173 
1174 
1175 
1176 //=================================================================================================
1177 //
1178 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1179 //
1180 //=================================================================================================
1181 
1182 //*************************************************************************************************
1192 template< typename MT // Type of the sparse matrix
1193  , bool SO > // Storage order
1194 template< typename Other > // Data type of the foreign expression
1195 inline bool SparseRow<MT,SO>::canAlias( const Other* alias ) const
1196 {
1197  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1198 }
1199 //*************************************************************************************************
1200 
1201 
1202 //*************************************************************************************************
1212 template< typename MT // Type of the sparse matrix
1213  , bool SO > // Storage order
1214 template< typename Other > // Data type of the foreign expression
1215 inline bool SparseRow<MT,SO>::isAliased( const Other* alias ) const
1216 {
1217  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
1218 }
1219 //*************************************************************************************************
1220 
1221 
1222 //*************************************************************************************************
1233 template< typename MT // Type of the sparse matrix
1234  , bool SO > // Storage order
1235 template< typename VT > // Type of the right-hand side dense vector
1237 {
1238  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1239 
1240  size_t nonzeros( 0UL );
1241 
1242  for( size_t j=0UL; j<size(); ++j )
1243  {
1244  if( matrix_.nonZeros( row_ ) == matrix_.capacity( row_ ) )
1245  matrix_.reserve( row_, extendCapacity() );
1246 
1247  matrix_.append( row_, j, (~rhs)[j], true );
1248  }
1249 }
1250 //*************************************************************************************************
1251 
1252 
1253 //*************************************************************************************************
1264 template< typename MT // Type of the sparse matrix
1265  , bool SO > // Storage order
1266 template< typename VT > // Type of the right-hand side sparse vector
1268 {
1269  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1270 
1271  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
1272  matrix_.append( row_, element->index(), element->value() );
1273  }
1274 }
1275 //*************************************************************************************************
1276 
1277 
1278 //*************************************************************************************************
1289 template< typename MT // Type of the sparse matrix
1290  , bool SO > // Storage order
1291 template< typename VT > // Type of the right-hand side dense vector
1293 {
1294  typedef typename AddTrait<This,typename VT::ResultType>::Type AddType;
1295 
1299 
1300  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1301 
1302  const AddType tmp( *this + (~rhs) );
1303  matrix_.reset( row_ );
1304  assign( tmp );
1305 }
1306 //*************************************************************************************************
1307 
1308 
1309 //*************************************************************************************************
1320 template< typename MT // Type of the sparse matrix
1321  , bool SO > // Storage order
1322 template< typename VT > // Type of the right-hand side sparse vector
1324 {
1325  typedef typename AddTrait<This,typename VT::ResultType>::Type AddType;
1326 
1330 
1331  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1332 
1333  const AddType tmp( *this + (~rhs) );
1334  matrix_.reset ( row_ );
1335  matrix_.reserve( row_, tmp.nonZeros() );
1336  assign( tmp );
1337 }
1338 //*************************************************************************************************
1339 
1340 
1341 //*************************************************************************************************
1352 template< typename MT // Type of the sparse matrix
1353  , bool SO > // Storage order
1354 template< typename VT > // Type of the right-hand side dense vector
1356 {
1357  typedef typename SubTrait<This,typename VT::ResultType>::Type SubType;
1358 
1362 
1363  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1364 
1365  const SubType tmp( *this - (~rhs) );
1366  matrix_.reset ( row_ );
1367  assign( tmp );
1368 }
1369 //*************************************************************************************************
1370 
1371 
1372 //*************************************************************************************************
1383 template< typename MT // Type of the sparse matrix
1384  , bool SO > // Storage order
1385 template< typename VT > // Type of the right-hand side sparse vector
1387 {
1388  typedef typename SubTrait<This,typename VT::ResultType>::Type SubType;
1389 
1393 
1394  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1395 
1396  const SubType tmp( *this - (~rhs) );
1397  matrix_.reset ( row_ );
1398  matrix_.reserve( row_, tmp.nonZeros() );
1399  assign( tmp );
1400 }
1401 //*************************************************************************************************
1402 
1403 
1404 
1405 
1406 
1407 
1408 
1409 
1410 //=================================================================================================
1411 //
1412 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR MATRICES
1413 //
1414 //=================================================================================================
1415 
1416 //*************************************************************************************************
1424 template< typename MT > // Type of the sparse matrix
1425 class SparseRow<MT,false> : public SparseVector< SparseRow<MT,false>, true >
1426  , private Expression
1427 {
1428  private:
1429  //**********************************************************************************************
1431 
1437  enum { useConst = IsConst<MT>::value };
1438  //**********************************************************************************************
1439 
1440  public:
1441  //**Type definitions****************************************************************************
1442  typedef SparseRow<MT,false> This;
1443  typedef typename RowTrait<MT>::Type ResultType;
1444  typedef typename ResultType::TransposeType TransposeType;
1445  typedef typename MT::ElementType ElementType;
1446  typedef typename MT::ReturnType ReturnType;
1447  typedef const ResultType CompositeType;
1448 
1450  typedef typename MT::ConstReference ConstReference;
1451 
1453  typedef typename SelectType< useConst, ConstReference, typename MT::Reference >::Type Reference;
1454  //**********************************************************************************************
1455 
1456  //**RowElement class definition*****************************************************************
1459  template< typename MatrixType // Type of the sparse matrix
1460  , typename IteratorType > // Type of the sparse matrix iterator
1461  class RowElement
1462  {
1463  private:
1464  //*******************************************************************************************
1466 
1471  enum { returnConst = IsConst<MatrixType>::value };
1472  //*******************************************************************************************
1473 
1474  public:
1475  //**Type definitions*************************************************************************
1476  typedef typename SelectType< returnConst, const ElementType&, ElementType& >::Type ReferenceType;
1477  //*******************************************************************************************
1478 
1479  //**Constructor******************************************************************************
1485  inline RowElement( IteratorType pos, size_t column )
1486  : pos_ ( pos ) // Iterator to the current position within the sparse row
1487  , column_( column ) // Index of the according column
1488  {}
1489  //*******************************************************************************************
1490 
1491  //**Assignment operator**********************************************************************
1497  template< typename T > inline RowElement& operator=( const T& v ) {
1498  *pos_ = v;
1499  return *this;
1500  }
1501  //*******************************************************************************************
1502 
1503  //**Addition assignment operator*************************************************************
1509  template< typename T > inline RowElement& operator+=( const T& v ) {
1510  *pos_ += v;
1511  return *this;
1512  }
1513  //*******************************************************************************************
1514 
1515  //**Subtraction assignment operator**********************************************************
1521  template< typename T > inline RowElement& operator-=( const T& v ) {
1522  *pos_ -= v;
1523  return *this;
1524  }
1525  //*******************************************************************************************
1526 
1527  //**Multiplication assignment operator*******************************************************
1533  template< typename T > inline RowElement& operator*=( const T& v ) {
1534  *pos_ *= v;
1535  return *this;
1536  }
1537  //*******************************************************************************************
1538 
1539  //**Division assignment operator*************************************************************
1545  template< typename T > inline RowElement& operator/=( const T& v ) {
1546  *pos_ /= v;
1547  return *this;
1548  }
1549  //*******************************************************************************************
1550 
1551  //**Element access operator******************************************************************
1556  inline const RowElement* operator->() const {
1557  return this;
1558  }
1559  //*******************************************************************************************
1560 
1561  //**Value function***************************************************************************
1566  inline ReferenceType value() const {
1567  return pos_->value();
1568  }
1569  //*******************************************************************************************
1570 
1571  //**Index function***************************************************************************
1576  inline size_t index() const {
1577  return column_;
1578  }
1579  //*******************************************************************************************
1580 
1581  private:
1582  //**Member variables*************************************************************************
1583  IteratorType pos_;
1584  size_t column_;
1585  //*******************************************************************************************
1586  };
1587  //**********************************************************************************************
1588 
1589  //**RowIterator class definition****************************************************************
1592  template< typename MatrixType // Type of the sparse matrix
1593  , typename IteratorType > // Type of the sparse matrix iterator
1594  class RowIterator
1595  {
1596  private:
1597  //*******************************************************************************************
1599 
1604  enum { returnConst = IsConst<MatrixType>::value };
1605  //*******************************************************************************************
1606 
1607  public:
1608  //**Type definitions*************************************************************************
1609  typedef std::forward_iterator_tag IteratorCategory;
1610  typedef RowElement<MatrixType,IteratorType> ValueType;
1611  typedef ValueType PointerType;
1612  typedef ValueType ReferenceType;
1613  typedef ptrdiff_t DifferenceType;
1614 
1615  // STL iterator requirements
1616  typedef IteratorCategory iterator_category;
1617  typedef ValueType value_type;
1618  typedef PointerType pointer;
1619  typedef ReferenceType reference;
1620  typedef DifferenceType difference_type;
1621 
1623  typedef typename SelectType< returnConst, ReturnType, ElementType& >::Type Value;
1624  //*******************************************************************************************
1625 
1626  //**Constructor******************************************************************************
1633  inline RowIterator( MatrixType& matrix, size_t row, size_t column )
1634  : matrix_( matrix ) // The sparse matrix containing the row.
1635  , row_ ( row ) // The current row index.
1636  , column_( column ) // The current column index.
1637  , pos_ () // Iterator to the current sparse element.
1638  {
1639  for( ; column_<matrix_.columns(); ++column_ ) {
1640  pos_ = matrix_.find( row_, column_ );
1641  if( pos_ != matrix_.end( column_ ) ) break;
1642  }
1643  }
1644  //*******************************************************************************************
1645 
1646  //**Constructor******************************************************************************
1654  inline RowIterator( MatrixType& matrix, size_t row, size_t column, IteratorType pos )
1655  : matrix_( matrix ) // The sparse matrix containing the row.
1656  , row_ ( row ) // The current row index.
1657  , column_( column ) // The current column index.
1658  , pos_ ( pos ) // Iterator to the current sparse element.
1659  {
1660  BLAZE_INTERNAL_ASSERT( matrix.find( row, column ) == pos, "Invalid initial iterator position" );
1661  }
1662  //*******************************************************************************************
1663 
1664  //**Constructor******************************************************************************
1669  template< typename MatrixType2, typename IteratorType2 >
1670  inline RowIterator( const RowIterator<MatrixType2,IteratorType2>& it )
1671  : matrix_( it.matrix_ ) // The sparse matrix containing the row.
1672  , row_ ( it.row_ ) // The current row index.
1673  , column_( it.column_ ) // The current column index.
1674  , pos_ ( it.pos_ ) // Iterator to the current sparse element.
1675  {}
1676  //*******************************************************************************************
1677 
1678  //**Prefix increment operator****************************************************************
1683  inline RowIterator& operator++() {
1684  ++column_;
1685  for( ; column_<matrix_.columns(); ++column_ ) {
1686  pos_ = matrix_.find( row_, column_ );
1687  if( pos_ != matrix_.end( column_ ) ) break;
1688  }
1689 
1690  return *this;
1691  }
1692  //*******************************************************************************************
1693 
1694  //**Postfix increment operator***************************************************************
1699  inline const RowIterator operator++( int ) {
1700  const RowIterator tmp( *this );
1701  ++(*this);
1702  return tmp;
1703  }
1704  //*******************************************************************************************
1705 
1706  //**Element access operator******************************************************************
1711  inline ReferenceType operator*() const {
1712  return ReferenceType( pos_, column_ );
1713  }
1714  //*******************************************************************************************
1715 
1716  //**Element access operator******************************************************************
1721  inline PointerType operator->() const {
1722  return PointerType( pos_, column_ );
1723  }
1724  //*******************************************************************************************
1725 
1726  //**Equality operator************************************************************************
1732  template< typename MatrixType2, typename IteratorType2 >
1733  inline bool operator==( const RowIterator<MatrixType2,IteratorType2>& rhs ) const {
1734  return ( &matrix_ == &rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
1735  }
1736  //*******************************************************************************************
1737 
1738  //**Inequality operator**********************************************************************
1744  template< typename MatrixType2, typename IteratorType2 >
1745  inline bool operator!=( const RowIterator<MatrixType2,IteratorType2>& rhs ) const {
1746  return !( *this == rhs );
1747  }
1748  //*******************************************************************************************
1749 
1750  //**Subtraction operator*********************************************************************
1756  inline DifferenceType operator-( const RowIterator& rhs ) const {
1757  size_t counter( 0UL );
1758  for( size_t j=rhs.column_; j<column_; ++j ) {
1759  if( matrix_.find( row_, j ) != matrix_.end( j ) )
1760  ++counter;
1761  }
1762  return counter;
1763  }
1764  //*******************************************************************************************
1765 
1766  private:
1767  //**Member variables*************************************************************************
1768  MatrixType& matrix_;
1769  size_t row_;
1770  size_t column_;
1771  IteratorType pos_;
1772  //*******************************************************************************************
1773 
1774  //**Friend declarations**********************************************************************
1776  template< typename MatrixType2, typename IteratorType2 > friend class RowIterator;
1777  template< typename MT2, bool SO2 > friend class SparseRow;
1779  //*******************************************************************************************
1780  };
1781  //**********************************************************************************************
1782 
1783  //**Type definitions****************************************************************************
1785  typedef RowIterator<const MT,typename MT::ConstIterator> ConstIterator;
1786 
1788  typedef typename SelectType< useConst, ConstIterator, RowIterator<MT,typename MT::Iterator> >::Type Iterator;
1789  //**********************************************************************************************
1790 
1791  //**Constructors********************************************************************************
1794  explicit inline SparseRow( MT& matrix, size_t index );
1795  // No explicitly declared copy constructor.
1797  //**********************************************************************************************
1798 
1799  //**Destructor**********************************************************************************
1800  // No explicitly declared destructor.
1801  //**********************************************************************************************
1802 
1803  //**Data access functions***********************************************************************
1806  inline Reference operator[]( size_t index );
1807  inline ConstReference operator[]( size_t index ) const;
1808  inline Iterator begin ();
1809  inline ConstIterator begin () const;
1810  inline ConstIterator cbegin() const;
1811  inline Iterator end ();
1812  inline ConstIterator end () const;
1813  inline ConstIterator cend () const;
1815  //**********************************************************************************************
1816 
1817  //**Assignment operators************************************************************************
1820  inline SparseRow& operator= ( const SparseRow& rhs );
1821  template< typename VT > inline SparseRow& operator= ( const Vector<VT,true>& rhs );
1822  template< typename VT > inline SparseRow& operator+=( const Vector<VT,true>& rhs );
1823  template< typename VT > inline SparseRow& operator-=( const Vector<VT,true>& rhs );
1824  template< typename VT > inline SparseRow& operator*=( const Vector<VT,true>& rhs );
1825 
1826  template< typename Other >
1827  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
1828  operator*=( Other rhs );
1829 
1830  template< typename Other >
1831  inline typename EnableIf< IsNumeric<Other>, SparseRow >::Type&
1832  operator/=( Other rhs );
1834  //**********************************************************************************************
1835 
1836  //**Utility functions***************************************************************************
1839  inline size_t size() const;
1840  inline size_t capacity() const;
1841  inline size_t nonZeros() const;
1842  inline void reset();
1843  inline ElementType& insert ( size_t index, const ElementType& value );
1844  inline void erase ( size_t index );
1845  inline Iterator erase ( Iterator pos );
1846  inline Iterator find ( size_t index );
1847  inline ConstIterator find ( size_t index ) const;
1848  inline void reserve( size_t n );
1849  template< typename Other > inline SparseRow& scale ( Other scalar );
1851  //**********************************************************************************************
1852 
1853  //**Low-level utility functions*****************************************************************
1856  inline void append( size_t index, const ElementType& value, bool check=false );
1858  //**********************************************************************************************
1859 
1860  //**Expression template evaluation functions****************************************************
1863  template< typename Other > inline bool canAlias ( const Other* alias ) const;
1864  template< typename Other > inline bool isAliased( const Other* alias ) const;
1865  template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
1866  template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
1867  template< typename VT > inline void addAssign( const Vector<VT,true>& rhs );
1868  template< typename VT > inline void subAssign( const Vector<VT,true>& rhs );
1870  //**********************************************************************************************
1871 
1872  private:
1873  //**Member variables****************************************************************************
1876  MT& matrix_;
1877  const size_t row_;
1878 
1879  //**********************************************************************************************
1880 
1881  //**Compile time checks*************************************************************************
1887  //**********************************************************************************************
1888 };
1890 //*************************************************************************************************
1891 
1892 
1893 
1894 
1895 //=================================================================================================
1896 //
1897 // CONSTRUCTOR
1898 //
1899 //=================================================================================================
1900 
1901 //*************************************************************************************************
1909 template< typename MT > // Type of the sparse matrix
1910 inline SparseRow<MT,false>::SparseRow( MT& matrix, size_t index )
1911  : matrix_( matrix ) // The sparse matrix containing the row
1912  , row_ ( index ) // The index of the row in the matrix
1913 {
1914  if( matrix_.rows() <= index )
1915  throw std::invalid_argument( "Invalid row access index" );
1916 }
1918 //*************************************************************************************************
1919 
1920 
1921 
1922 
1923 //=================================================================================================
1924 //
1925 // DATA ACCESS FUNCTIONS
1926 //
1927 //=================================================================================================
1928 
1929 //*************************************************************************************************
1936 template< typename MT > // Type of the sparse matrix
1937 inline typename SparseRow<MT,false>::Reference SparseRow<MT,false>::operator[]( size_t index )
1938 {
1939  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
1940  return matrix_(row_,index);
1941 }
1943 //*************************************************************************************************
1944 
1945 
1946 //*************************************************************************************************
1953 template< typename MT > // Type of the sparse matrix
1954 inline typename SparseRow<MT,false>::ConstReference SparseRow<MT,false>::operator[]( size_t index ) const
1955 {
1956  BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
1957  return const_cast<const MT&>( matrix_ )(row_,index);
1958 }
1960 //*************************************************************************************************
1961 
1962 
1963 //*************************************************************************************************
1971 template< typename MT > // Type of the sparse matrix
1972 inline typename SparseRow<MT,false>::Iterator SparseRow<MT,false>::begin()
1973 {
1974  return Iterator( matrix_, row_, 0UL );
1975 }
1977 //*************************************************************************************************
1978 
1979 
1980 //*************************************************************************************************
1988 template< typename MT > // Type of the sparse matrix
1989 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::begin() const
1990 {
1991  return ConstIterator( matrix_, row_, 0UL );
1992 }
1994 //*************************************************************************************************
1995 
1996 
1997 //*************************************************************************************************
2005 template< typename MT > // Type of the sparse matrix
2006 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::cbegin() const
2007 {
2008  return ConstIterator( matrix_, row_, 0UL );
2009 }
2011 //*************************************************************************************************
2012 
2013 
2014 //*************************************************************************************************
2022 template< typename MT > // Type of the sparse matrix
2023 inline typename SparseRow<MT,false>::Iterator SparseRow<MT,false>::end()
2024 {
2025  return Iterator( matrix_, row_, size() );
2026 }
2028 //*************************************************************************************************
2029 
2030 
2031 //*************************************************************************************************
2039 template< typename MT > // Type of the sparse matrix
2040 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::end() const
2041 {
2042  return ConstIterator( matrix_, row_, size() );
2043 }
2045 //*************************************************************************************************
2046 
2047 
2048 //*************************************************************************************************
2056 template< typename MT > // Type of the sparse matrix
2057 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::cend() const
2058 {
2059  return ConstIterator( matrix_, row_, size() );
2060 }
2062 //*************************************************************************************************
2063 
2064 
2065 
2066 
2067 //=================================================================================================
2068 //
2069 // ASSIGNMENT OPERATORS
2070 //
2071 //=================================================================================================
2072 
2073 //*************************************************************************************************
2084 template< typename MT > // Type of the sparse matrix
2085 inline SparseRow<MT,false>& SparseRow<MT,false>::operator=( const SparseRow& rhs )
2086 {
2087  using blaze::assign;
2088 
2089  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && row_ == rhs.row_ ) )
2090  return *this;
2091 
2092  if( size() != rhs.size() )
2093  throw std::invalid_argument( "Row sizes do not match" );
2094 
2095  if( rhs.canAlias( &matrix_ ) ) {
2096  const ResultType tmp( rhs );
2097  assign( *this, tmp );
2098  }
2099  else {
2100  assign( *this, rhs );
2101  }
2102 
2103  return *this;
2104 }
2106 //*************************************************************************************************
2107 
2108 
2109 //*************************************************************************************************
2120 template< typename MT > // Type of the sparse matrix
2121 template< typename VT > // Type of the right-hand side vector
2122 inline SparseRow<MT,false>& SparseRow<MT,false>::operator=( const Vector<VT,true>& rhs )
2123 {
2124  using blaze::assign;
2125 
2126  if( size() != (~rhs).size() )
2127  throw std::invalid_argument( "Vector sizes do not match" );
2128 
2129  const typename VT::CompositeType tmp( ~rhs );
2130  assign( *this, tmp );
2131 
2132  return *this;
2133 }
2135 //*************************************************************************************************
2136 
2137 
2138 //*************************************************************************************************
2149 template< typename MT > // Type of the sparse matrix
2150 template< typename VT > // Type of the right-hand side vector
2151 inline SparseRow<MT,false>& SparseRow<MT,false>::operator+=( const Vector<VT,true>& rhs )
2152 {
2153  using blaze::addAssign;
2154 
2155  if( (~rhs).size() != size() )
2156  throw std::invalid_argument( "Vector sizes do not match" );
2157 
2158  addAssign( *this, ~rhs );
2159 
2160  return *this;
2161 }
2163 //*************************************************************************************************
2164 
2165 
2166 //*************************************************************************************************
2177 template< typename MT > // Type of the sparse matrix
2178 template< typename VT > // Type of the right-hand side vector
2179 inline SparseRow<MT,false>& SparseRow<MT,false>::operator-=( const Vector<VT,true>& rhs )
2180 {
2181  using blaze::subAssign;
2182 
2183  if( (~rhs).size() != size() )
2184  throw std::invalid_argument( "Vector sizes do not match" );
2185 
2186  subAssign( *this, ~rhs );
2187 
2188  return *this;
2189 }
2191 //*************************************************************************************************
2192 
2193 
2194 //*************************************************************************************************
2206 template< typename MT > // Type of the sparse matrix
2207 template< typename VT > // Type of the right-hand side vector
2208 inline SparseRow<MT,false>& SparseRow<MT,false>::operator*=( const Vector<VT,true>& rhs )
2209 {
2210  if( (~rhs).size() != size() )
2211  throw std::invalid_argument( "Vector sizes do not match" );
2212 
2213  typedef typename MultTrait<This,typename VT::ResultType>::Type MultType;
2214 
2217 
2218  const MultType tmp( *this * (~rhs) );
2219  assign( tmp );
2220 
2221  return *this;
2222 }
2224 //*************************************************************************************************
2225 
2226 
2227 //*************************************************************************************************
2239 template< typename MT > // Type of the sparse matrix
2240 template< typename Other > // Data type of the right-hand side scalar
2241 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,false> >::Type&
2242  SparseRow<MT,false>::operator*=( Other rhs )
2243 {
2244  for( Iterator element=begin(); element!=end(); ++element )
2245  element->value() *= rhs;
2246  return *this;
2247 }
2249 //*************************************************************************************************
2250 
2251 
2252 //*************************************************************************************************
2265 template< typename MT > // Type of the sparse matrix
2266 template< typename Other > // Data type of the right-hand side scalar
2267 inline typename EnableIf< IsNumeric<Other>, SparseRow<MT,false> >::Type&
2268  SparseRow<MT,false>::operator/=( Other rhs )
2269 {
2270  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
2271 
2272  typedef typename DivTrait<ElementType,Other>::Type DT;
2273  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
2274 
2275  // Depending on the two involved data types, an integer division is applied or a
2276  // floating point division is selected.
2277  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
2278  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
2279  for( Iterator element=begin(); element!=end(); ++element )
2280  element->value() *= tmp;
2281  }
2282  else {
2283  for( Iterator element=begin(); element!=end(); ++element )
2284  element->value() /= rhs;
2285  }
2286 
2287  return *this;
2288 }
2290 //*************************************************************************************************
2291 
2292 
2293 
2294 
2295 //=================================================================================================
2296 //
2297 // UTILITY FUNCTIONS
2298 //
2299 //=================================================================================================
2300 
2301 //*************************************************************************************************
2307 template< typename MT > // Type of the sparse matrix
2308 inline size_t SparseRow<MT,false>::size() const
2309 {
2310  return matrix_.columns();
2311 }
2313 //*************************************************************************************************
2314 
2315 
2316 //*************************************************************************************************
2322 template< typename MT > // Type of the sparse matrix
2323 inline size_t SparseRow<MT,false>::capacity() const
2324 {
2325  return matrix_.columns();
2326 }
2328 //*************************************************************************************************
2329 
2330 
2331 //*************************************************************************************************
2340 template< typename MT > // Type of the sparse matrix
2341 inline size_t SparseRow<MT,false>::nonZeros() const
2342 {
2343  size_t counter( 0UL );
2344  for( ConstIterator element=begin(); element!=end(); ++element ) {
2345  ++counter;
2346  }
2347  return counter;
2348 }
2350 //*************************************************************************************************
2351 
2352 
2353 //*************************************************************************************************
2359 template< typename MT > // Type of the sparse matrix
2360 inline void SparseRow<MT,false>::reset()
2361 {
2362  for( size_t j=0UL; j<size(); ++j ) {
2363  matrix_.erase( row_, j );
2364  }
2365 }
2367 //*************************************************************************************************
2368 
2369 
2370 //*************************************************************************************************
2383 template< typename MT > // Type of the sparse matrix
2384 inline typename SparseRow<MT,false>::ElementType&
2385  SparseRow<MT,false>::insert( size_t index, const ElementType& value )
2386 {
2387  return matrix_.insert( row_, index, value )->value();
2388 }
2390 //*************************************************************************************************
2391 
2392 
2393 //*************************************************************************************************
2402 template< typename MT > // Type of the sparse matrix
2403 inline void SparseRow<MT,false>::erase( size_t index )
2404 {
2405  matrix_.erase( row_, index );
2406 }
2408 //*************************************************************************************************
2409 
2410 
2411 //*************************************************************************************************
2420 template< typename MT > // Type of the sparse matrix
2421 inline typename SparseRow<MT,false>::Iterator SparseRow<MT,false>::erase( Iterator pos )
2422 {
2423  const size_t column( pos.column_ );
2424 
2425  if( column == size() )
2426  return pos;
2427 
2428  matrix_.erase( column, pos.pos_ );
2429  return Iterator( matrix_, row_, column+1UL );
2430 }
2432 //*************************************************************************************************
2433 
2434 
2435 //*************************************************************************************************
2449 template< typename MT > // Type of the sparse matrix
2450 inline typename SparseRow<MT,false>::Iterator SparseRow<MT,false>::find( size_t index )
2451 {
2452  const typename MT::Iterator pos( matrix_.find( row_, index ) );
2453 
2454  if( pos != matrix_.end( index ) )
2455  return Iterator( matrix_, row_, index, pos );
2456  else
2457  return end();
2458 }
2460 //*************************************************************************************************
2461 
2462 
2463 //*************************************************************************************************
2477 template< typename MT > // Type of the sparse matrix
2478 inline typename SparseRow<MT,false>::ConstIterator SparseRow<MT,false>::find( size_t index ) const
2479 {
2480  const typename MT::ConstIterator pos( matrix_.find( row_, index ) );
2481 
2482  if( pos != matrix_.end( index ) )
2483  return ConstIterator( matrix_, row_, index, pos );
2484  else
2485  return end();
2486 }
2488 //*************************************************************************************************
2489 
2490 
2491 //*************************************************************************************************
2501 template< typename MT > // Type of the sparse matrix
2502 void SparseRow<MT,false>::reserve( size_t n )
2503 {
2504  return;
2505 }
2507 //*************************************************************************************************
2508 
2509 
2510 //*************************************************************************************************
2517 template< typename MT > // Type of the sparse matrix
2518 template< typename Other > // Data type of the scalar value
2519 inline SparseRow<MT,false>& SparseRow<MT,false>::scale( Other scalar )
2520 {
2521  for( Iterator element=begin(); element!=end(); ++element )
2522  element->value() *= scalar;
2523  return *this;
2524 }
2526 //*************************************************************************************************
2527 
2528 
2529 
2530 
2531 //=================================================================================================
2532 //
2533 // LOW-LEVEL UTILITY FUNCTIONS
2534 //
2535 //=================================================================================================
2536 
2537 //*************************************************************************************************
2562 template< typename MT > // Type of the sparse matrix
2563 inline void SparseRow<MT,false>::append( size_t index, const ElementType& value, bool /*check*/ )
2564 {
2565  matrix_.insert( row_, index, value );
2566 }
2568 //*************************************************************************************************
2569 
2570 
2571 
2572 
2573 //=================================================================================================
2574 //
2575 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
2576 //
2577 //=================================================================================================
2578 
2579 //*************************************************************************************************
2590 template< typename MT > // Type of the sparse matrix
2591 template< typename Other > // Data type of the foreign expression
2592 inline bool SparseRow<MT,false>::canAlias( const Other* alias ) const
2593 {
2594  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
2595 }
2597 //*************************************************************************************************
2598 
2599 
2600 //*************************************************************************************************
2607 template< typename MT > // Type of the sparse matrix
2608 template< typename Other > // Data type of the foreign expression
2609 inline bool SparseRow<MT,false>::isAliased( const Other* alias ) const
2610 {
2611  return static_cast<const void*>( &matrix_ ) == static_cast<const void*>( alias );
2612 }
2614 //*************************************************************************************************
2615 
2616 
2617 //*************************************************************************************************
2629 template< typename MT > // Type of the sparse matrix
2630 template< typename VT > // Type of the right-hand side dense vector
2631 inline void SparseRow<MT,false>::assign( const DenseVector<VT,true>& rhs )
2632 {
2633  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2634 
2635  for( size_t j=0UL; j<(~rhs).size(); ++j ) {
2636  matrix_(row_,j) = (~rhs)[j];
2637  }
2638 }
2640 //*************************************************************************************************
2641 
2642 
2643 //*************************************************************************************************
2655 template< typename MT > // Type of the sparse matrix
2656 template< typename VT > // Type of the right-hand side sparse vector
2657 inline void SparseRow<MT,false>::assign( const SparseVector<VT,true>& rhs )
2658 {
2659  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2660 
2661  size_t j( 0UL );
2662 
2663  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2664  for( ; j<element->index(); ++j )
2665  matrix_.erase( row_, j );
2666  matrix_(row_,j++) = element->value();
2667  }
2668  for( ; j<size(); ++j ) {
2669  matrix_.erase( row_, j );
2670  }
2671 }
2673 //*************************************************************************************************
2674 
2675 
2676 //*************************************************************************************************
2688 template< typename MT > // Type of the sparse matrix
2689 template< typename VT > // Type of the right-hand side vector
2690 inline void SparseRow<MT,false>::addAssign( const Vector<VT,true>& rhs )
2691 {
2692  typedef typename AddTrait<This,typename VT::ResultType>::Type AddType;
2693 
2696 
2697  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2698 
2699  const AddType tmp( *this + (~rhs) );
2700  assign( tmp );
2701 }
2703 //*************************************************************************************************
2704 
2705 
2706 //*************************************************************************************************
2718 template< typename MT > // Type of the sparse matrix
2719 template< typename VT > // Type of the right-hand side vector
2720 inline void SparseRow<MT,false>::subAssign( const Vector<VT,true>& rhs )
2721 {
2722  typedef typename SubTrait<This,typename VT::ResultType>::Type SubType;
2723 
2726 
2727  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2728 
2729  const SubType tmp( *this - (~rhs) );
2730  assign( tmp );
2731 }
2733 //*************************************************************************************************
2734 
2735 
2736 
2737 
2738 
2739 
2740 
2741 
2742 //=================================================================================================
2743 //
2744 // SPARSEROW OPERATORS
2745 //
2746 //=================================================================================================
2747 
2748 //*************************************************************************************************
2751 template< typename MT, bool SO >
2752 inline void reset( SparseRow<MT,SO>& row );
2753 
2754 template< typename MT, bool SO >
2755 inline void clear( SparseRow<MT,SO>& row );
2756 
2757 template< typename MT, bool SO >
2758 inline bool isnan( const SparseRow<MT,SO>& row );
2759 
2760 template< typename MT, bool SO >
2761 inline bool isDefault( const SparseRow<MT,SO>& row );
2763 //*************************************************************************************************
2764 
2765 
2766 //*************************************************************************************************
2773 template< typename MT // Type of the sparse matrix
2774  , bool SO > // Storage order
2775 inline void reset( SparseRow<MT,SO>& row )
2776 {
2777  row.reset();
2778 }
2779 //*************************************************************************************************
2780 
2781 
2782 //*************************************************************************************************
2789 template< typename MT // Type of the sparse matrix
2790  , bool SO > // Storage order
2791 inline void clear( SparseRow<MT,SO>& row )
2792 {
2793  row.reset();
2794 }
2795 //*************************************************************************************************
2796 
2797 
2798 //*************************************************************************************************
2814 template< typename MT // Type of the sparse matrix
2815  , bool SO > // Storage order
2816 inline bool isnan( const SparseRow<MT,SO>& row )
2817 {
2818  typedef typename SparseRow<MT,SO>::ConstIterator ConstIterator;
2819 
2820  const ConstIterator end( row.end() );
2821  for( ConstIterator element=row.begin(); element!=end; ++element ) {
2822  if( isnan( element->value() ) ) return true;
2823  }
2824  return false;
2825 }
2826 //*************************************************************************************************
2827 
2828 
2829 //*************************************************************************************************
2847 template< typename MT // Type of the sparse matrix
2848  , bool SO > // Storage order
2849 inline bool isDefault( const SparseRow<MT,SO>& row )
2850 {
2851  typedef typename SparseRow<MT,SO>::ConstIterator ConstIterator;
2852 
2853  const ConstIterator end( row.end() );
2854  for( ConstIterator element=row.begin(); element!=end; ++element )
2855  if( !isDefault( element->value() ) ) return false;
2856  return true;
2857 }
2858 //*************************************************************************************************
2859 
2860 
2861 
2862 
2863 //=================================================================================================
2864 //
2865 // GLOBAL OPERATORS
2866 //
2867 //=================================================================================================
2868 
2869 //*************************************************************************************************
2888 template< typename MT // Type of the sparse matrix
2889  , bool SO > // Storage order
2890 inline SparseRow<MT> row( SparseMatrix<MT,SO>& sm, size_t index )
2891 {
2893 
2894  return SparseRow<MT>( ~sm, index );
2895 }
2896 //*************************************************************************************************
2897 
2898 
2899 //*************************************************************************************************
2918 template< typename MT // Type of the sparse matrix
2919  , bool SO > // Storage order
2920 inline SparseRow<const MT> row( const SparseMatrix<MT,SO>& sm, size_t index )
2921 {
2923 
2924  return SparseRow<const MT>( ~sm, index );
2925 }
2926 //*************************************************************************************************
2927 
2928 
2929 
2930 
2931 //=================================================================================================
2932 //
2933 // ADDTRAIT SPECIALIZATIONS
2934 //
2935 //=================================================================================================
2936 
2937 //*************************************************************************************************
2939 template< typename T1, bool SO, typename T2, size_t N >
2940 struct AddTrait< SparseRow<T1,SO>, StaticVector<T2,N,true> >
2941 {
2942  typedef typename AddTrait< typename SparseRow<T1,SO>::ResultType,
2943  StaticVector<T2,N,true> >::Type Type;
2944 };
2945 
2946 template< typename T1, size_t N, typename T2, bool SO >
2947 struct AddTrait< StaticVector<T1,N,true>, SparseRow<T2,SO> >
2948 {
2949  typedef typename AddTrait< StaticVector<T1,N,true>,
2950  typename SparseRow<T2,SO>::ResultType >::Type Type;
2951 };
2952 
2953 template< typename T1, bool SO, typename T2 >
2954 struct AddTrait< SparseRow<T1,SO>, DynamicVector<T2,true> >
2955 {
2956  typedef typename AddTrait< typename SparseRow<T1,SO>::ResultType,
2957  DynamicVector<T2,true> >::Type Type;
2958 };
2959 
2960 template< typename T1, typename T2, bool SO >
2961 struct AddTrait< DynamicVector<T1,true>, SparseRow<T2,SO> >
2962 {
2963  typedef typename AddTrait< DynamicVector<T1,true>,
2964  typename SparseRow<T2,SO>::ResultType >::Type Type;
2965 };
2966 
2967 template< typename T1, bool SO1, typename T2, bool SO2 >
2968 struct AddTrait< SparseRow<T1,SO1>, DenseRow<T2,SO2> >
2969 {
2970  typedef typename AddTrait< typename SparseRow<T1,SO1>::ResultType,
2971  typename DenseRow <T2,SO2>::ResultType >::Type Type;
2972 };
2973 
2974 template< typename T1, bool SO1, typename T2, bool SO2 >
2975 struct AddTrait< DenseRow<T1,SO1>, SparseRow<T2,SO2> >
2976 {
2977  typedef typename AddTrait< typename DenseRow <T1,SO1>::ResultType,
2978  typename SparseRow<T2,SO2>::ResultType >::Type Type;
2979 };
2980 
2981 template< typename T1, bool SO, typename T2 >
2982 struct AddTrait< SparseRow<T1,SO>, CompressedVector<T2,true> >
2983 {
2984  typedef typename AddTrait< typename SparseRow<T1,SO>::ResultType,
2985  CompressedVector<T2,true> >::Type Type;
2986 };
2987 
2988 template< typename T1, typename T2, bool SO >
2989 struct AddTrait< CompressedVector<T1,true>, SparseRow<T2,SO> >
2990 {
2991  typedef typename AddTrait< CompressedVector<T1,true>,
2992  typename SparseRow<T2,SO>::ResultType >::Type Type;
2993 };
2994 
2995 template< typename T1, bool SO1, typename T2, bool SO2 >
2996 struct AddTrait< SparseRow<T1,SO1>, SparseRow<T2,SO2> >
2997 {
2998  typedef typename AddTrait< typename SparseRow<T1,SO1>::ResultType,
2999  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3000 };
3002 //*************************************************************************************************
3003 
3004 
3005 
3006 
3007 //=================================================================================================
3008 //
3009 // SUBTRAIT SPECIALIZATIONS
3010 //
3011 //=================================================================================================
3012 
3013 //*************************************************************************************************
3015 template< typename T1, bool SO, typename T2, size_t N >
3016 struct SubTrait< SparseRow<T1,SO>, StaticVector<T2,N,true> >
3017 {
3018  typedef typename SubTrait< typename SparseRow<T1,SO>::ResultType,
3019  StaticVector<T2,N,true> >::Type Type;
3020 };
3021 
3022 template< typename T1, size_t N, typename T2, bool SO >
3023 struct SubTrait< StaticVector<T1,N,true>, SparseRow<T2,SO> >
3024 {
3025  typedef typename SubTrait< StaticVector<T1,N,true>,
3026  typename SparseRow<T2,SO>::ResultType >::Type Type;
3027 };
3028 
3029 template< typename T1, bool SO, typename T2 >
3030 struct SubTrait< SparseRow<T1,SO>, DynamicVector<T2,true> >
3031 {
3032  typedef typename SubTrait< typename SparseRow<T1,SO>::ResultType,
3033  DynamicVector<T2,true> >::Type Type;
3034 };
3035 
3036 template< typename T1, typename T2, bool SO >
3037 struct SubTrait< DynamicVector<T1,true>, SparseRow<T2,SO> >
3038 {
3039  typedef typename SubTrait< DynamicVector<T1,true>,
3040  typename SparseRow<T2,SO>::ResultType >::Type Type;
3041 };
3042 
3043 template< typename T1, bool SO1, typename T2, bool SO2 >
3044 struct SubTrait< SparseRow<T1,SO1>, DenseRow<T2,SO2> >
3045 {
3046  typedef typename SubTrait< typename SparseRow<T1,SO1>::ResultType,
3047  typename DenseRow <T2,SO2>::ResultType >::Type Type;
3048 };
3049 
3050 template< typename T1, bool SO1, typename T2, bool SO2 >
3051 struct SubTrait< DenseRow<T1,SO1>, SparseRow<T2,SO2> >
3052 {
3053  typedef typename SubTrait< typename DenseRow <T1,SO1>::ResultType,
3054  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3055 };
3056 
3057 template< typename T1, bool SO, typename T2 >
3058 struct SubTrait< SparseRow<T1,SO>, CompressedVector<T2,true> >
3059 {
3060  typedef typename SubTrait< typename SparseRow<T1,SO>::ResultType,
3061  CompressedVector<T2,true> >::Type Type;
3062 };
3063 
3064 template< typename T1, typename T2, bool SO >
3065 struct SubTrait< CompressedVector<T1,true>, SparseRow<T2,SO> >
3066 {
3067  typedef typename SubTrait< CompressedVector<T1,true>,
3068  typename SparseRow<T2,SO>::ResultType >::Type Type;
3069 };
3070 
3071 template< typename T1, bool SO1, typename T2, bool SO2 >
3072 struct SubTrait< SparseRow<T1,SO1>, SparseRow<T2,SO2> >
3073 {
3074  typedef typename SubTrait< typename SparseRow<T1,SO1>::ResultType,
3075  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3076 };
3078 //*************************************************************************************************
3079 
3080 
3081 
3082 
3083 //=================================================================================================
3084 //
3085 // MULTTRAIT SPECIALIZATIONS
3086 //
3087 //=================================================================================================
3088 
3089 //*************************************************************************************************
3091 template< typename T1, bool SO, typename T2 >
3092 struct MultTrait< SparseRow<T1,SO>, T2 >
3093 {
3094  typedef typename MultTrait< typename SparseRow<T1,SO>::ResultType, T2 >::Type Type;
3096 };
3097 
3098 template< typename T1, typename T2, bool SO >
3099 struct MultTrait< T1, SparseRow<T2,SO> >
3100 {
3101  typedef typename MultTrait< T1, typename SparseRow<T2,SO>::ResultType >::Type Type;
3103 };
3104 
3105 template< typename T1, bool SO, typename T2, size_t N, bool TF >
3106 struct MultTrait< SparseRow<T1,SO>, StaticVector<T2,N,TF> >
3107 {
3108  typedef typename MultTrait< typename SparseRow<T1,SO>::ResultType,
3109  StaticVector<T2,N,TF> >::Type Type;
3110 };
3111 
3112 template< typename T1, size_t N, bool TF, typename T2, bool SO >
3113 struct MultTrait< StaticVector<T1,N,TF>, SparseRow<T2,SO> >
3114 {
3115  typedef typename MultTrait< StaticVector<T1,N,TF>,
3116  typename SparseRow<T2,SO>::ResultType >::Type Type;
3117 };
3118 
3119 template< typename T1, bool SO, typename T2, bool TF >
3120 struct MultTrait< SparseRow<T1,SO>, DynamicVector<T2,TF> >
3121 {
3122  typedef typename MultTrait< typename SparseRow<T1,SO>::ResultType,
3123  DynamicVector<T2,TF> >::Type Type;
3124 };
3125 
3126 template< typename T1, bool TF, typename T2, bool SO >
3127 struct MultTrait< DynamicVector<T1,TF>, SparseRow<T2,SO> >
3128 {
3129  typedef typename MultTrait< DynamicVector<T1,TF>,
3130  typename SparseRow<T2,SO>::ResultType >::Type Type;
3131 };
3132 
3133 template< typename T1, bool SO1, typename T2, bool SO2 >
3134 struct MultTrait< SparseRow<T1,SO1>, DenseRow<T2,SO2> >
3135 {
3136  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3137  typename DenseRow <T2,SO2>::ResultType >::Type Type;
3138 };
3139 
3140 template< typename T1, bool SO1, typename T2, bool SO2 >
3141 struct MultTrait< DenseRow<T1,SO1>, SparseRow<T2,SO2> >
3142 {
3143  typedef typename MultTrait< typename DenseRow <T1,SO1>::ResultType,
3144  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3145 };
3146 
3147 template< typename T1, bool SO, typename T2, bool TF >
3148 struct MultTrait< SparseRow<T1,SO>, CompressedVector<T2,TF> >
3149 {
3150  typedef typename MultTrait< typename SparseRow<T1,SO>::ResultType,
3151  CompressedVector<T2,TF> >::Type Type;
3152 };
3153 
3154 template< typename T1, bool TF, typename T2, bool SO >
3155 struct MultTrait< CompressedVector<T1,TF>, SparseRow<T2,SO> >
3156 {
3157  typedef typename MultTrait< CompressedVector<T1,TF>,
3158  typename SparseRow<T2,SO>::ResultType >::Type Type;
3159 };
3160 
3161 template< typename T1, bool SO1, typename T2, bool SO2 >
3162 struct MultTrait< SparseRow<T1,SO1>, SparseRow<T2,SO2> >
3163 {
3164  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3165  typename SparseRow<T2,SO2>::ResultType >::Type Type;
3166 };
3167 
3168 template< typename T1, bool SO1, typename T2, size_t M, size_t N, bool SO2 >
3169 struct MultTrait< SparseRow<T1,SO1>, StaticMatrix<T2,M,N,SO2> >
3170 {
3171  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3172  StaticMatrix<T2,M,N,SO2> >::Type Type;
3173 };
3174 
3175 template< typename T1, bool SO1, typename T2, bool SO2 >
3176 struct MultTrait< SparseRow<T1,SO1>, DynamicMatrix<T2,SO2> >
3177 {
3178  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3179  DynamicMatrix<T2,SO2> >::Type Type;
3180 };
3181 
3182 template< typename T1, bool SO1, typename T2, bool SO2 >
3183 struct MultTrait< SparseRow<T1,SO1>, CompressedMatrix<T2,SO2> >
3184 {
3185  typedef typename MultTrait< typename SparseRow<T1,SO1>::ResultType,
3186  CompressedMatrix<T2,SO2> >::Type Type;
3187 };
3189 //*************************************************************************************************
3190 
3191 
3192 
3193 
3194 //=================================================================================================
3195 //
3196 // DIVTRAIT SPECIALIZATIONS
3197 //
3198 //=================================================================================================
3199 
3200 //*************************************************************************************************
3202 template< typename T1, bool SO, typename T2 >
3203 struct DivTrait< SparseRow<T1,SO>, T2 >
3204 {
3205  typedef typename DivTrait< typename SparseRow<T1,SO>::ResultType, T2 >::Type Type;
3207 };
3209 //*************************************************************************************************
3210 
3211 } // namespace blaze
3212 
3213 #endif