SparseColumn.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_SPARSECOLUMN_H_
36 #define _BLAZE_MATH_VIEWS_SPARSECOLUMN_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <stdexcept>
58 #include <blaze/math/Functions.h>
60 #include <blaze/math/shims/IsOne.h>
61 #include <blaze/math/shims/Reset.h>
85 #include <blaze/util/Assert.h>
88 #include <blaze/util/DisableIf.h>
89 #include <blaze/util/EnableIf.h>
91 #include <blaze/util/mpl/And.h>
92 #include <blaze/util/mpl/If.h>
93 #include <blaze/util/mpl/Or.h>
94 #include <blaze/util/Null.h>
96 #include <blaze/util/Types.h>
102 #include <blaze/util/Unused.h>
103 
104 
105 namespace blaze {
106 
107 //=================================================================================================
108 //
109 // CLASS DEFINITION
110 //
111 //=================================================================================================
112 
113 //*************************************************************************************************
371 template< typename MT // Type of the sparse matrix
372  , bool SO = IsColumnMajorMatrix<MT>::value // Storage order
373  , bool SF = IsSymmetric<MT>::value > // Symmetry flag
374 class SparseColumn : public SparseVector< SparseColumn<MT,SO,SF>, false >
375  , private Column
376 {
377  private:
378  //**Type definitions****************************************************************************
380  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
381  //**********************************************************************************************
382 
383  //**********************************************************************************************
385 
391  enum { useConst = IsConst<MT>::value };
392  //**********************************************************************************************
393 
394  public:
395  //**Type definitions****************************************************************************
399  typedef typename MT::ElementType ElementType;
400  typedef typename MT::ReturnType ReturnType;
401  typedef const SparseColumn& CompositeType;
402 
405 
408 
411 
414  //**********************************************************************************************
415 
416  //**Compilation flags***************************************************************************
418  enum { smpAssignable = 0 };
419  //**********************************************************************************************
420 
421  //**Constructors********************************************************************************
424  explicit inline SparseColumn( MT& matrix, size_t index );
425  // No explicitly declared copy constructor.
427  //**********************************************************************************************
428 
429  //**Destructor**********************************************************************************
430  // No explicitly declared destructor.
431  //**********************************************************************************************
432 
433  //**Data access functions***********************************************************************
436  inline Reference operator[]( size_t index );
437  inline ConstReference operator[]( size_t index ) const;
438  inline Iterator begin ();
439  inline ConstIterator begin () const;
440  inline ConstIterator cbegin() const;
441  inline Iterator end ();
442  inline ConstIterator end () const;
443  inline ConstIterator cend () const;
445  //**********************************************************************************************
446 
447  //**Assignment operators************************************************************************
450  inline SparseColumn& operator=( const SparseColumn& rhs );
451 
452  template< typename VT > inline SparseColumn& operator= ( const DenseVector<VT,false>& rhs );
453  template< typename VT > inline SparseColumn& operator= ( const SparseVector<VT,false>& rhs );
454  template< typename VT > inline SparseColumn& operator+=( const DenseVector<VT,false>& rhs );
455  template< typename VT > inline SparseColumn& operator+=( const SparseVector<VT,false>& rhs );
456  template< typename VT > inline SparseColumn& operator-=( const DenseVector<VT,false>& rhs );
457  template< typename VT > inline SparseColumn& operator-=( const SparseVector<VT,false>& rhs );
458  template< typename VT > inline SparseColumn& operator*=( const Vector<VT,false>& rhs );
459 
460  template< typename Other >
461  inline typename EnableIf< IsNumeric<Other>, SparseColumn >::Type&
462  operator*=( Other rhs );
463 
464  template< typename Other >
465  inline typename EnableIf< IsNumeric<Other>, SparseColumn >::Type&
466  operator/=( Other rhs );
468  //**********************************************************************************************
469 
470  //**Utility functions***************************************************************************
473  inline size_t size() const;
474  inline size_t capacity() const;
475  inline size_t nonZeros() const;
476  inline void reset();
477  inline Iterator set ( size_t index, const ElementType& value );
478  inline Iterator insert ( size_t index, const ElementType& value );
479  inline void erase ( size_t index );
480  inline Iterator erase ( Iterator pos );
481  inline Iterator erase ( Iterator first, Iterator last );
482  inline void reserve( size_t n );
483  template< typename Other > inline SparseColumn& scale ( const Other& scalar );
485  //**********************************************************************************************
486 
487  //**Lookup functions****************************************************************************
490  inline Iterator find ( size_t index );
491  inline ConstIterator find ( size_t index ) const;
492  inline Iterator lowerBound( size_t index );
493  inline ConstIterator lowerBound( size_t index ) const;
494  inline Iterator upperBound( size_t index );
495  inline ConstIterator upperBound( size_t index ) const;
497  //**********************************************************************************************
498 
499  //**Low-level utility functions*****************************************************************
502  inline void append( size_t index, const ElementType& value, bool check=false );
504  //**********************************************************************************************
505 
506  //**Expression template evaluation functions****************************************************
509  template< typename Other > inline bool canAlias ( const Other* alias ) const;
510  template< typename Other > inline bool isAliased( const Other* alias ) const;
511 
512  template< typename VT > inline void assign ( const DenseVector <VT,false>& rhs );
513  template< typename VT > inline void assign ( const SparseVector<VT,false>& rhs );
514  template< typename VT > inline void addAssign( const DenseVector <VT,false>& rhs );
515  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
516  template< typename VT > inline void subAssign( const DenseVector <VT,false>& rhs );
517  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
519  //**********************************************************************************************
520 
521  private:
522  //**Utility functions***************************************************************************
525  inline size_t extendCapacity() const;
526 
527  template< typename MT2, bool SO2, typename VT >
528  inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
529  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,false>& rhs );
530 
531  template< typename MT2, bool SO2, typename VT >
532  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
533  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs );
534 
535  template< typename MT2, bool SO2, typename VT >
536  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
537  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs );
538 
539  template< typename MT2, bool SO2, typename VT >
540  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
541  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs );
542 
543  template< typename MT2, bool SO2, typename VT >
544  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
545  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs );
546 
547  template< typename MT2, bool SO2, typename VT >
548  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
549  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs );
550 
551  template< typename MT2, bool SO2, typename VT >
552  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
553  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs );
555  //**********************************************************************************************
556 
557  //**Member variables****************************************************************************
560  Operand matrix_;
561  const size_t col_;
562 
563  //**********************************************************************************************
564 
565  //**Friend declarations*************************************************************************
567  template< typename MT2, bool SO2, bool SF2 >
568  friend bool isSame( const SparseColumn<MT2,SO2,SF2>& a, const SparseColumn<MT2,SO2,SF2>& b );
569 
570  template< typename MT2, bool SO2, bool SF2 >
571  friend typename DerestrictTrait< SparseColumn<MT2,SO2,SF2> >::Type
572  derestrict( SparseColumn<MT2,SO2,SF2>& dm );
574  //**********************************************************************************************
575 
576  //**Compile time checks*************************************************************************
586  //**********************************************************************************************
587 };
588 //*************************************************************************************************
589 
590 
591 
592 
593 //=================================================================================================
594 //
595 // CONSTRUCTOR
596 //
597 //=================================================================================================
598 
599 //*************************************************************************************************
606 template< typename MT // Type of the sparse matrix
607  , bool SO // Storage order
608  , bool SF > // Symmetry flag
609 inline SparseColumn<MT,SO,SF>::SparseColumn( MT& matrix, size_t index )
610  : matrix_( matrix ) // The sparse matrix containing the column
611  , col_ ( index ) // The index of the column in the matrix
612 {
613  if( matrix_.columns() <= index )
614  throw std::invalid_argument( "Invalid column access index" );
615 }
616 //*************************************************************************************************
617 
618 
619 
620 
621 //=================================================================================================
622 //
623 // DATA ACCESS FUNCTIONS
624 //
625 //=================================================================================================
626 
627 //*************************************************************************************************
633 template< typename MT // Type of the sparse matrix
634  , bool SO // Storage order
635  , bool SF > // Symmetry flag
636 inline typename SparseColumn<MT,SO,SF>::Reference
638 {
639  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
640  return matrix_(index,col_);
641 }
642 //*************************************************************************************************
643 
644 
645 //*************************************************************************************************
651 template< typename MT // Type of the sparse matrix
652  , bool SO // Storage order
653  , bool SF > // Symmetry flag
656 {
657  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
658  return const_cast<const MT&>( matrix_ )(index,col_);
659 }
660 //*************************************************************************************************
661 
662 
663 //*************************************************************************************************
670 template< typename MT // Type of the sparse matrix
671  , bool SO // Storage order
672  , bool SF > // Symmetry flag
674 {
675  return matrix_.begin( col_ );
676 }
677 //*************************************************************************************************
678 
679 
680 //*************************************************************************************************
687 template< typename MT // Type of the sparse matrix
688  , bool SO // Storage order
689  , bool SF > // Symmetry flag
691 {
692  return matrix_.cbegin( col_ );
693 }
694 //*************************************************************************************************
695 
696 
697 //*************************************************************************************************
704 template< typename MT // Type of the sparse matrix
705  , bool SO // Storage order
706  , bool SF > // Symmetry flag
708 {
709  return matrix_.cbegin( col_ );
710 }
711 //*************************************************************************************************
712 
713 
714 //*************************************************************************************************
721 template< typename MT // Type of the sparse matrix
722  , bool SO // Storage order
723  , bool SF > // Symmetry flag
725 {
726  return matrix_.end( col_ );
727 }
728 //*************************************************************************************************
729 
730 
731 //*************************************************************************************************
738 template< typename MT // Type of the sparse matrix
739  , bool SO // Storage order
740  , bool SF > // Symmetry flag
742 {
743  return matrix_.cend( col_ );
744 }
745 //*************************************************************************************************
746 
747 
748 //*************************************************************************************************
755 template< typename MT // Type of the sparse matrix
756  , bool SO // Storage order
757  , bool SF > // Symmetry flag
759 {
760  return matrix_.cend( col_ );
761 }
762 //*************************************************************************************************
763 
764 
765 
766 
767 //=================================================================================================
768 //
769 // ASSIGNMENT OPERATORS
770 //
771 //=================================================================================================
772 
773 //*************************************************************************************************
786 template< typename MT // Type of the sparse matrix
787  , bool SO // Storage order
788  , bool SF > // Symmetry flag
790 {
791  using blaze::assign;
792 
796 
797  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && col_ == rhs.col_ ) )
798  return *this;
799 
800  if( size() != rhs.size() )
801  throw std::invalid_argument( "Column sizes do not match" );
802 
803  if( !preservesInvariant( matrix_, rhs ) )
804  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
805 
806  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
807 
808  if( rhs.canAlias( &matrix_ ) ) {
809  const ResultType tmp( rhs );
810  left.reset();
811  left.reserve( tmp.nonZeros() );
812  assign( left, tmp );
813  }
814  else {
815  left.reset();
816  left.reserve( rhs.nonZeros() );
817  assign( left, rhs );
818  }
819 
820  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
821  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
822 
823  return *this;
824 }
825 //*************************************************************************************************
826 
827 
828 //*************************************************************************************************
841 template< typename MT // Type of the sparse matrix
842  , bool SO // Storage order
843  , bool SF > // Symmetry flag
844 template< typename VT > // Type of the right-hand side dense vector
846 {
847  using blaze::assign;
848 
852 
853  if( size() != (~rhs).size() )
854  throw std::invalid_argument( "Vector sizes do not match" );
855 
856  typedef typename If< IsRestricted<MT>, typename VT::CompositeType, const VT& >::Type Right;
857  Right right( ~rhs );
858 
859  if( !preservesInvariant( matrix_, right ) )
860  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
861 
862  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
863 
864  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
865  const typename VT::ResultType tmp( right );
866  left.reset();
867  assign( left, tmp );
868  }
869  else {
870  left.reset();
871  assign( left, right );
872  }
873 
874  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
875  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
876 
877  return *this;
878 }
879 //*************************************************************************************************
880 
881 
882 //*************************************************************************************************
895 template< typename MT // Type of the sparse matrix
896  , bool SO // Storage order
897  , bool SF > // Symmetry flag
898 template< typename VT > // Type of the right-hand side sparse vector
900 {
901  using blaze::assign;
902 
906 
907  if( size() != (~rhs).size() )
908  throw std::invalid_argument( "Vector sizes do not match" );
909 
910  typedef typename If< IsRestricted<MT>, typename VT::CompositeType, const VT& >::Type Right;
911  Right right( ~rhs );
912 
913  if( !preservesInvariant( matrix_, right ) )
914  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
915 
916  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
917 
918  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
919  const typename VT::ResultType tmp( right );
920  left.reset();
921  left.reserve( tmp.nonZeros() );
922  assign( left, tmp );
923  }
924  else {
925  left.reset();
926  left.reserve( right.nonZeros() );
927  assign( left, right );
928  }
929 
930  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
931  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
932 
933  return *this;
934 }
935 //*************************************************************************************************
936 
937 
938 //*************************************************************************************************
951 template< typename MT // Type of the sparse matrix
952  , bool SO // Storage order
953  , bool SF > // Symmetry flag
954 template< typename VT > // Type of the right-hand side dense vector
956 {
957  using blaze::assign;
958 
965 
967 
971 
972  if( size() != (~rhs).size() )
973  throw std::invalid_argument( "Vector sizes do not match" );
974 
975  const AddType tmp( *this + (~rhs) );
976 
977  if( !preservesInvariant( matrix_, tmp ) )
978  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
979 
980  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
981 
982  left.reset();
983  assign( left, tmp );
984 
985  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
986  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
987 
988  return *this;
989 }
990 //*************************************************************************************************
991 
992 
993 //*************************************************************************************************
1006 template< typename MT // Type of the sparse matrix
1007  , bool SO // Storage order
1008  , bool SF > // Symmetry flag
1009 template< typename VT > // Type of the right-hand side sparse vector
1011 {
1012  using blaze::assign;
1013 
1020 
1021  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
1022 
1026 
1027  if( size() != (~rhs).size() )
1028  throw std::invalid_argument( "Vector sizes do not match" );
1029 
1030  const AddType tmp( *this + (~rhs) );
1031 
1032  if( !preservesInvariant( matrix_, tmp ) )
1033  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
1034 
1035  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1036 
1037  left.reset();
1038  left.reserve( tmp.nonZeros() );
1039  assign( left, tmp );
1040 
1041  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1042  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1043 
1044  return *this;
1045 }
1046 //*************************************************************************************************
1047 
1048 
1049 //*************************************************************************************************
1063 template< typename MT // Type of the sparse matrix
1064  , bool SO // Storage order
1065  , bool SF > // Symmetry flag
1066 template< typename VT > // Type of the right-hand side dense vector
1068 {
1069  using blaze::assign;
1070 
1077 
1078  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
1079 
1083 
1084  if( size() != (~rhs).size() )
1085  throw std::invalid_argument( "Vector sizes do not match" );
1086 
1087  const SubType tmp( *this - (~rhs) );
1088 
1089  if( !preservesInvariant( matrix_, tmp ) )
1090  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
1091 
1092  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1093 
1094  left.reset();
1095  assign( left, tmp );
1096 
1097  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1098  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1099 
1100  return *this;
1101 }
1102 //*************************************************************************************************
1103 
1104 
1105 //*************************************************************************************************
1119 template< typename MT // Type of the sparse matrix
1120  , bool SO // Storage order
1121  , bool SF > // Symmetry flag
1122 template< typename VT > // Type of the right-hand side sparse vector
1124 {
1125  using blaze::assign;
1126 
1133 
1134  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
1135 
1139 
1140  if( size() != (~rhs).size() )
1141  throw std::invalid_argument( "Vector sizes do not match" );
1142 
1143  const SubType tmp( *this - (~rhs) );
1144 
1145  if( !preservesInvariant( matrix_, tmp ) )
1146  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
1147 
1148  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1149 
1150  left.reset();
1151  left.reserve( tmp.nonZeros() );
1152  assign( left, tmp );
1153 
1154  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1155  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1156 
1157  return *this;
1158 }
1159 //*************************************************************************************************
1160 
1161 
1162 //*************************************************************************************************
1173 template< typename MT // Type of the sparse matrix
1174  , bool SO // Storage order
1175  , bool SF > // Symmetry flag
1176 template< typename VT > // Type of the right-hand side vector
1178 {
1179  using blaze::assign;
1180 
1186 
1187  typedef typename MultTrait<ResultType,typename VT::ResultType>::Type MultType;
1188 
1191 
1192  if( size() != (~rhs).size() )
1193  throw std::invalid_argument( "Vector sizes do not match" );
1194 
1195  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
1196 
1197  const MultType tmp( *this * (~rhs) );
1198  left.reset();
1199  assign( left, tmp );
1200 
1201  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
1202  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
1203 
1204  return *this;
1205 }
1206 //*************************************************************************************************
1207 
1208 
1209 //*************************************************************************************************
1223 template< typename MT // Type of the sparse matrix
1224  , bool SO // Storage order
1225  , bool SF > // Symmetry flag
1226 template< typename Other > // Data type of the right-hand side scalar
1227 inline typename EnableIf< IsNumeric<Other>, SparseColumn<MT,SO,SF> >::Type&
1229 {
1231 
1232  for( Iterator element=begin(); element!=end(); ++element )
1233  element->value() *= rhs;
1234  return *this;
1235 }
1236 //*************************************************************************************************
1237 
1238 
1239 //*************************************************************************************************
1256 template< typename MT // Type of the sparse matrix
1257  , bool SO // Storage order
1258  , bool SF > // Symmetry flag
1259 template< typename Other > // Data type of the right-hand side scalar
1260 inline typename EnableIf< IsNumeric<Other>, SparseColumn<MT,SO,SF> >::Type&
1262 {
1264 
1265  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1266 
1267  typedef typename DivTrait<ElementType,Other>::Type DT;
1268  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
1269 
1270  // Depending on the two involved data types, an integer division is applied or a
1271  // floating point division is selected.
1273  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
1274  for( Iterator element=begin(); element!=end(); ++element )
1275  element->value() *= tmp;
1276  }
1277  else {
1278  for( Iterator element=begin(); element!=end(); ++element )
1279  element->value() /= rhs;
1280  }
1281 
1282  return *this;
1283 }
1284 //*************************************************************************************************
1285 
1286 
1287 
1288 
1289 //=================================================================================================
1290 //
1291 // UTILITY FUNCTIONS
1292 //
1293 //=================================================================================================
1294 
1295 //*************************************************************************************************
1300 template< typename MT // Type of the sparse matrix
1301  , bool SO // Storage order
1302  , bool SF > // Symmetry flag
1303 inline size_t SparseColumn<MT,SO,SF>::size() const
1304 {
1305  return matrix_.rows();
1306 }
1307 //*************************************************************************************************
1308 
1309 
1310 //*************************************************************************************************
1315 template< typename MT // Type of the sparse matrix
1316  , bool SO // Storage order
1317  , bool SF > // Symmetry flag
1319 {
1320  return matrix_.capacity( col_ );
1321 }
1322 //*************************************************************************************************
1323 
1324 
1325 //*************************************************************************************************
1333 template< typename MT // Type of the sparse matrix
1334  , bool SO // Storage order
1335  , bool SF > // Symmetry flag
1337 {
1338  return matrix_.nonZeros( col_ );
1339 }
1340 //*************************************************************************************************
1341 
1342 
1343 //*************************************************************************************************
1348 template< typename MT // Type of the sparse matrix
1349  , bool SO // Storage order
1350  , bool SF > // Symmetry flag
1352 {
1353  matrix_.reset( col_ );
1354 }
1355 //*************************************************************************************************
1356 
1357 
1358 //*************************************************************************************************
1369 template< typename MT // Type of the sparse matrix
1370  , bool SO // Storage order
1371  , bool SF > // Symmetry flag
1372 inline typename SparseColumn<MT,SO,SF>::Iterator
1373  SparseColumn<MT,SO,SF>::set( size_t index, const ElementType& value )
1374 {
1375  return matrix_.set( index, col_, value );
1376 }
1377 //*************************************************************************************************
1378 
1379 
1380 //*************************************************************************************************
1392 template< typename MT // Type of the sparse matrix
1393  , bool SO // Storage order
1394  , bool SF > // Symmetry flag
1395 inline typename SparseColumn<MT,SO,SF>::Iterator
1396  SparseColumn<MT,SO,SF>::insert( size_t index, const ElementType& value )
1397 {
1398  return matrix_.insert( index, col_, value );
1399 }
1400 //*************************************************************************************************
1401 
1402 
1403 //*************************************************************************************************
1411 template< typename MT // Type of the sparse matrix
1412  , bool SO // Storage order
1413  , bool SF > // Symmetry flag
1414 inline void SparseColumn<MT,SO,SF>::erase( size_t index )
1415 {
1416  matrix_.erase( index, col_ );
1417 }
1418 //*************************************************************************************************
1419 
1420 
1421 //*************************************************************************************************
1429 template< typename MT // Type of the sparse matrix
1430  , bool SO // Storage order
1431  , bool SF > // Symmetry flag
1433 {
1434  return matrix_.erase( col_, pos );
1435 }
1436 //*************************************************************************************************
1437 
1438 
1439 //*************************************************************************************************
1448 template< typename MT // Type of the sparse matrix
1449  , bool SO // Storage order
1450  , bool SF > // Symmetry flag
1451 inline typename SparseColumn<MT,SO,SF>::Iterator
1453 {
1454  return matrix_.erase( col_, first, last );
1455 }
1456 //*************************************************************************************************
1457 
1458 
1459 //*************************************************************************************************
1468 template< typename MT // Type of the sparse matrix
1469  , bool SO // Storage order
1470  , bool SF > // Symmetry flag
1472 {
1473  matrix_.reserve( col_, n );
1474 }
1475 //*************************************************************************************************
1476 
1477 
1478 //*************************************************************************************************
1488 template< typename MT // Type of the sparse matrix
1489  , bool SO // Storage order
1490  , bool SF > // Symmetry flag
1491 template< typename Other > // Data type of the scalar value
1493 {
1495 
1496  for( Iterator element=begin(); element!=end(); ++element )
1497  element->value() *= scalar;
1498  return *this;
1499 }
1500 //*************************************************************************************************
1501 
1502 
1503 //*************************************************************************************************
1511 template< typename MT // Type of the sparse matrix
1512  , bool SO // Storage order
1513  , bool SF > // Symmetry flag
1515 {
1516  using blaze::max;
1517  using blaze::min;
1518 
1519  size_t nonzeros( 2UL*capacity()+1UL );
1520  nonzeros = max( nonzeros, 7UL );
1521  nonzeros = min( nonzeros, size() );
1522 
1523  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
1524 
1525  return nonzeros;
1526 }
1527 //*************************************************************************************************
1528 
1529 
1530 //*************************************************************************************************
1541 template< typename MT // Type of the sparse matrix
1542  , bool SO // Storage order
1543  , bool SF > // Symmetry flag
1544 template< typename MT2 // Type of the left-hand side sparse matrix
1545  , bool SO2 // Storage order of the left-hand side sparse matrix
1546  , typename VT > // Type of the right-hand side vector
1547 inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
1549 {
1550  UNUSED_PARAMETER( lhs, rhs );
1551 
1552  return true;
1553 }
1554 //*************************************************************************************************
1555 
1556 
1557 //*************************************************************************************************
1568 template< typename MT // Type of the sparse matrix
1569  , bool SO // Storage order
1570  , bool SF > // Symmetry flag
1571 template< typename MT2 // Type of the left-hand side sparse matrix
1572  , bool SO2 // Storage order of the left-hand side sparse matrix
1573  , typename VT > // Type of the right-hand side dense vector
1574 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1576 {
1578 
1579  UNUSED_PARAMETER( lhs );
1580 
1581  const size_t iend( ( IsStrictlyLower<MT2>::value )?( col_+1UL ):( col_ ) );
1582 
1583  for( size_t i=0UL; i<iend; ++i ) {
1584  if( !isDefault( (~rhs)[i] ) )
1585  return false;
1586  }
1587 
1588  if( IsUniLower<MT2>::value && !isOne( (~rhs)[col_] ) )
1589  return false;
1590 
1591  return true;
1592 }
1593 //*************************************************************************************************
1594 
1595 
1596 //*************************************************************************************************
1607 template< typename MT // Type of the sparse matrix
1608  , bool SO // Storage order
1609  , bool SF > // Symmetry flag
1610 template< typename MT2 // Type of the left-hand side sparse matrix
1611  , bool SO2 // Storage order of the left-hand side sparse matrix
1612  , typename VT > // Type of the right-hand side sparse vector
1613 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1615 {
1617 
1618  UNUSED_PARAMETER( lhs );
1619 
1620  typedef typename VT::ConstIterator RhsIterator;
1621 
1622  const RhsIterator last( (~rhs).lowerBound( ( IsStrictlyLower<MT2>::value )?( col_+1UL ):( col_ ) ) );
1623 
1624  if( IsUniLower<MT2>::value && ( last == (~rhs).end() || last->index() != col_ || !isOne( last->value() ) ) )
1625  return false;
1626 
1627  for( RhsIterator element=(~rhs).begin(); element!=last; ++element ) {
1628  if( !isDefault( element->value() ) )
1629  return false;
1630  }
1631 
1632  return true;
1633 }
1634 //*************************************************************************************************
1635 
1636 
1637 //*************************************************************************************************
1648 template< typename MT // Type of the sparse matrix
1649  , bool SO // Storage order
1650  , bool SF > // Symmetry flag
1651 template< typename MT2 // Type of the left-hand side sparse matrix
1652  , bool SO2 // Storage order of the left-hand side sparse matrix
1653  , typename VT > // Type of the right-hand side dense vector
1654 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1656 {
1658 
1659  UNUSED_PARAMETER( lhs );
1660 
1661  if( IsUniUpper<MT2>::value && !isOne( (~rhs)[col_] ) )
1662  return false;
1663 
1664  const size_t ibegin( ( IsStrictlyUpper<MT2>::value )?( col_ ):( col_+1UL ) );
1665 
1666  for( size_t i=ibegin; i<size(); ++i ) {
1667  if( !isDefault( (~rhs)[i] ) )
1668  return false;
1669  }
1670 
1671  return true;
1672 }
1673 //*************************************************************************************************
1674 
1675 
1676 //*************************************************************************************************
1687 template< typename MT // Type of the sparse matrix
1688  , bool SO // Storage order
1689  , bool SF > // Symmetry flag
1690 template< typename MT2 // Type of the left-hand side sparse matrix
1691  , bool SO2 // Storage order of the left-hand side sparse matrix
1692  , typename VT > // Type of the right-hand side sparse vector
1693 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
1695 {
1697 
1698  UNUSED_PARAMETER( lhs );
1699 
1700  typedef typename VT::ConstIterator RhsIterator;
1701 
1702  const bool checkDiagonal( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value );
1703  const RhsIterator last( (~rhs).end() );
1704  RhsIterator element( (~rhs).lowerBound( ( checkDiagonal )?( col_ ):( col_+1UL ) ) );
1705 
1706  if( IsUniUpper<MT2>::value ) {
1707  if( element == last || element->index() != col_ || !isOne( element->value() ) )
1708  return false;
1709  ++element;
1710  }
1711 
1712  for( ; element!=last; ++element ) {
1713  if( !isDefault( element->value() ) )
1714  return false;
1715  }
1716 
1717  return true;
1718 }
1719 //*************************************************************************************************
1720 
1721 
1722 //*************************************************************************************************
1733 template< typename MT // Type of the sparse matrix
1734  , bool SO // Storage order
1735  , bool SF > // Symmetry flag
1736 template< typename MT2 // Type of the left-hand side sparse matrix
1737  , bool SO2 // Storage order of the left-hand side sparse matrix
1738  , typename VT > // Type of the right-hand side dense vector
1739 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
1741 {
1743 
1744  UNUSED_PARAMETER( lhs );
1745 
1746  for( size_t i=0UL; i<col_; ++i ) {
1747  if( !isDefault( (~rhs)[i] ) )
1748  return false;
1749  }
1750 
1751  for( size_t i=col_+1UL; i<size(); ++i ) {
1752  if( !isDefault( (~rhs)[i] ) )
1753  return false;
1754  }
1755 
1756  return true;
1757 }
1758 //*************************************************************************************************
1759 
1760 
1761 //*************************************************************************************************
1772 template< typename MT // Type of the sparse matrix
1773  , bool SO // Storage order
1774  , bool SF > // Symmetry flag
1775 template< typename MT2 // Type of the left-hand side sparse matrix
1776  , bool SO2 // Storage order of the left-hand side sparse matrix
1777  , typename VT > // Type of the right-hand side sparse vector
1778 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
1780 {
1782 
1783  UNUSED_PARAMETER( lhs );
1784 
1785  typedef typename VT::ConstIterator RhsIterator;
1786 
1787  for( RhsIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
1788  if( element->index() != col_ && !isDefault( element->value() ) )
1789  return false;
1790  }
1791 
1792  return true;
1793 }
1794 //*************************************************************************************************
1795 
1796 
1797 
1798 
1799 //=================================================================================================
1800 //
1801 // LOOKUP FUNCTIONS
1802 //
1803 //=================================================================================================
1804 
1805 //*************************************************************************************************
1818 template< typename MT // Type of the sparse matrix
1819  , bool SO // Storage order
1820  , bool SF > // Symmetry flag
1822 {
1823  return matrix_.find( index, col_ );
1824 }
1825 //*************************************************************************************************
1826 
1827 
1828 //*************************************************************************************************
1841 template< typename MT // Type of the sparse matrix
1842  , bool SO // Storage order
1843  , bool SF > // Symmetry flag
1845  SparseColumn<MT,SO,SF>::find( size_t index ) const
1846 {
1847  return matrix_.find( index, col_ );
1848 }
1849 //*************************************************************************************************
1850 
1851 
1852 //*************************************************************************************************
1864 template< typename MT // Type of the sparse matrix
1865  , bool SO // Storage order
1866  , bool SF > // Symmetry flag
1868 {
1869  return matrix_.lowerBound( index, col_ );
1870 }
1871 //*************************************************************************************************
1872 
1873 
1874 //*************************************************************************************************
1886 template< typename MT // Type of the sparse matrix
1887  , bool SO // Storage order
1888  , bool SF > // Symmetry flag
1891 {
1892  return matrix_.lowerBound( index, col_ );
1893 }
1894 //*************************************************************************************************
1895 
1896 
1897 //*************************************************************************************************
1909 template< typename MT // Type of the sparse matrix
1910  , bool SO // Storage order
1911  , bool SF > // Symmetry flag
1913 {
1914  return matrix_.upperBound( index, col_ );
1915 }
1916 //*************************************************************************************************
1917 
1918 
1919 //*************************************************************************************************
1931 template< typename MT // Type of the sparse matrix
1932  , bool SO // Storage order
1933  , bool SF > // Symmetry flag
1936 {
1937  return matrix_.upperBound( index, col_ );
1938 }
1939 //*************************************************************************************************
1940 
1941 
1942 
1943 
1944 //=================================================================================================
1945 //
1946 // LOW-LEVEL UTILITY FUNCTIONS
1947 //
1948 //=================================================================================================
1949 
1950 //*************************************************************************************************
1974 template< typename MT // Type of the sparse matrix
1975  , bool SO // Storage order
1976  , bool SF > // Symmetry flag
1977 inline void SparseColumn<MT,SO,SF>::append( size_t index, const ElementType& value, bool check )
1978 {
1979  matrix_.append( index, col_, value, check );
1980 }
1981 //*************************************************************************************************
1982 
1983 
1984 
1985 
1986 //=================================================================================================
1987 //
1988 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1989 //
1990 //=================================================================================================
1991 
1992 //*************************************************************************************************
2002 template< typename MT // Type of the sparse matrix
2003  , bool SO // Storage order
2004  , bool SF > // Symmetry flag
2005 template< typename Other > // Data type of the foreign expression
2006 inline bool SparseColumn<MT,SO,SF>::canAlias( const Other* alias ) const
2007 {
2008  return matrix_.isAliased( alias );
2009 }
2010 //*************************************************************************************************
2011 
2012 
2013 //*************************************************************************************************
2023 template< typename MT // Type of the sparse matrix
2024  , bool SO // Storage order
2025  , bool SF > // Symmetry flag
2026 template< typename Other > // Data type of the foreign expression
2027 inline bool SparseColumn<MT,SO,SF>::isAliased( const Other* alias ) const
2028 {
2029  return matrix_.isAliased( alias );
2030 }
2031 //*************************************************************************************************
2032 
2033 
2034 //*************************************************************************************************
2045 template< typename MT // Type of the sparse matrix
2046  , bool SO // Storage order
2047  , bool SF > // Symmetry flag
2048 template< typename VT > // Type of the right-hand side dense vector
2050 {
2052 
2053  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2054  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2055 
2056  for( size_t i=0UL; i<size(); ++i )
2057  {
2058  if( matrix_.nonZeros( col_ ) == matrix_.capacity( col_ ) )
2059  matrix_.reserve( col_, extendCapacity() );
2060 
2061  matrix_.append( i, col_, (~rhs)[i], true );
2062  }
2063 }
2064 //*************************************************************************************************
2065 
2066 
2067 //*************************************************************************************************
2078 template< typename MT // Type of the sparse matrix
2079  , bool SO // Storage order
2080  , bool SF > // Symmetry flag
2081 template< typename VT > // Type of the right-hand side sparse vector
2083 {
2085 
2086  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2087  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
2088 
2089  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2090  matrix_.append( element->index(), col_, element->value(), true );
2091  }
2092 }
2093 //*************************************************************************************************
2094 
2095 
2096 //*************************************************************************************************
2107 template< typename MT // Type of the sparse matrix
2108  , bool SO // Storage order
2109  , bool SF > // Symmetry flag
2110 template< typename VT > // Type of the right-hand side dense vector
2112 {
2114 
2115  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
2116 
2120 
2121  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2122 
2123  const AddType tmp( serial( *this + (~rhs) ) );
2124  matrix_.reset( col_ );
2125  assign( tmp );
2126 }
2127 //*************************************************************************************************
2128 
2129 
2130 //*************************************************************************************************
2141 template< typename MT // Type of the sparse matrix
2142  , bool SO // Storage order
2143  , bool SF > // Symmetry flag
2144 template< typename VT > // Type of the right-hand side sparse vector
2146 {
2148 
2149  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
2150 
2154 
2155  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2156 
2157  const AddType tmp( serial( *this + (~rhs) ) );
2158  matrix_.reset( col_ );
2159  matrix_.reserve( col_, tmp.nonZeros() );
2160  assign( tmp );
2161 }
2162 //*************************************************************************************************
2163 
2164 
2165 //*************************************************************************************************
2176 template< typename MT // Type of the sparse matrix
2177  , bool SO // Storage order
2178  , bool SF > // Symmetry flag
2179 template< typename VT > // Type of the right-hand side dense vector
2181 {
2183 
2184  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
2185 
2189 
2190  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2191 
2192  const SubType tmp( serial( *this - (~rhs) ) );
2193  matrix_.reset( col_ );
2194  assign( tmp );
2195 }
2196 //*************************************************************************************************
2197 
2198 
2199 //*************************************************************************************************
2210 template< typename MT // Type of the sparse matrix
2211  , bool SO // Storage order
2212  , bool SF > // Symmetry flag
2213 template< typename VT > // Type of the right-hand side sparse vector
2215 {
2217 
2218  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
2219 
2223 
2224  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2225 
2226  const SubType tmp( serial( *this - (~rhs) ) );
2227  matrix_.reset( col_ );
2228  matrix_.reserve( col_, tmp.nonZeros() );
2229  assign( tmp );
2230 }
2231 //*************************************************************************************************
2232 
2233 
2234 
2235 
2236 
2237 
2238 
2239 
2240 //=================================================================================================
2241 //
2242 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR MATRICES
2243 //
2244 //=================================================================================================
2245 
2246 //*************************************************************************************************
2254 template< typename MT > // Type of the sparse matrix
2255 class SparseColumn<MT,false,false> : public SparseVector< SparseColumn<MT,false,false>, false >
2256  , private Column
2257 {
2258  private:
2259  //**Type definitions****************************************************************************
2261  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
2262  //**********************************************************************************************
2263 
2264  //**********************************************************************************************
2266 
2272  enum { useConst = IsConst<MT>::value };
2273  //**********************************************************************************************
2274 
2275  public:
2276  //**Type definitions****************************************************************************
2277  typedef SparseColumn<MT,false,false> This;
2278  typedef typename ColumnTrait<MT>::Type ResultType;
2279  typedef typename ResultType::TransposeType TransposeType;
2280  typedef typename MT::ElementType ElementType;
2281  typedef typename MT::ReturnType ReturnType;
2282  typedef const SparseColumn& CompositeType;
2283 
2285  typedef typename MT::ConstReference ConstReference;
2286 
2288  typedef typename IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference;
2289  //**********************************************************************************************
2290 
2291  //**ColumnElement class definition**************************************************************
2294  template< typename MatrixType // Type of the sparse matrix
2295  , typename IteratorType > // Type of the sparse matrix iterator
2296  class ColumnElement : private SparseElement
2297  {
2298  private:
2299  //*******************************************************************************************
2301 
2306  enum { returnConst = IsConst<MatrixType>::value };
2307  //*******************************************************************************************
2308 
2309  //**Type definitions*************************************************************************
2311  typedef typename std::iterator_traits<IteratorType>::value_type SET;
2312 
2313  typedef typename SET::Reference RT;
2314  typedef typename SET::ConstReference CRT;
2315  //*******************************************************************************************
2316 
2317  public:
2318  //**Type definitions*************************************************************************
2319  typedef typename SET::ValueType ValueType;
2320  typedef size_t IndexType;
2321  typedef typename IfTrue<returnConst,CRT,RT>::Type Reference;
2322  typedef CRT ConstReference;
2323  //*******************************************************************************************
2324 
2325  //**Constructor******************************************************************************
2331  inline ColumnElement( IteratorType pos, size_t row )
2332  : pos_( pos ) // Iterator to the current position within the sparse column
2333  , row_( row ) // Index of the according row
2334  {}
2335  //*******************************************************************************************
2336 
2337  //**Assignment operator**********************************************************************
2343  template< typename T > inline ColumnElement& operator=( const T& v ) {
2344  *pos_ = v;
2345  return *this;
2346  }
2347  //*******************************************************************************************
2348 
2349  //**Addition assignment operator*************************************************************
2355  template< typename T > inline ColumnElement& operator+=( const T& v ) {
2356  *pos_ += v;
2357  return *this;
2358  }
2359  //*******************************************************************************************
2360 
2361  //**Subtraction assignment operator**********************************************************
2367  template< typename T > inline ColumnElement& operator-=( const T& v ) {
2368  *pos_ -= v;
2369  return *this;
2370  }
2371  //*******************************************************************************************
2372 
2373  //**Multiplication assignment operator*******************************************************
2379  template< typename T > inline ColumnElement& operator*=( const T& v ) {
2380  *pos_ *= v;
2381  return *this;
2382  }
2383  //*******************************************************************************************
2384 
2385  //**Division assignment operator*************************************************************
2391  template< typename T > inline ColumnElement& operator/=( const T& v ) {
2392  *pos_ /= v;
2393  return *this;
2394  }
2395  //*******************************************************************************************
2396 
2397  //**Element access operator******************************************************************
2402  inline const ColumnElement* operator->() const {
2403  return this;
2404  }
2405  //*******************************************************************************************
2406 
2407  //**Value function***************************************************************************
2412  inline Reference value() const {
2413  return pos_->value();
2414  }
2415  //*******************************************************************************************
2416 
2417  //**Index function***************************************************************************
2422  inline IndexType index() const {
2423  return row_;
2424  }
2425  //*******************************************************************************************
2426 
2427  private:
2428  //**Member variables*************************************************************************
2429  IteratorType pos_;
2430  size_t row_;
2431  //*******************************************************************************************
2432  };
2433  //**********************************************************************************************
2434 
2435  //**ColumnIterator class definition*************************************************************
2438  template< typename MatrixType // Type of the sparse matrix
2439  , typename IteratorType > // Type of the sparse matrix iterator
2440  class ColumnIterator
2441  {
2442  public:
2443  //**Type definitions*************************************************************************
2444  typedef std::forward_iterator_tag IteratorCategory;
2445  typedef ColumnElement<MatrixType,IteratorType> ValueType;
2446  typedef ValueType PointerType;
2447  typedef ValueType ReferenceType;
2448  typedef ptrdiff_t DifferenceType;
2449 
2450  // STL iterator requirements
2451  typedef IteratorCategory iterator_category;
2452  typedef ValueType value_type;
2453  typedef PointerType pointer;
2454  typedef ReferenceType reference;
2455  typedef DifferenceType difference_type;
2456  //*******************************************************************************************
2457 
2458  //**Constructor******************************************************************************
2461  inline ColumnIterator()
2462  : matrix_( NULL ) // The sparse matrix containing the column.
2463  , row_ ( 0UL ) // The current row index.
2464  , column_( 0UL ) // The current column index.
2465  , pos_ () // Iterator to the current sparse element.
2466  {}
2467  //*******************************************************************************************
2468 
2469  //**Constructor******************************************************************************
2476  inline ColumnIterator( MatrixType& matrix, size_t row, size_t column )
2477  : matrix_( &matrix ) // The sparse matrix containing the column.
2478  , row_ ( row ) // The current row index.
2479  , column_( column ) // The current column index.
2480  , pos_ () // Iterator to the current sparse element.
2481  {
2482  for( ; row_<matrix_->rows(); ++row_ ) {
2483  pos_ = matrix_->find( row_, column_ );
2484  if( pos_ != matrix_->end( row_ ) ) break;
2485  }
2486  }
2487  //*******************************************************************************************
2488 
2489  //**Constructor******************************************************************************
2497  inline ColumnIterator( MatrixType& matrix, size_t row, size_t column, IteratorType pos )
2498  : matrix_( &matrix ) // The sparse matrix containing the column.
2499  , row_ ( row ) // The current row index.
2500  , column_( column ) // The current column index.
2501  , pos_ ( pos ) // Iterator to the current sparse element.
2502  {
2503  BLAZE_INTERNAL_ASSERT( matrix.find( row, column ) == pos, "Invalid initial iterator position" );
2504  }
2505  //*******************************************************************************************
2506 
2507  //**Constructor******************************************************************************
2512  template< typename MatrixType2, typename IteratorType2 >
2513  inline ColumnIterator( const ColumnIterator<MatrixType2,IteratorType2>& it )
2514  : matrix_( it.matrix_ ) // The sparse matrix containing the column.
2515  , row_ ( it.row_ ) // The current row index.
2516  , column_( it.column_ ) // The current column index.
2517  , pos_ ( it.pos_ ) // Iterator to the current sparse element.
2518  {}
2519  //*******************************************************************************************
2520 
2521  //**Prefix increment operator****************************************************************
2526  inline ColumnIterator& operator++() {
2527  ++row_;
2528  for( ; row_<matrix_->rows(); ++row_ ) {
2529  pos_ = matrix_->find( row_, column_ );
2530  if( pos_ != matrix_->end( row_ ) ) break;
2531  }
2532 
2533  return *this;
2534  }
2535  //*******************************************************************************************
2536 
2537  //**Postfix increment operator***************************************************************
2542  inline const ColumnIterator operator++( int ) {
2543  const ColumnIterator tmp( *this );
2544  ++(*this);
2545  return tmp;
2546  }
2547  //*******************************************************************************************
2548 
2549  //**Element access operator******************************************************************
2554  inline ReferenceType operator*() const {
2555  return ReferenceType( pos_, row_ );
2556  }
2557  //*******************************************************************************************
2558 
2559  //**Element access operator******************************************************************
2564  inline PointerType operator->() const {
2565  return PointerType( pos_, row_ );
2566  }
2567  //*******************************************************************************************
2568 
2569  //**Equality operator************************************************************************
2575  template< typename MatrixType2, typename IteratorType2 >
2576  inline bool operator==( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const {
2577  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
2578  }
2579  //*******************************************************************************************
2580 
2581  //**Inequality operator**********************************************************************
2587  template< typename MatrixType2, typename IteratorType2 >
2588  inline bool operator!=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const {
2589  return !( *this == rhs );
2590  }
2591  //*******************************************************************************************
2592 
2593  //**Subtraction operator*********************************************************************
2599  inline DifferenceType operator-( const ColumnIterator& rhs ) const {
2600  size_t counter( 0UL );
2601  for( size_t i=rhs.row_; i<row_; ++i ) {
2602  if( matrix_->find( i, column_ ) != matrix_->end( i ) )
2603  ++counter;
2604  }
2605  return counter;
2606  }
2607  //*******************************************************************************************
2608 
2609  private:
2610  //**Member variables*************************************************************************
2611  MatrixType* matrix_;
2612  size_t row_;
2613  size_t column_;
2614  IteratorType pos_;
2615  //*******************************************************************************************
2616 
2617  //**Friend declarations**********************************************************************
2618  template< typename MatrixType2, typename IteratorType2 > friend class ColumnIterator;
2619  template< typename MT2, bool SO2, bool SF2 > friend class SparseColumn;
2620  //*******************************************************************************************
2621  };
2622  //**********************************************************************************************
2623 
2624  //**Type definitions****************************************************************************
2626  typedef ColumnIterator<const MT,typename MT::ConstIterator> ConstIterator;
2627 
2629  typedef typename IfTrue< useConst, ConstIterator, ColumnIterator<MT,typename MT::Iterator> >::Type Iterator;
2630  //**********************************************************************************************
2631 
2632  //**Compilation flags***************************************************************************
2634  enum { smpAssignable = 0 };
2635  //**********************************************************************************************
2636 
2637  //**Constructors********************************************************************************
2640  explicit inline SparseColumn( MT& matrix, size_t index );
2641  // No explicitly declared copy constructor.
2643  //**********************************************************************************************
2644 
2645  //**Destructor**********************************************************************************
2646  // No explicitly declared destructor.
2647  //**********************************************************************************************
2648 
2649  //**Data access functions***********************************************************************
2652  inline Reference operator[]( size_t index );
2653  inline ConstReference operator[]( size_t index ) const;
2654  inline Iterator begin ();
2655  inline ConstIterator begin () const;
2656  inline ConstIterator cbegin() const;
2657  inline Iterator end ();
2658  inline ConstIterator end () const;
2659  inline ConstIterator cend () const;
2661  //**********************************************************************************************
2662 
2663  //**Assignment operators************************************************************************
2666  inline SparseColumn& operator= ( const SparseColumn& rhs );
2667  template< typename VT > inline SparseColumn& operator= ( const Vector<VT,false>& rhs );
2668  template< typename VT > inline SparseColumn& operator+=( const Vector<VT,false>& rhs );
2669  template< typename VT > inline SparseColumn& operator-=( const Vector<VT,false>& rhs );
2670  template< typename VT > inline SparseColumn& operator*=( const Vector<VT,false>& rhs );
2671 
2672  template< typename Other >
2673  inline typename EnableIf< IsNumeric<Other>, SparseColumn >::Type&
2674  operator*=( Other rhs );
2675 
2676  template< typename Other >
2677  inline typename EnableIf< IsNumeric<Other>, SparseColumn >::Type&
2678  operator/=( Other rhs );
2680  //**********************************************************************************************
2681 
2682  //**Utility functions***************************************************************************
2685  inline size_t size() const;
2686  inline size_t capacity() const;
2687  inline size_t nonZeros() const;
2688  inline void reset();
2689  inline Iterator set ( size_t index, const ElementType& value );
2690  inline Iterator insert ( size_t index, const ElementType& value );
2691  inline void erase ( size_t index );
2692  inline Iterator erase ( Iterator pos );
2693  inline Iterator erase ( Iterator first, Iterator last );
2694  inline void reserve( size_t n );
2695  template< typename Other > inline SparseColumn& scale ( const Other& scalar );
2697  //**********************************************************************************************
2698 
2699  //**Lookup functions****************************************************************************
2702  inline Iterator find ( size_t index );
2703  inline ConstIterator find ( size_t index ) const;
2704  inline Iterator lowerBound( size_t index );
2705  inline ConstIterator lowerBound( size_t index ) const;
2706  inline Iterator upperBound( size_t index );
2707  inline ConstIterator upperBound( size_t index ) const;
2709  //**********************************************************************************************
2710 
2711  //**Low-level utility functions*****************************************************************
2714  inline void append( size_t index, const ElementType& value, bool check=false );
2716  //**********************************************************************************************
2717 
2718  //**Expression template evaluation functions****************************************************
2721  template< typename Other > inline bool canAlias ( const Other* alias ) const;
2722  template< typename Other > inline bool isAliased( const Other* alias ) const;
2723 
2724  template< typename VT > inline void assign ( const DenseVector <VT,false>& rhs );
2725  template< typename VT > inline void assign ( const SparseVector<VT,false>& rhs );
2726  template< typename VT > inline void addAssign( const Vector<VT,false>& rhs );
2727  template< typename VT > inline void subAssign( const Vector<VT,false>& rhs );
2729  //**********************************************************************************************
2730 
2731  private:
2732  //**Utility functions***************************************************************************
2735  template< typename MT2, bool SO2, typename VT >
2736  inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
2737  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,false>& rhs );
2738 
2739  template< typename MT2, bool SO2, typename VT >
2740  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2741  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs );
2742 
2743  template< typename MT2, bool SO2, typename VT >
2744  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2745  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs );
2746 
2747  template< typename MT2, bool SO2, typename VT >
2748  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2749  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs );
2750 
2751  template< typename MT2, bool SO2, typename VT >
2752  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
2753  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs );
2754 
2755  template< typename MT2, bool SO2, typename VT >
2756  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2757  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs );
2758 
2759  template< typename MT2, bool SO2, typename VT >
2760  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
2761  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs );
2763  //**********************************************************************************************
2764 
2765  //**Member variables****************************************************************************
2768  Operand matrix_;
2769  const size_t col_;
2770 
2771  //**********************************************************************************************
2772 
2773  //**Friend declarations*************************************************************************
2774  template< typename MT2, bool SO2, bool SF2 >
2775  friend bool isSame( const SparseColumn<MT2,SO2,SF2>& a, const SparseColumn<MT2,SO2,SF2>& b );
2776 
2777  template< typename MT2, bool SO2, bool SF2 >
2778  friend typename DerestrictTrait< SparseColumn<MT2,SO2,SF2> >::Type
2779  derestrict( SparseColumn<MT2,SO2,SF2>& dm );
2780  //**********************************************************************************************
2781 
2782  //**Compile time checks*************************************************************************
2790  BLAZE_STATIC_ASSERT( !IsRestricted<MT>::value || IsLower<MT>::value || IsUpper<MT>::value );
2791  //**********************************************************************************************
2792 };
2794 //*************************************************************************************************
2795 
2796 
2797 
2798 
2799 //=================================================================================================
2800 //
2801 // CONSTRUCTOR
2802 //
2803 //=================================================================================================
2804 
2805 //*************************************************************************************************
2813 template< typename MT > // Type of the sparse matrix
2814 inline SparseColumn<MT,false,false>::SparseColumn( MT& matrix, size_t index )
2815  : matrix_( matrix ) // The sparse matrix containing the column
2816  , col_ ( index ) // The index of the column in the matrix
2817 {
2818  if( matrix_.columns() <= index )
2819  throw std::invalid_argument( "Invalid column access index" );
2820 }
2822 //*************************************************************************************************
2823 
2824 
2825 
2826 
2827 //=================================================================================================
2828 //
2829 // DATA ACCESS FUNCTIONS
2830 //
2831 //=================================================================================================
2832 
2833 //*************************************************************************************************
2840 template< typename MT > // Type of the sparse matrix
2843 {
2844  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2845  return matrix_(index,col_);
2846 }
2848 //*************************************************************************************************
2849 
2850 
2851 //*************************************************************************************************
2858 template< typename MT > // Type of the sparse matrix
2860  SparseColumn<MT,false,false>::operator[]( size_t index ) const
2861 {
2862  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2863  return const_cast<const MT&>( matrix_ )(index,col_);
2864 }
2866 //*************************************************************************************************
2867 
2868 
2869 //*************************************************************************************************
2877 template< typename MT > // Type of the sparse matrix
2879 {
2880  return Iterator( matrix_, 0UL, col_ );
2881 }
2883 //*************************************************************************************************
2884 
2885 
2886 //*************************************************************************************************
2894 template< typename MT > // Type of the sparse matrix
2897 {
2898  return ConstIterator( matrix_, 0UL, col_ );
2899 }
2901 //*************************************************************************************************
2902 
2903 
2904 //*************************************************************************************************
2912 template< typename MT > // Type of the sparse matrix
2915 {
2916  return ConstIterator( matrix_, 0UL, col_ );
2917 }
2919 //*************************************************************************************************
2920 
2921 
2922 //*************************************************************************************************
2930 template< typename MT > // Type of the sparse matrix
2932 {
2933  return Iterator( matrix_, size(), col_ );
2934 }
2936 //*************************************************************************************************
2937 
2938 
2939 //*************************************************************************************************
2947 template< typename MT > // Type of the sparse matrix
2950 {
2951  return ConstIterator( matrix_, size(), col_ );
2952 }
2954 //*************************************************************************************************
2955 
2956 
2957 //*************************************************************************************************
2965 template< typename MT > // Type of the sparse matrix
2968 {
2969  return ConstIterator( matrix_, size(), col_ );
2970 }
2972 //*************************************************************************************************
2973 
2974 
2975 
2976 
2977 //=================================================================================================
2978 //
2979 // ASSIGNMENT OPERATORS
2980 //
2981 //=================================================================================================
2982 
2983 //*************************************************************************************************
2997 template< typename MT > // Type of the sparse matrix
2998 inline SparseColumn<MT,false,false>&
2999  SparseColumn<MT,false,false>::operator=( const SparseColumn& rhs )
3000 {
3001  using blaze::assign;
3002 
3006 
3007  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && col_ == rhs.col_ ) )
3008  return *this;
3009 
3010  if( size() != rhs.size() )
3011  throw std::invalid_argument( "Column sizes do not match" );
3012 
3013  if( !preservesInvariant( matrix_, rhs ) )
3014  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
3015 
3016  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3017 
3018  if( rhs.canAlias( &matrix_ ) ) {
3019  const ResultType tmp( rhs );
3020  assign( left, tmp );
3021  }
3022  else {
3023  assign( left, rhs );
3024  }
3025 
3026  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3027  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3028 
3029  return *this;
3030 }
3032 //*************************************************************************************************
3033 
3034 
3035 //*************************************************************************************************
3049 template< typename MT > // Type of the sparse matrix
3050 template< typename VT > // Type of the right-hand side vector
3051 inline SparseColumn<MT,false,false>&
3052  SparseColumn<MT,false,false>::operator=( const Vector<VT,false>& rhs )
3053 {
3054  using blaze::assign;
3055 
3056  if( size() != (~rhs).size() )
3057  throw std::invalid_argument( "Vector sizes do not match" );
3058 
3059  const typename VT::CompositeType tmp( ~rhs );
3060 
3061  if( !preservesInvariant( matrix_, tmp ) )
3062  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
3063 
3064  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3065 
3066  assign( left, tmp );
3067 
3068  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3069  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3070 
3071  return *this;
3072 }
3074 //*************************************************************************************************
3075 
3076 
3077 //*************************************************************************************************
3091 template< typename MT > // Type of the sparse matrix
3092 template< typename VT > // Type of the right-hand side vector
3093 inline SparseColumn<MT,false,false>&
3094  SparseColumn<MT,false,false>::operator+=( const Vector<VT,false>& rhs )
3095 {
3096  using blaze::assign;
3097 
3103 
3104  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
3105 
3108 
3109  if( size() != (~rhs).size() )
3110  throw std::invalid_argument( "Vector sizes do not match" );
3111 
3112  const AddType tmp( *this + (~rhs) );
3113 
3114  if( !preservesInvariant( matrix_, tmp ) )
3115  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
3116 
3117  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3118 
3119  assign( left, tmp );
3120 
3121  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3122  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3123 
3124  return *this;
3125 }
3127 //*************************************************************************************************
3128 
3129 
3130 //*************************************************************************************************
3144 template< typename MT > // Type of the sparse matrix
3145 template< typename VT > // Type of the right-hand side vector
3146 inline SparseColumn<MT,false,false>&
3147  SparseColumn<MT,false,false>::operator-=( const Vector<VT,false>& rhs )
3148 {
3149  using blaze::assign;
3150 
3156 
3157  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
3158 
3161 
3162  if( size() != (~rhs).size() )
3163  throw std::invalid_argument( "Vector sizes do not match" );
3164 
3165  const SubType tmp( *this - (~rhs) );
3166 
3167  if( !preservesInvariant( matrix_, tmp ) )
3168  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
3169 
3170  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3171 
3172  assign( left, tmp );
3173 
3174  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3175  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3176 
3177  return *this;
3178 }
3180 //*************************************************************************************************
3181 
3182 
3183 //*************************************************************************************************
3195 template< typename MT > // Type of the sparse matrix
3196 template< typename VT > // Type of the right-hand side vector
3197 inline SparseColumn<MT,false,false>&
3198  SparseColumn<MT,false,false>::operator*=( const Vector<VT,false>& rhs )
3199 {
3200  using blaze::assign;
3201 
3207 
3208  typedef typename MultTrait<ResultType,typename VT::ResultType>::Type MultType;
3209 
3212 
3213  if( size() != (~rhs).size() )
3214  throw std::invalid_argument( "Vector sizes do not match" );
3215 
3216  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
3217 
3218  const MultType tmp( *this * (~rhs) );
3219  assign( left, tmp );
3220 
3221  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
3222  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
3223 
3224  return *this;
3225 }
3227 //*************************************************************************************************
3228 
3229 
3230 //*************************************************************************************************
3245 template< typename MT > // Type of the sparse matrix
3246 template< typename Other > // Data type of the right-hand side scalar
3247 inline typename EnableIf< IsNumeric<Other>, SparseColumn<MT,false,false> >::Type&
3248  SparseColumn<MT,false,false>::operator*=( Other rhs )
3249 {
3251 
3252  for( Iterator element=begin(); element!=end(); ++element )
3253  element->value() *= rhs;
3254  return *this;
3255 }
3257 //*************************************************************************************************
3258 
3259 
3260 //*************************************************************************************************
3278 template< typename MT > // Type of the sparse matrix
3279 template< typename Other > // Data type of the right-hand side scalar
3280 inline typename EnableIf< IsNumeric<Other>, SparseColumn<MT,false,false> >::Type&
3281  SparseColumn<MT,false,false>::operator/=( Other rhs )
3282 {
3284 
3285  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3286 
3287  typedef typename DivTrait<ElementType,Other>::Type DT;
3288  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
3289 
3290  // Depending on the two involved data types, an integer division is applied or a
3291  // floating point division is selected.
3292  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
3293  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
3294  for( Iterator element=begin(); element!=end(); ++element )
3295  element->value() *= tmp;
3296  }
3297  else {
3298  for( Iterator element=begin(); element!=end(); ++element )
3299  element->value() /= rhs;
3300  }
3301 
3302  return *this;
3303 }
3305 //*************************************************************************************************
3306 
3307 
3308 
3309 
3310 //=================================================================================================
3311 //
3312 // UTILITY FUNCTIONS
3313 //
3314 //=================================================================================================
3315 
3316 //*************************************************************************************************
3322 template< typename MT > // Type of the sparse matrix
3323 inline size_t SparseColumn<MT,false,false>::size() const
3324 {
3325  return matrix_.rows();
3326 }
3328 //*************************************************************************************************
3329 
3330 
3331 //*************************************************************************************************
3337 template< typename MT > // Type of the sparse matrix
3338 inline size_t SparseColumn<MT,false,false>::capacity() const
3339 {
3340  return matrix_.rows();
3341 }
3343 //*************************************************************************************************
3344 
3345 
3346 //*************************************************************************************************
3355 template< typename MT > // Type of the sparse matrix
3356 inline size_t SparseColumn<MT,false,false>::nonZeros() const
3357 {
3358  size_t counter( 0UL );
3359  for( ConstIterator element=begin(); element!=end(); ++element ) {
3360  ++counter;
3361  }
3362  return counter;
3363 }
3365 //*************************************************************************************************
3366 
3367 
3368 //*************************************************************************************************
3374 template< typename MT > // Type of the sparse matrix
3376 {
3377  const size_t ibegin( ( IsLower<MT>::value )
3378  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3379  ?( col_+1UL )
3380  :( col_ ) )
3381  :( 0UL ) );
3382  const size_t iend ( ( IsUpper<MT>::value )
3383  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3384  ?( col_ )
3385  :( col_+1UL ) )
3386  :( size() ) );
3387 
3388  for( size_t i=ibegin; i<iend; ++i ) {
3389  matrix_.erase( i, col_ );
3390  }
3391 }
3393 //*************************************************************************************************
3394 
3395 
3396 //*************************************************************************************************
3408 template< typename MT > // Type of the sparse matrix
3410  SparseColumn<MT,false,false>::set( size_t index, const ElementType& value )
3411 {
3412  return Iterator( matrix_, index, col_, matrix_.set( index, col_, value ) );
3413 }
3415 //*************************************************************************************************
3416 
3417 
3418 //*************************************************************************************************
3431 template< typename MT > // Type of the sparse matrix
3433  SparseColumn<MT,false,false>::insert( size_t index, const ElementType& value )
3434 {
3435  return Iterator( matrix_, index, col_, matrix_.insert( index, col_, value ) );
3436 }
3438 //*************************************************************************************************
3439 
3440 
3441 //*************************************************************************************************
3450 template< typename MT > // Type of the sparse matrix
3451 inline void SparseColumn<MT,false,false>::erase( size_t index )
3452 {
3453  matrix_.erase( index, col_ );
3454 }
3456 //*************************************************************************************************
3457 
3458 
3459 //*************************************************************************************************
3468 template< typename MT > // Type of the sparse matrix
3471 {
3472  const size_t row( pos.row_ );
3473 
3474  if( row == size() )
3475  return pos;
3476 
3477  matrix_.erase( row, pos.pos_ );
3478  return Iterator( matrix_, row+1UL, col_ );
3479 }
3481 //*************************************************************************************************
3482 
3483 
3484 //*************************************************************************************************
3494 template< typename MT > // Type of the sparse matrix
3497 {
3498  for( ; first!=last; ++first ) {
3499  matrix_.erase( first.row_, first.pos_ );
3500  }
3501  return last;
3502 }
3504 //*************************************************************************************************
3505 
3506 
3507 //*************************************************************************************************
3517 template< typename MT > // Type of the sparse matrix
3519 {
3520  UNUSED_PARAMETER( n );
3521 
3522  return;
3523 }
3525 //*************************************************************************************************
3526 
3527 
3528 //*************************************************************************************************
3539 template< typename MT > // Type of the sparse matrix
3540 template< typename Other > // Data type of the scalar value
3541 inline SparseColumn<MT,false,false>& SparseColumn<MT,false,false>::scale( const Other& scalar )
3542 {
3544 
3545  for( Iterator element=begin(); element!=end(); ++element )
3546  element->value() *= scalar;
3547  return *this;
3548 }
3550 //*************************************************************************************************
3551 
3552 
3553 //*************************************************************************************************
3565 template< typename MT > // Type of the sparse matrix
3566 template< typename MT2 // Type of the left-hand side sparse matrix
3567  , bool SO2 // Storage order of the left-hand side sparse matrix
3568  , typename VT > // Type of the right-hand side vector
3569 inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
3570  SparseColumn<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,false>& rhs )
3571 {
3572  UNUSED_PARAMETER( lhs, rhs );
3573 
3574  return true;
3575 }
3577 //*************************************************************************************************
3578 
3579 
3580 //*************************************************************************************************
3592 template< typename MT > // Type of the sparse matrix
3593 template< typename MT2 // Type of the left-hand side sparse matrix
3594  , bool SO2 // Storage order of the left-hand side sparse matrix
3595  , typename VT > // Type of the right-hand side dense vector
3596 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3597  SparseColumn<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs )
3598 {
3600 
3601  UNUSED_PARAMETER( lhs );
3602 
3603  const size_t iend( ( IsStrictlyLower<MT2>::value )?( col_+1UL ):( col_ ) );
3604 
3605  for( size_t i=0UL; i<iend; ++i ) {
3606  if( !isDefault( (~rhs)[i] ) )
3607  return false;
3608  }
3609 
3610  if( IsUniLower<MT2>::value && !isOne( (~rhs)[col_] ) )
3611  return false;
3612 
3613  return true;
3614 }
3616 //*************************************************************************************************
3617 
3618 
3619 //*************************************************************************************************
3631 template< typename MT > // Type of the sparse matrix
3632 template< typename MT2 // Type of the left-hand side sparse matrix
3633  , bool SO2 // Storage order of the left-hand side sparse matrix
3634  , typename VT > // Type of the right-hand side sparse vector
3635 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3636  SparseColumn<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs )
3637 {
3639 
3640  UNUSED_PARAMETER( lhs );
3641 
3642  typedef typename VT::ConstIterator RhsIterator;
3643 
3644  const RhsIterator last( (~rhs).lowerBound( ( IsStrictlyLower<MT2>::value )?( col_+1UL ):( col_ ) ) );
3645 
3646  if( IsUniLower<MT2>::value && ( last == (~rhs).end() || last->index() != col_ || !isOne( last->value() ) ) )
3647  return false;
3648 
3649  for( RhsIterator element=(~rhs).begin(); element!=last; ++element ) {
3650  if( !isDefault( element->value() ) )
3651  return false;
3652  }
3653 
3654  return true;
3655 }
3657 //*************************************************************************************************
3658 
3659 
3660 //*************************************************************************************************
3672 template< typename MT > // Type of the sparse matrix
3673 template< typename MT2 // Type of the left-hand side sparse matrix
3674  , bool SO2 // Storage order of the left-hand side sparse matrix
3675  , typename VT > // Type of the right-hand side dense vector
3676 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3677  SparseColumn<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs )
3678 {
3680 
3681  UNUSED_PARAMETER( lhs );
3682 
3683  if( IsUniUpper<MT2>::value && !isOne( (~rhs)[col_] ) )
3684  return false;
3685 
3686  const size_t ibegin( ( IsStrictlyUpper<MT2>::value )?( col_ ):( col_+1UL ) );
3687 
3688  for( size_t i=ibegin; i<size(); ++i ) {
3689  if( !isDefault( (~rhs)[i] ) )
3690  return false;
3691  }
3692 
3693  return true;
3694 }
3696 //*************************************************************************************************
3697 
3698 
3699 //*************************************************************************************************
3711 template< typename MT > // Type of the sparse matrix
3712 template< typename MT2 // Type of the left-hand side sparse matrix
3713  , bool SO2 // Storage order of the left-hand side sparse matrix
3714  , typename VT > // Type of the right-hand side sparse vector
3715 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
3716  SparseColumn<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs )
3717 {
3719 
3720  UNUSED_PARAMETER( lhs );
3721 
3722  typedef typename VT::ConstIterator RhsIterator;
3723 
3724  const bool checkDiagonal( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value );
3725  const RhsIterator last( (~rhs).end() );
3726  RhsIterator element( (~rhs).lowerBound( ( checkDiagonal )?( col_ ):( col_+1UL ) ) );
3727 
3728  if( IsUniUpper<MT2>::value ) {
3729  if( element == last || element->index() != col_ || !isOne( element->value() ) )
3730  return false;
3731  ++element;
3732  }
3733 
3734  for( ; element!=last; ++element ) {
3735  if( !isDefault( element->value() ) )
3736  return false;
3737  }
3738 
3739  return true;
3740 }
3742 //*************************************************************************************************
3743 
3744 
3745 //*************************************************************************************************
3757 template< typename MT > // Type of the sparse matrix
3758 template< typename MT2 // Type of the left-hand side sparse matrix
3759  , bool SO2 // Storage order of the left-hand side sparse matrix
3760  , typename VT > // Type of the right-hand side dense vector
3761 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
3762  SparseColumn<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs )
3763 {
3765 
3766  UNUSED_PARAMETER( lhs );
3767 
3768  for( size_t i=0UL; i<col_; ++i ) {
3769  if( !isDefault( (~rhs)[i] ) )
3770  return false;
3771  }
3772 
3773  for( size_t i=col_+1UL; i<size(); ++i ) {
3774  if( !isDefault( (~rhs)[i] ) )
3775  return false;
3776  }
3777 
3778  return true;
3779 }
3781 //*************************************************************************************************
3782 
3783 
3784 //*************************************************************************************************
3796 template< typename MT > // Type of the sparse matrix
3797 template< typename MT2 // Type of the left-hand side sparse matrix
3798  , bool SO2 // Storage order of the left-hand side sparse matrix
3799  , typename VT > // Type of the right-hand side sparse vector
3800 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
3801  SparseColumn<MT,false,false>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs )
3802 {
3804 
3805  UNUSED_PARAMETER( lhs );
3806 
3807  typedef typename VT::ConstIterator RhsIterator;
3808 
3809  for( RhsIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
3810  if( element->index() != col_ && !isDefault( element->value() ) )
3811  return false;
3812  }
3813 
3814  return true;
3815 }
3817 //*************************************************************************************************
3818 
3819 
3820 
3821 
3822 //=================================================================================================
3823 //
3824 // LOOKUP FUNCTIONS
3825 //
3826 //=================================================================================================
3827 
3828 //*************************************************************************************************
3842 template< typename MT > // Type of the sparse matrix
3844  SparseColumn<MT,false,false>::find( size_t index )
3845 {
3846  const typename MT::Iterator pos( matrix_.find( index, col_ ) );
3847 
3848  if( pos != matrix_.end( index ) )
3849  return Iterator( matrix_, index, col_, pos );
3850  else
3851  return end();
3852 }
3854 //*************************************************************************************************
3855 
3856 
3857 //*************************************************************************************************
3871 template< typename MT > // Type of the sparse matrix
3873  SparseColumn<MT,false,false>::find( size_t index ) const
3874 {
3875  const typename MT::ConstIterator pos( matrix_.find( index, col_ ) );
3876 
3877  if( pos != matrix_.end( index ) )
3878  return ConstIterator( matrix_, index, col_, pos );
3879  else
3880  return end();
3881 }
3883 //*************************************************************************************************
3884 
3885 
3886 //*************************************************************************************************
3899 template< typename MT > // Type of the sparse matrix
3902 {
3903  for( size_t i=index; i<size(); ++i )
3904  {
3905  const typename MT::Iterator pos( matrix_.find( i, col_ ) );
3906 
3907  if( pos != matrix_.end( i ) )
3908  return Iterator( matrix_, i, col_, pos );
3909  }
3910 
3911  return end();
3912 }
3914 //*************************************************************************************************
3915 
3916 
3917 //*************************************************************************************************
3930 template< typename MT > // Type of the sparse matrix
3932  SparseColumn<MT,false,false>::lowerBound( size_t index ) const
3933 {
3934  for( size_t i=index; i<size(); ++i )
3935  {
3936  const typename MT::ConstIterator pos( matrix_.find( i, col_ ) );
3937 
3938  if( pos != matrix_.end( i ) )
3939  return ConstIterator( matrix_, i, col_, pos );
3940  }
3941 
3942  return end();
3943 }
3945 //*************************************************************************************************
3946 
3947 
3948 //*************************************************************************************************
3961 template< typename MT > // Type of the sparse matrix
3964 {
3965  for( size_t i=index+1UL; i<size(); ++i )
3966  {
3967  const typename MT::Iterator pos( matrix_.find( i, col_ ) );
3968 
3969  if( pos != matrix_.end( i ) )
3970  return Iterator( matrix_, i, col_, pos );
3971  }
3972 
3973  return end();
3974 }
3976 //*************************************************************************************************
3977 
3978 
3979 //*************************************************************************************************
3992 template< typename MT > // Type of the sparse matrix
3994  SparseColumn<MT,false,false>::upperBound( size_t index ) const
3995 {
3996  for( size_t i=index+1UL; i<size(); ++i )
3997  {
3998  const typename MT::ConstIterator pos( matrix_.find( i, col_ ) );
3999 
4000  if( pos != matrix_.end( i ) )
4001  return ConstIterator( matrix_, i, col_, pos );
4002  }
4003 
4004  return end();
4005 }
4007 //*************************************************************************************************
4008 
4009 
4010 
4011 
4012 //=================================================================================================
4013 //
4014 // LOW-LEVEL UTILITY FUNCTIONS
4015 //
4016 //=================================================================================================
4017 
4018 //*************************************************************************************************
4043 template< typename MT > // Type of the sparse matrix
4044 inline void SparseColumn<MT,false,false>::append( size_t index, const ElementType& value, bool check )
4045 {
4046  if( !check || !isDefault( value ) )
4047  matrix_.insert( index, col_, value );
4048 }
4050 //*************************************************************************************************
4051 
4052 
4053 
4054 
4055 //=================================================================================================
4056 //
4057 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4058 //
4059 //=================================================================================================
4060 
4061 //*************************************************************************************************
4072 template< typename MT > // Type of the sparse matrix
4073 template< typename Other > // Data type of the foreign expression
4074 inline bool SparseColumn<MT,false,false>::canAlias( const Other* alias ) const
4075 {
4076  return matrix_.isAliased( alias );
4077 }
4079 //*************************************************************************************************
4080 
4081 
4082 //*************************************************************************************************
4089 template< typename MT > // Type of the sparse matrix
4090 template< typename Other > // Data type of the foreign expression
4091 inline bool SparseColumn<MT,false,false>::isAliased( const Other* alias ) const
4092 {
4093  return matrix_.isAliased( alias );
4094 }
4096 //*************************************************************************************************
4097 
4098 
4099 //*************************************************************************************************
4111 template< typename MT > // Type of the sparse matrix
4112 template< typename VT > // Type of the right-hand side dense vector
4113 inline void SparseColumn<MT,false,false>::assign( const DenseVector<VT,false>& rhs )
4114 {
4116 
4117  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4118 
4119  for( size_t i=0UL; i<(~rhs).size(); ++i ) {
4120  matrix_(i,col_) = (~rhs)[i];
4121  }
4122 }
4124 //*************************************************************************************************
4125 
4126 
4127 //*************************************************************************************************
4139 template< typename MT > // Type of the sparse matrix
4140 template< typename VT > // Type of the right-hand side sparse vector
4141 inline void SparseColumn<MT,false,false>::assign( const SparseVector<VT,false>& rhs )
4142 {
4144 
4145  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4146 
4147  size_t i( 0UL );
4148 
4149  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
4150  for( ; i<element->index(); ++i )
4151  matrix_.erase( i, col_ );
4152  matrix_(i++,col_) = element->value();
4153  }
4154  for( ; i<size(); ++i ) {
4155  matrix_.erase( i, col_ );
4156  }
4157 }
4159 //*************************************************************************************************
4160 
4161 
4162 //*************************************************************************************************
4174 template< typename MT > // Type of the sparse matrix
4175 template< typename VT > // Type of the right-hand side vector
4176 inline void SparseColumn<MT,false,false>::addAssign( const Vector<VT,false>& rhs )
4177 {
4179 
4180  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
4181 
4184 
4185  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4186 
4187  const AddType tmp( serial( *this + (~rhs) ) );
4188  assign( tmp );
4189 }
4191 //*************************************************************************************************
4192 
4193 
4194 //*************************************************************************************************
4206 template< typename MT > // Type of the sparse matrix
4207 template< typename VT > // Type of the right-hand side vector
4208 inline void SparseColumn<MT,false,false>::subAssign( const Vector<VT,false>& rhs )
4209 {
4211 
4212  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
4213 
4216 
4217  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4218 
4219  const SubType tmp( serial( *this - (~rhs) ) );
4220  assign( tmp );
4221 }
4223 //*************************************************************************************************
4224 
4225 
4226 
4227 
4228 
4229 
4230 
4231 
4232 //=================================================================================================
4233 //
4234 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR MATRICES
4235 //
4236 //=================================================================================================
4237 
4238 //*************************************************************************************************
4246 template< typename MT > // Type of the sparse matrix
4247 class SparseColumn<MT,false,true> : public SparseVector< SparseColumn<MT,false,true>, false >
4248  , private Column
4249 {
4250  private:
4251  //**Type definitions****************************************************************************
4253  typedef typename If< IsExpression<MT>, MT, MT& >::Type Operand;
4254  //**********************************************************************************************
4255 
4256  //**********************************************************************************************
4258 
4264  enum { useConst = IsConst<MT>::value };
4265  //**********************************************************************************************
4266 
4267  public:
4268  //**Type definitions****************************************************************************
4269  typedef SparseColumn<MT,false,true> This;
4270  typedef typename ColumnTrait<MT>::Type ResultType;
4271  typedef typename ResultType::TransposeType TransposeType;
4272  typedef typename MT::ElementType ElementType;
4273  typedef typename MT::ReturnType ReturnType;
4274  typedef const SparseColumn& CompositeType;
4275 
4277  typedef typename MT::ConstReference ConstReference;
4278 
4280  typedef typename IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference;
4281 
4283  typedef typename MT::ConstIterator ConstIterator;
4284 
4286  typedef typename IfTrue< useConst, ConstIterator, typename MT::Iterator >::Type Iterator;
4287  //**********************************************************************************************
4288 
4289  //**Compilation flags***************************************************************************
4291  enum { smpAssignable = 0 };
4292  //**********************************************************************************************
4293 
4294  //**Constructors********************************************************************************
4297  explicit inline SparseColumn( MT& matrix, size_t index );
4298  // No explicitly declared copy constructor.
4300  //**********************************************************************************************
4301 
4302  //**Destructor**********************************************************************************
4303  // No explicitly declared destructor.
4304  //**********************************************************************************************
4305 
4306  //**Data access functions***********************************************************************
4309  inline Reference operator[]( size_t index );
4310  inline ConstReference operator[]( size_t index ) const;
4311  inline Iterator begin ();
4312  inline ConstIterator begin () const;
4313  inline ConstIterator cbegin() const;
4314  inline Iterator end ();
4315  inline ConstIterator end () const;
4316  inline ConstIterator cend () const;
4318  //**********************************************************************************************
4319 
4320  //**Assignment operators************************************************************************
4323  inline SparseColumn& operator=( const SparseColumn& rhs );
4324 
4325  template< typename VT > inline SparseColumn& operator= ( const DenseVector<VT,false>& rhs );
4326  template< typename VT > inline SparseColumn& operator= ( const SparseVector<VT,false>& rhs );
4327  template< typename VT > inline SparseColumn& operator+=( const DenseVector<VT,false>& rhs );
4328  template< typename VT > inline SparseColumn& operator+=( const SparseVector<VT,false>& rhs );
4329  template< typename VT > inline SparseColumn& operator-=( const DenseVector<VT,false>& rhs );
4330  template< typename VT > inline SparseColumn& operator-=( const SparseVector<VT,false>& rhs );
4331  template< typename VT > inline SparseColumn& operator*=( const Vector<VT,false>& rhs );
4332 
4333  template< typename Other >
4334  inline typename EnableIf< IsNumeric<Other>, SparseColumn >::Type&
4335  operator*=( Other rhs );
4336 
4337  template< typename Other >
4338  inline typename EnableIf< IsNumeric<Other>, SparseColumn >::Type&
4339  operator/=( Other rhs );
4341  //**********************************************************************************************
4342 
4343  //**Utility functions***************************************************************************
4346  inline size_t size() const;
4347  inline size_t capacity() const;
4348  inline size_t nonZeros() const;
4349  inline void reset();
4350  inline Iterator set ( size_t index, const ElementType& value );
4351  inline Iterator insert ( size_t index, const ElementType& value );
4352  inline void erase ( size_t index );
4353  inline Iterator erase ( Iterator pos );
4354  inline Iterator erase ( Iterator first, Iterator last );
4355  inline void reserve( size_t n );
4356  template< typename Other > inline SparseColumn& scale ( const Other& scalar );
4358  //**********************************************************************************************
4359 
4360  //**Lookup functions****************************************************************************
4363  inline Iterator find ( size_t index );
4364  inline ConstIterator find ( size_t index ) const;
4365  inline Iterator lowerBound( size_t index );
4366  inline ConstIterator lowerBound( size_t index ) const;
4367  inline Iterator upperBound( size_t index );
4368  inline ConstIterator upperBound( size_t index ) const;
4370  //**********************************************************************************************
4371 
4372  //**Low-level utility functions*****************************************************************
4375  inline void append( size_t index, const ElementType& value, bool check=false );
4377  //**********************************************************************************************
4378 
4379  //**Expression template evaluation functions****************************************************
4382  template< typename Other > inline bool canAlias ( const Other* alias ) const;
4383  template< typename Other > inline bool isAliased( const Other* alias ) const;
4384 
4385  template< typename VT > inline void assign ( const DenseVector <VT,false>& rhs );
4386  template< typename VT > inline void assign ( const SparseVector<VT,false>& rhs );
4387  template< typename VT > inline void addAssign( const DenseVector <VT,false>& rhs );
4388  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
4389  template< typename VT > inline void subAssign( const DenseVector <VT,false>& rhs );
4390  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
4392  //**********************************************************************************************
4393 
4394  private:
4395  //**Utility functions***************************************************************************
4398  inline size_t extendCapacity() const;
4399 
4400  template< typename MT2, bool SO2, typename VT >
4401  inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
4402  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,false>& rhs );
4403 
4404  template< typename MT2, bool SO2, typename VT >
4405  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4406  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs );
4407 
4408  template< typename MT2, bool SO2, typename VT >
4409  inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4410  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs );
4411 
4412  template< typename MT2, bool SO2, typename VT >
4413  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4414  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs );
4415 
4416  template< typename MT2, bool SO2, typename VT >
4417  inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
4418  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs );
4419 
4420  template< typename MT2, bool SO2, typename VT >
4421  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4422  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs );
4423 
4424  template< typename MT2, bool SO2, typename VT >
4425  inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
4426  preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs );
4428  //**********************************************************************************************
4429 
4430  //**Member variables****************************************************************************
4433  Operand matrix_;
4434  const size_t col_;
4435 
4436  //**********************************************************************************************
4437 
4438  //**Friend declarations*************************************************************************
4439  template< typename MT2, bool SO2, bool SF2 >
4440  friend bool isSame( const SparseColumn<MT2,SO2,SF2>& a, const SparseColumn<MT2,SO2,SF2>& b );
4441 
4442  template< typename MT2, bool SO2, bool SF2 >
4443  friend typename DerestrictTrait< SparseColumn<MT2,SO2,SF2> >::Type
4444  derestrict( SparseColumn<MT2,SO2,SF2>& dm );
4445  //**********************************************************************************************
4446 
4447  //**Compile time checks*************************************************************************
4455  BLAZE_STATIC_ASSERT( !IsRestricted<MT>::value || IsLower<MT>::value || IsUpper<MT>::value );
4456  //**********************************************************************************************
4457 };
4459 //*************************************************************************************************
4460 
4461 
4462 
4463 
4464 //=================================================================================================
4465 //
4466 // CONSTRUCTOR
4467 //
4468 //=================================================================================================
4469 
4470 //*************************************************************************************************
4478 template< typename MT > // Type of the sparse matrix
4479 inline SparseColumn<MT,false,true>::SparseColumn( MT& matrix, size_t index )
4480  : matrix_( matrix ) // The sparse matrix containing the column
4481  , col_ ( index ) // The index of the column in the matrix
4482 {
4483  if( matrix_.columns() <= index )
4484  throw std::invalid_argument( "Invalid column access index" );
4485 }
4487 //*************************************************************************************************
4488 
4489 
4490 
4491 
4492 //=================================================================================================
4493 //
4494 // DATA ACCESS FUNCTIONS
4495 //
4496 //=================================================================================================
4497 
4498 //*************************************************************************************************
4505 template< typename MT > // Type of the sparse matrix
4508 {
4509  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4510  return matrix_(col_,index);
4511 }
4513 //*************************************************************************************************
4514 
4515 
4516 //*************************************************************************************************
4523 template< typename MT > // Type of the sparse matrix
4525  SparseColumn<MT,false,true>::operator[]( size_t index ) const
4526 {
4527  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4528  return const_cast<const MT&>( matrix_ )(col_,index);
4529 }
4531 //*************************************************************************************************
4532 
4533 
4534 //*************************************************************************************************
4542 template< typename MT > // Type of the sparse matrix
4544 {
4545  return matrix_.begin( col_ );
4546 }
4548 //*************************************************************************************************
4549 
4550 
4551 //*************************************************************************************************
4559 template< typename MT > // Type of the sparse matrix
4562 {
4563  return matrix_.cbegin( col_ );
4564 }
4566 //*************************************************************************************************
4567 
4568 
4569 //*************************************************************************************************
4577 template< typename MT > // Type of the sparse matrix
4580 {
4581  return matrix_.cbegin( col_ );
4582 }
4584 //*************************************************************************************************
4585 
4586 
4587 //*************************************************************************************************
4595 template< typename MT > // Type of the sparse matrix
4597 {
4598  return matrix_.end( col_ );
4599 }
4601 //*************************************************************************************************
4602 
4603 
4604 //*************************************************************************************************
4612 template< typename MT > // Type of the sparse matrix
4615 {
4616  return matrix_.cend( col_ );
4617 }
4619 //*************************************************************************************************
4620 
4621 
4622 //*************************************************************************************************
4630 template< typename MT > // Type of the sparse matrix
4633 {
4634  return matrix_.cend( col_ );
4635 }
4637 //*************************************************************************************************
4638 
4639 
4640 
4641 
4642 //=================================================================================================
4643 //
4644 // ASSIGNMENT OPERATORS
4645 //
4646 //=================================================================================================
4647 
4648 //*************************************************************************************************
4662 template< typename MT > // Type of the sparse matrix
4663 inline SparseColumn<MT,false,true>& SparseColumn<MT,false,true>::operator=( const SparseColumn& rhs )
4664 {
4665  using blaze::assign;
4666 
4670 
4671  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && col_ == rhs.col_ ) )
4672  return *this;
4673 
4674  if( size() != rhs.size() )
4675  throw std::invalid_argument( "Column sizes do not match" );
4676 
4677  if( !preservesInvariant( matrix_, rhs ) )
4678  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4679 
4680  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4681 
4682  if( rhs.canAlias( &matrix_ ) ) {
4683  const ResultType tmp( rhs );
4684  left.reset();
4685  left.reserve( tmp.nonZeros() );
4686  assign( left, tmp );
4687  }
4688  else {
4689  left.reset();
4690  left.reserve( rhs.nonZeros() );
4691  assign( left, rhs );
4692  }
4693 
4694  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4695  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4696 
4697  return *this;
4698 }
4700 //*************************************************************************************************
4701 
4702 
4703 //*************************************************************************************************
4717 template< typename MT > // Type of the sparse matrix
4718 template< typename VT > // Type of the right-hand side dense vector
4719 inline SparseColumn<MT,false,true>&
4720  SparseColumn<MT,false,true>::operator=( const DenseVector<VT,false>& rhs )
4721 {
4722  using blaze::assign;
4723 
4727 
4728  if( size() != (~rhs).size() )
4729  throw std::invalid_argument( "Vector sizes do not match" );
4730 
4731  typedef typename If< IsRestricted<MT>, typename VT::CompositeType, const VT& >::Type Right;
4732  Right right( ~rhs );
4733 
4734  if( !preservesInvariant( matrix_, right ) )
4735  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4736 
4737  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4738 
4739  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4740  const typename VT::ResultType tmp( right );
4741  left.reset();
4742  assign( left, tmp );
4743  }
4744  else {
4745  left.reset();
4746  assign( left, right );
4747  }
4748 
4749  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4750  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4751 
4752  return *this;
4753 }
4755 //*************************************************************************************************
4756 
4757 
4758 //*************************************************************************************************
4772 template< typename MT > // Type of the sparse matrix
4773 template< typename VT > // Type of the right-hand side sparse vector
4774 inline SparseColumn<MT,false,true>&
4775  SparseColumn<MT,false,true>::operator=( const SparseVector<VT,false>& rhs )
4776 {
4777  using blaze::assign;
4778 
4782 
4783  if( size() != (~rhs).size() )
4784  throw std::invalid_argument( "Vector sizes do not match" );
4785 
4786  typedef typename If< IsRestricted<MT>, typename VT::CompositeType, const VT& >::Type Right;
4787  Right right( ~rhs );
4788 
4789  if( !preservesInvariant( matrix_, right ) )
4790  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4791 
4792  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4793 
4794  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4795  const typename VT::ResultType tmp( right);
4796  left.reset();
4797  left.reserve( tmp.nonZeros() );
4798  assign( left, tmp );
4799  }
4800  else {
4801  left.reset();
4802  left.reserve( right.nonZeros() );
4803  assign( left, right );
4804  }
4805 
4806  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4807  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4808 
4809  return *this;
4810 }
4812 //*************************************************************************************************
4813 
4814 
4815 //*************************************************************************************************
4829 template< typename MT > // Type of the sparse matrix
4830 template< typename VT > // Type of the right-hand side dense vector
4831 inline SparseColumn<MT,false,true>&
4832  SparseColumn<MT,false,true>::operator+=( const DenseVector<VT,false>& rhs )
4833 {
4834  using blaze::assign;
4835 
4842 
4843  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
4844 
4848 
4849  if( size() != (~rhs).size() )
4850  throw std::invalid_argument( "Vector sizes do not match" );
4851 
4852  const AddType tmp( *this + (~rhs) );
4853 
4854  if( !preservesInvariant( matrix_, tmp ) )
4855  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4856 
4857  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4858 
4859  left.reset();
4860  assign( left, tmp );
4861 
4862  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4863  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4864 
4865  return *this;
4866 }
4868 //*************************************************************************************************
4869 
4870 
4871 //*************************************************************************************************
4885 template< typename MT > // Type of the sparse matrix
4886 template< typename VT > // Type of the right-hand side sparse vector
4887 inline SparseColumn<MT,false,true>&
4888  SparseColumn<MT,false,true>::operator+=( const SparseVector<VT,false>& rhs )
4889 {
4890  using blaze::assign;
4891 
4898 
4899  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
4900 
4904 
4905  if( size() != (~rhs).size() )
4906  throw std::invalid_argument( "Vector sizes do not match" );
4907 
4908  const AddType tmp( *this + (~rhs) );
4909 
4910  if( !preservesInvariant( matrix_, tmp ) )
4911  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4912 
4913  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4914 
4915  left.reset();
4916  left.reserve( tmp.nonZeros() );
4917  assign( left, tmp );
4918 
4919  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4920  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4921 
4922  return *this;
4923 }
4925 //*************************************************************************************************
4926 
4927 
4928 //*************************************************************************************************
4943 template< typename MT > // Type of the sparse matrix
4944 template< typename VT > // Type of the right-hand side dense vector
4945 inline SparseColumn<MT,false,true>&
4946  SparseColumn<MT,false,true>::operator-=( const DenseVector<VT,false>& rhs )
4947 {
4948  using blaze::assign;
4949 
4956 
4957  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
4958 
4962 
4963  if( size() != (~rhs).size() )
4964  throw std::invalid_argument( "Vector sizes do not match" );
4965 
4966  const SubType tmp( *this - (~rhs) );
4967 
4968  if( !preservesInvariant( matrix_, tmp ) )
4969  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
4970 
4971  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
4972 
4973  left.reset();
4974  assign( left, tmp );
4975 
4976  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
4977  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
4978 
4979  return *this;
4980 }
4982 //*************************************************************************************************
4983 
4984 
4985 //*************************************************************************************************
5000 template< typename MT > // Type of the sparse matrix
5001 template< typename VT > // Type of the right-hand side sparse vector
5002 inline SparseColumn<MT,false,true>&
5003  SparseColumn<MT,false,true>::operator-=( const SparseVector<VT,false>& rhs )
5004 {
5005  using blaze::assign;
5006 
5013 
5014  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
5015 
5019 
5020  if( size() != (~rhs).size() )
5021  throw std::invalid_argument( "Vector sizes do not match" );
5022 
5023  const SubType tmp( *this - (~rhs) );
5024 
5025  if( !preservesInvariant( matrix_, tmp ) )
5026  throw std::invalid_argument( "Invalid assignment to restricted matrix" );
5027 
5028  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5029 
5030  left.reset();
5031  left.reserve( tmp.nonZeros() );
5032  assign( left, tmp );
5033 
5034  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
5035  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
5036 
5037  return *this;
5038 }
5040 //*************************************************************************************************
5041 
5042 
5043 //*************************************************************************************************
5055 template< typename MT > // Type of the sparse matrix
5056 template< typename VT > // Type of the right-hand side vector
5057 inline SparseColumn<MT,false,true>&
5058  SparseColumn<MT,false,true>::operator*=( const Vector<VT,false>& rhs )
5059 {
5060  using blaze::assign;
5061 
5067 
5068  typedef typename MultTrait<ResultType,typename VT::ResultType>::Type MultType;
5069 
5072 
5073  if( size() != (~rhs).size() )
5074  throw std::invalid_argument( "Vector sizes do not match" );
5075 
5076  typename DerestrictTrait<This>::Type left( derestrict( *this ) );
5077 
5078  const MultType tmp( *this * (~rhs) );
5079  left.reset();
5080  assign( left, tmp );
5081 
5082  BLAZE_INTERNAL_ASSERT( !IsLower<MT>::value || isLower( derestrict( matrix_ ) ), "Lower violation detected" );
5083  BLAZE_INTERNAL_ASSERT( !IsUpper<MT>::value || isUpper( derestrict( matrix_ ) ), "Upper violation detected" );
5084 
5085  return *this;
5086 }
5088 //*************************************************************************************************
5089 
5090 
5091 //*************************************************************************************************
5106 template< typename MT > // Type of the sparse matrix
5107 template< typename Other > // Data type of the right-hand side scalar
5108 inline typename EnableIf< IsNumeric<Other>, SparseColumn<MT,false,true> >::Type&
5109  SparseColumn<MT,false,true>::operator*=( Other rhs )
5110 {
5112 
5113  for( Iterator element=begin(); element!=end(); ++element )
5114  element->value() *= rhs;
5115  return *this;
5116 }
5118 //*************************************************************************************************
5119 
5120 
5121 //*************************************************************************************************
5139 template< typename MT > // Type of the sparse matrix
5140 template< typename Other > // Data type of the right-hand side scalar
5141 inline typename EnableIf< IsNumeric<Other>, SparseColumn<MT,false,true> >::Type&
5142  SparseColumn<MT,false,true>::operator/=( Other rhs )
5143 {
5145 
5146  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
5147 
5148  typedef typename DivTrait<ElementType,Other>::Type DT;
5149  typedef typename If< IsNumeric<DT>, DT, Other >::Type Tmp;
5150 
5151  // Depending on the two involved data types, an integer division is applied or a
5152  // floating point division is selected.
5153  if( IsNumeric<DT>::value && IsFloatingPoint<DT>::value ) {
5154  const Tmp tmp( Tmp(1)/static_cast<Tmp>( rhs ) );
5155  for( Iterator element=begin(); element!=end(); ++element )
5156  element->value() *= tmp;
5157  }
5158  else {
5159  for( Iterator element=begin(); element!=end(); ++element )
5160  element->value() /= rhs;
5161  }
5162 
5163  return *this;
5164 }
5166 //*************************************************************************************************
5167 
5168 
5169 
5170 
5171 //=================================================================================================
5172 //
5173 // UTILITY FUNCTIONS
5174 //
5175 //=================================================================================================
5176 
5177 //*************************************************************************************************
5183 template< typename MT > // Type of the sparse matrix
5184 inline size_t SparseColumn<MT,false,true>::size() const
5185 {
5186  return matrix_.rows();
5187 }
5189 //*************************************************************************************************
5190 
5191 
5192 //*************************************************************************************************
5198 template< typename MT > // Type of the sparse matrix
5199 inline size_t SparseColumn<MT,false,true>::capacity() const
5200 {
5201  return matrix_.capacity( col_ );
5202 }
5204 //*************************************************************************************************
5205 
5206 
5207 //*************************************************************************************************
5216 template< typename MT > // Type of the sparse matrix
5217 inline size_t SparseColumn<MT,false,true>::nonZeros() const
5218 {
5219  return matrix_.nonZeros( col_ );
5220 }
5222 //*************************************************************************************************
5223 
5224 
5225 //*************************************************************************************************
5231 template< typename MT > // Type of the sparse matrix
5233 {
5234  matrix_.reset( col_ );
5235 }
5237 //*************************************************************************************************
5238 
5239 
5240 //*************************************************************************************************
5252 template< typename MT > // Type of the sparse matrix
5254  SparseColumn<MT,false,true>::set( size_t index, const ElementType& value )
5255 {
5256  return matrix_.set( col_, index, value );
5257 }
5259 //*************************************************************************************************
5260 
5261 
5262 //*************************************************************************************************
5275 template< typename MT > // Type of the sparse matrix
5277  SparseColumn<MT,false,true>::insert( size_t index, const ElementType& value )
5278 {
5279  return matrix_.insert( col_, index, value );
5280 }
5282 //*************************************************************************************************
5283 
5284 
5285 //*************************************************************************************************
5294 template< typename MT > // Type of the sparse matrix
5295 inline void SparseColumn<MT,false,true>::erase( size_t index )
5296 {
5297  matrix_.erase( col_, index );
5298 }
5300 //*************************************************************************************************
5301 
5302 
5303 //*************************************************************************************************
5312 template< typename MT > // Type of the sparse matrix
5315 {
5316  return matrix_.erase( col_, pos );
5317 }
5319 //*************************************************************************************************
5320 
5321 
5322 //*************************************************************************************************
5332 template< typename MT > // Type of the sparse matrix
5335 {
5336  return matrix_.erase( col_, first, last );
5337 }
5339 //*************************************************************************************************
5340 
5341 
5342 //*************************************************************************************************
5352 template< typename MT > // Type of the sparse matrix
5353 void SparseColumn<MT,false,true>::reserve( size_t n )
5354 {
5355  matrix_.reserve( col_, n );
5356 }
5358 //*************************************************************************************************
5359 
5360 
5361 //*************************************************************************************************
5372 template< typename MT > // Type of the sparse matrix
5373 template< typename Other > // Data type of the scalar value
5374 inline SparseColumn<MT,false,true>& SparseColumn<MT,false,true>::scale( const Other& scalar )
5375 {
5377 
5378  for( Iterator element=begin(); element!=end(); ++element )
5379  element->value() *= scalar;
5380  return *this;
5381 }
5383 //*************************************************************************************************
5384 
5385 
5386 //*************************************************************************************************
5395 template< typename MT > // Type of the sparse matrix
5396 inline size_t SparseColumn<MT,false,true>::extendCapacity() const
5397 {
5398  using blaze::max;
5399  using blaze::min;
5400 
5401  size_t nonzeros( 2UL*capacity()+1UL );
5402  nonzeros = max( nonzeros, 7UL );
5403  nonzeros = min( nonzeros, size() );
5404 
5405  BLAZE_INTERNAL_ASSERT( nonzeros > capacity(), "Invalid capacity value" );
5406 
5407  return nonzeros;
5408 }
5410 //*************************************************************************************************
5411 
5412 
5413 //*************************************************************************************************
5425 template< typename MT > // Type of the sparse matrix
5426 template< typename MT2 // Type of the left-hand side sparse matrix
5427  , bool SO2 // Storage order of the left-hand side sparse matrix
5428  , typename VT > // Type of the right-hand side vector
5429 inline typename EnableIf< Not< IsRestricted<MT2> >, bool >::Type
5430  SparseColumn<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const Vector<VT,false>& rhs )
5431 {
5432  UNUSED_PARAMETER( lhs, rhs );
5433 
5434  return true;
5435 }
5437 //*************************************************************************************************
5438 
5439 
5440 //*************************************************************************************************
5452 template< typename MT > // Type of the sparse matrix
5453 template< typename MT2 // Type of the left-hand side sparse matrix
5454  , bool SO2 // Storage order of the left-hand side sparse matrix
5455  , typename VT > // Type of the right-hand side dense vector
5456 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5457  SparseColumn<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs )
5458 {
5460 
5461  UNUSED_PARAMETER( lhs );
5462 
5463  const size_t iend( ( IsStrictlyLower<MT2>::value )?( col_+1UL ):( col_ ) );
5464 
5465  for( size_t i=0UL; i<iend; ++i ) {
5466  if( !isDefault( (~rhs)[i] ) )
5467  return false;
5468  }
5469 
5470  if( IsUniLower<MT2>::value && !isOne( (~rhs)[col_] ) )
5471  return false;
5472 
5473  return true;
5474 }
5476 //*************************************************************************************************
5477 
5478 
5479 //*************************************************************************************************
5491 template< typename MT > // Type of the sparse matrix
5492 template< typename MT2 // Type of the left-hand side sparse matrix
5493  , bool SO2 // Storage order of the left-hand side sparse matrix
5494  , typename VT > // Type of the right-hand side sparse vector
5495 inline typename EnableIf< And< IsLower<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5496  SparseColumn<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs )
5497 {
5499 
5500  UNUSED_PARAMETER( lhs );
5501 
5502  typedef typename VT::ConstIterator RhsIterator;
5503 
5504  const RhsIterator last( (~rhs).lowerBound( ( IsStrictlyLower<MT2>::value )?( col_+1UL ):( col_ ) ) );
5505 
5506  if( IsUniLower<MT2>::value && ( last == (~rhs).end() || last->index() != col_ || !isOne( last->value() ) ) )
5507  return false;
5508 
5509  for( RhsIterator element=(~rhs).begin(); element!=last; ++element ) {
5510  if( !isDefault( element->value() ) )
5511  return false;
5512  }
5513 
5514  return true;
5515 }
5517 //*************************************************************************************************
5518 
5519 
5520 //*************************************************************************************************
5532 template< typename MT > // Type of the sparse matrix
5533 template< typename MT2 // Type of the left-hand side sparse matrix
5534  , bool SO2 // Storage order of the left-hand side sparse matrix
5535  , typename VT > // Type of the right-hand side dense vector
5536 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5537  SparseColumn<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs )
5538 {
5540 
5541  UNUSED_PARAMETER( lhs );
5542 
5543  if( IsUniUpper<MT2>::value && !isOne( (~rhs)[col_] ) )
5544  return false;
5545 
5546  const size_t ibegin( ( IsStrictlyUpper<MT2>::value )?( col_ ):( col_+1UL ) );
5547 
5548  for( size_t i=ibegin; i<size(); ++i ) {
5549  if( !isDefault( (~rhs)[i] ) )
5550  return false;
5551  }
5552 
5553  return true;
5554 }
5556 //*************************************************************************************************
5557 
5558 
5559 //*************************************************************************************************
5571 template< typename MT > // Type of the sparse matrix
5572 template< typename MT2 // Type of the left-hand side sparse matrix
5573  , bool SO2 // Storage order of the left-hand side sparse matrix
5574  , typename VT > // Type of the right-hand side sparse vector
5575 inline typename EnableIf< And< IsUpper<MT2>, Not< IsDiagonal<MT2> > >, bool >::Type
5576  SparseColumn<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs )
5577 {
5579 
5580  UNUSED_PARAMETER( lhs );
5581 
5582  typedef typename VT::ConstIterator RhsIterator;
5583 
5584  const bool checkDiagonal( IsUniUpper<MT2>::value || IsStrictlyUpper<MT2>::value );
5585  const RhsIterator last( (~rhs).end() );
5586  RhsIterator element( (~rhs).lowerBound( ( checkDiagonal )?( col_ ):( col_+1UL ) ) );
5587 
5588  if( IsUniUpper<MT2>::value ) {
5589  if( element == last || element->index() != col_ || !isOne( element->value() ) )
5590  return false;
5591  ++element;
5592  }
5593 
5594  for( ; element!=last; ++element ) {
5595  if( !isDefault( element->value() ) )
5596  return false;
5597  }
5598 
5599  return true;
5600 }
5602 //*************************************************************************************************
5603 
5604 
5605 //*************************************************************************************************
5617 template< typename MT > // Type of the sparse matrix
5618 template< typename MT2 // Type of the left-hand side sparse matrix
5619  , bool SO2 // Storage order of the left-hand side sparse matrix
5620  , typename VT > // Type of the right-hand side dense vector
5621 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
5622  SparseColumn<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const DenseVector<VT,false>& rhs )
5623 {
5625 
5626  UNUSED_PARAMETER( lhs );
5627 
5628  for( size_t i=0UL; i<col_; ++i ) {
5629  if( !isDefault( (~rhs)[i] ) )
5630  return false;
5631  }
5632 
5633  for( size_t i=col_+1UL; i<size(); ++i ) {
5634  if( !isDefault( (~rhs)[i] ) )
5635  return false;
5636  }
5637 
5638  return true;
5639 }
5641 //*************************************************************************************************
5642 
5643 
5644 //*************************************************************************************************
5656 template< typename MT > // Type of the sparse matrix
5657 template< typename MT2 // Type of the left-hand side sparse matrix
5658  , bool SO2 // Storage order of the left-hand side sparse matrix
5659  , typename VT > // Type of the right-hand side sparse vector
5660 inline typename EnableIf< IsDiagonal<MT2>, bool >::Type
5661  SparseColumn<MT,false,true>::preservesInvariant( const SparseMatrix<MT2,SO2>& lhs, const SparseVector<VT,false>& rhs )
5662 {
5664 
5665  UNUSED_PARAMETER( lhs );
5666 
5667  typedef typename VT::ConstIterator RhsIterator;
5668 
5669  for( RhsIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
5670  if( element->index() != col_ && !isDefault( element->value() ) )
5671  return false;
5672  }
5673 
5674  return true;
5675 }
5677 //*************************************************************************************************
5678 
5679 
5680 
5681 
5682 //=================================================================================================
5683 //
5684 // LOOKUP FUNCTIONS
5685 //
5686 //=================================================================================================
5687 
5688 //*************************************************************************************************
5702 template< typename MT > // Type of the sparse matrix
5704  SparseColumn<MT,false,true>::find( size_t index )
5705 {
5706  return matrix_.find( col_, index );
5707 }
5709 //*************************************************************************************************
5710 
5711 
5712 //*************************************************************************************************
5726 template< typename MT > // Type of the sparse matrix
5728  SparseColumn<MT,false,true>::find( size_t index ) const
5729 {
5730  return matrix_.find( col_, index );
5731 }
5733 //*************************************************************************************************
5734 
5735 
5736 //*************************************************************************************************
5749 template< typename MT > // Type of the sparse matrix
5752 {
5753  return matrix_.lowerBound( col_, index );
5754 }
5756 //*************************************************************************************************
5757 
5758 
5759 //*************************************************************************************************
5772 template< typename MT > // Type of the sparse matrix
5774  SparseColumn<MT,false,true>::lowerBound( size_t index ) const
5775 {
5776  return matrix_.lowerBound( col_, index );
5777 }
5779 //*************************************************************************************************
5780 
5781 
5782 //*************************************************************************************************
5795 template< typename MT > // Type of the sparse matrix
5798 {
5799  return matrix_.upperBound( col_, index );
5800 }
5802 //*************************************************************************************************
5803 
5804 
5805 //*************************************************************************************************
5818 template< typename MT > // Type of the sparse matrix
5820  SparseColumn<MT,false,true>::upperBound( size_t index ) const
5821 {
5822  return matrix_.upperBound( col_, index );
5823 }
5825 //*************************************************************************************************
5826 
5827 
5828 
5829 
5830 //=================================================================================================
5831 //
5832 // LOW-LEVEL UTILITY FUNCTIONS
5833 //
5834 //=================================================================================================
5835 
5836 //*************************************************************************************************
5861 template< typename MT > // Type of the sparse matrix
5862 inline void SparseColumn<MT,false,true>::append( size_t index, const ElementType& value, bool check )
5863 {
5864  matrix_.append( col_, index, value, check );
5865 }
5867 //*************************************************************************************************
5868 
5869 
5870 
5871 
5872 //=================================================================================================
5873 //
5874 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5875 //
5876 //=================================================================================================
5877 
5878 //*************************************************************************************************
5889 template< typename MT > // Type of the sparse matrix
5890 template< typename Other > // Data type of the foreign expression
5891 inline bool SparseColumn<MT,false,true>::canAlias( const Other* alias ) const
5892 {
5893  return matrix_.isAliased( alias );
5894 }
5896 //*************************************************************************************************
5897 
5898 
5899 //*************************************************************************************************
5910 template< typename MT > // Type of the sparse matrix
5911 template< typename Other > // Data type of the foreign expression
5912 inline bool SparseColumn<MT,false,true>::isAliased( const Other* alias ) const
5913 {
5914  return matrix_.isAliased( alias );
5915 }
5917 //*************************************************************************************************
5918 
5919 
5920 //*************************************************************************************************
5932 template< typename MT > // Type of the sparse matrix
5933 template< typename VT > // Type of the right-hand side dense vector
5934 inline void SparseColumn<MT,false,true>::assign( const DenseVector<VT,false>& rhs )
5935 {
5937 
5938  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5939  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5940 
5941  for( size_t i=0UL; i<size(); ++i )
5942  {
5943  if( matrix_.nonZeros( col_ ) == matrix_.capacity( col_ ) )
5944  matrix_.reserve( col_, extendCapacity() );
5945 
5946  matrix_.append( col_, i, (~rhs)[i], true );
5947  }
5948 }
5950 //*************************************************************************************************
5951 
5952 
5953 //*************************************************************************************************
5965 template< typename MT > // Type of the sparse matrix
5966 template< typename VT > // Type of the right-hand side sparse vector
5967 inline void SparseColumn<MT,false,true>::assign( const SparseVector<VT,false>& rhs )
5968 {
5970 
5971  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5972  BLAZE_INTERNAL_ASSERT( nonZeros() == 0UL, "Invalid non-zero elements detected" );
5973 
5974  for( typename VT::ConstIterator element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
5975  matrix_.append( col_, element->index(), element->value(), true );
5976  }
5977 }
5979 //*************************************************************************************************
5980 
5981 
5982 //*************************************************************************************************
5994 template< typename MT > // Type of the sparse matrix
5995 template< typename VT > // Type of the right-hand side dense vector
5996 inline void SparseColumn<MT,false,true>::addAssign( const DenseVector<VT,false>& rhs )
5997 {
5999 
6000  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
6001 
6005 
6006  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6007 
6008  const AddType tmp( serial( *this + (~rhs) ) );
6009  matrix_.reset( col_ );
6010  assign( tmp );
6011 }
6013 //*************************************************************************************************
6014 
6015 
6016 //*************************************************************************************************
6028 template< typename MT > // Type of the sparse matrix
6029 template< typename VT > // Type of the right-hand side sparse vector
6030 inline void SparseColumn<MT,false,true>::addAssign( const SparseVector<VT,false>& rhs )
6031 {
6033 
6034  typedef typename AddTrait<ResultType,typename VT::ResultType>::Type AddType;
6035 
6039 
6040  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6041 
6042  const AddType tmp( serial( *this + (~rhs) ) );
6043  matrix_.reset( col_ );
6044  matrix_.reserve( col_, tmp.nonZeros() );
6045  assign( tmp );
6046 }
6048 //*************************************************************************************************
6049 
6050 
6051 //*************************************************************************************************
6063 template< typename MT > // Type of the sparse matrix
6064 template< typename VT > // Type of the right-hand side dense vector
6065 inline void SparseColumn<MT,false,true>::subAssign( const DenseVector<VT,false>& rhs )
6066 {
6068 
6069  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
6070 
6074 
6075  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6076 
6077  const SubType tmp( serial( *this - (~rhs) ) );
6078  matrix_.reset( col_ );
6079  assign( tmp );
6080 }
6082 //*************************************************************************************************
6083 
6084 
6085 //*************************************************************************************************
6097 template< typename MT > // Type of the sparse matrix
6098 template< typename VT > // Type of the right-hand side sparse vector
6099 inline void SparseColumn<MT,false,true>::subAssign( const SparseVector<VT,false>& rhs )
6100 {
6102 
6103  typedef typename SubTrait<ResultType,typename VT::ResultType>::Type SubType;
6104 
6108 
6109  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6110 
6111  const SubType tmp( serial( *this - (~rhs) ) );
6112  matrix_.reset( col_ );
6113  matrix_.reserve( col_, tmp.nonZeros() );
6114  assign( tmp );
6115 }
6117 //*************************************************************************************************
6118 
6119 
6120 
6121 
6122 
6123 
6124 
6125 
6126 //=================================================================================================
6127 //
6128 // SPARSECOLUMN OPERATORS
6129 //
6130 //=================================================================================================
6131 
6132 //*************************************************************************************************
6135 template< typename MT, bool SO, bool SF >
6136 inline void reset( SparseColumn<MT,SO,SF>& column );
6137 
6138 template< typename MT, bool SO, bool SF >
6139 inline void clear( SparseColumn<MT,SO,SF>& column );
6140 
6141 template< typename MT, bool SO, bool SF >
6142 inline bool isDefault( const SparseColumn<MT,SO,SF>& column );
6143 
6144 template< typename MT, bool SO, bool SF >
6145 inline bool isSame( const SparseColumn<MT,SO,SF>& a, const SparseColumn<MT,SO,SF>& b );
6147 //*************************************************************************************************
6148 
6149 
6150 //*************************************************************************************************
6157 template< typename MT // Type of the sparse matrix
6158  , bool SO // Storage order
6159  , bool SF > // Symmetry flag
6160 inline void reset( SparseColumn<MT,SO,SF>& column )
6161 {
6162  column.reset();
6163 }
6164 //*************************************************************************************************
6165 
6166 
6167 //*************************************************************************************************
6176 template< typename MT // Type of the sparse matrix
6177  , bool SO // Storage order
6178  , bool SF > // Symmetry flag
6179 inline void clear( SparseColumn<MT,SO,SF>& column )
6180 {
6181  column.reset();
6182 }
6183 //*************************************************************************************************
6184 
6185 
6186 //*************************************************************************************************
6204 template< typename MT // Type of the sparse matrix
6205  , bool SO // Storage order
6206  , bool SF > // Symmetry flag
6207 inline bool isDefault( const SparseColumn<MT,SO,SF>& column )
6208 {
6210 
6211  const ConstIterator end( column.end() );
6212  for( ConstIterator element=column.begin(); element!=end; ++element )
6213  if( !isDefault( element->value() ) ) return false;
6214  return true;
6215 }
6216 //*************************************************************************************************
6217 
6218 
6219 //*************************************************************************************************
6231 template< typename MT // Type of the sparse matrix
6232  , bool SO // Storage order
6233  , bool SF > // Symmetry flag
6234 inline bool isSame( const SparseColumn<MT,SO,SF>& a, const SparseColumn<MT,SO,SF>& b )
6235 {
6236  return ( isSame( a.matrix_, b.matrix_ ) && ( a.col_ == b.col_ ) );
6237 }
6238 //*************************************************************************************************
6239 
6240 
6241 
6242 
6243 //*************************************************************************************************
6258 template< typename MT // Type of the sparse matrix
6259  , bool SO // Storage order
6260  , bool SF > // Symmetry flag
6261 inline typename DerestrictTrait< SparseColumn<MT,SO,SF> >::Type
6262  derestrict( SparseColumn<MT,SO,SF>& column )
6263 {
6264  typedef typename DerestrictTrait< SparseColumn<MT,SO,SF> >::Type ReturnType;
6265  return ReturnType( derestrict( column.matrix_ ), column.col_ );
6266 }
6268 //*************************************************************************************************
6269 
6270 
6271 
6272 
6273 //=================================================================================================
6274 //
6275 // ISRESTRICTED SPECIALIZATIONS
6276 //
6277 //=================================================================================================
6278 
6279 //*************************************************************************************************
6281 template< typename MT, bool SO, bool SF >
6282 struct IsRestricted< SparseColumn<MT,SO,SF> > : public If< IsRestricted<MT>, TrueType, FalseType >::Type
6283 {
6284  enum { value = IsRestricted<MT>::value };
6285  typedef typename If< IsRestricted<MT>, TrueType, FalseType >::Type Type;
6286 };
6288 //*************************************************************************************************
6289 
6290 
6291 
6292 
6293 //=================================================================================================
6294 //
6295 // DERESTRICTTRAIT SPECIALIZATIONS
6296 //
6297 //=================================================================================================
6298 
6299 //*************************************************************************************************
6301 template< typename MT, bool SO, bool SF >
6302 struct DerestrictTrait< SparseColumn<MT,SO,SF> >
6303 {
6304  typedef SparseColumn< typename RemoveReference< typename DerestrictTrait<MT>::Type >::Type > Type;
6305 };
6307 //*************************************************************************************************
6308 
6309 
6310 
6311 
6312 //=================================================================================================
6313 //
6314 // SUBVECTORTRAIT SPECIALIZATIONS
6315 //
6316 //=================================================================================================
6317 
6318 //*************************************************************************************************
6320 template< typename MT, bool SO, bool SF >
6321 struct SubvectorTrait< SparseColumn<MT,SO,SF> >
6322 {
6324 };
6326 //*************************************************************************************************
6327 
6328 } // namespace blaze
6329 
6330 #endif
Iterator upperBound(size_t index)
Returns an iterator to the first index greater then the given index.
Definition: SparseColumn.h:1912
Constraint on the data type.
bool canAlias(const Other *alias) const
Returns whether the sparse column can alias with the given address alias.
Definition: SparseColumn.h:2006
const MT::ElementType max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1649
Compile time check for numeric types.This type trait tests whether or not the given template paramete...
Definition: IsNumeric.h:98
Header file for mathematical functions.
ConstIterator cbegin() const
Returns an iterator to the first element of the column.
Definition: SparseColumn.h:707
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the UNUSED_PARAMETER function template.
Header file for the IsUniUpper type trait.
Compile time type selection.The If class template selects one of the two given types T2 and T3 depend...
Definition: If.h:112
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8247
Header file for the subtraction trait.
Header file for basic type definitions.
Iterator insert(size_t index, const ElementType &value)
Inserting an element into the sparse column.
Definition: SparseColumn.h:1396
Iterator find(size_t index)
Searches for a specific column element.
Definition: SparseColumn.h:1821
Header file for the SparseVector base class.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector)
Returns the current size/dimension of the vector.
Definition: Vector.h:264
void subAssign(const DenseVector< VT, false > &rhs)
Default implementation of the subtraction assignment of a dense vector.
Definition: SparseColumn.h:2180
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:258
Base template for the ColumnTrait class.
Definition: ColumnTrait.h:115
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a column dense or sparse vector type...
Definition: TransposeFlag.h:159
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:209
Header file for the IsDiagonal type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:118
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b)
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:946
void reserve(size_t n)
Setting the minimum capacity of the sparse column.
Definition: SparseColumn.h:1471
size_t capacity() const
Returns the maximum capacity of the sparse column.
Definition: SparseColumn.h:1318
Header file for the IsColumnMajorMatrix type trait.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:821
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2507
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix)
Returns the maximum capacity of the matrix.
Definition: Matrix.h:348
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename ColumnExprTrait< MT >::Type >::Type column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:103
void UNUSED_PARAMETER(const T1 &)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the And class template.
Compile time check for lower triangular matrices.This type trait tests whether or not the given templ...
Definition: IsLower.h:90
IfTrue< useConst, ConstReference, typename MT::Reference >::Type Reference
Reference to a non-constant column value.
Definition: SparseColumn.h:407
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:118
MT::ConstIterator ConstIterator
Iterator over constant elements.
Definition: SparseColumn.h:410
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:699
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:386
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a symmetric matrix type...
Definition: Symmetric.h:78
Compile time check for upper triangular matrices.This type trait tests whether or not the given templ...
Definition: IsUpper.h:90
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:118
Header file for the RequiresEvaluation type trait.
Header file for the IsUniLower type trait.
void append(size_t index, const ElementType &value, bool check=false)
Appending an element to the sparse column.
Definition: SparseColumn.h:1977
bool isLower(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is a lower triangular matrix.
Definition: DenseMatrix.h:964
Base class for sparse matrices.The SparseMatrix class is a base class for all sparse matrix classes...
Definition: Forward.h:107
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:861
Constraint on the data type.
Header file for the column base class.
Compile time check for data types with restricted data access.This type trait tests whether the given...
Definition: IsRestricted.h:82
const size_t col_
The index of the column in the matrix.
Definition: SparseColumn.h:561
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SparseColumn.h:398
Constraint on the data type.
Compile time check for upper unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniUpper.h:85
ConstIterator cend() const
Returns an iterator just past the last element of the column.
Definition: SparseColumn.h:758
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
Header file for the If class template.
Compile time assertion.
Constraint on the data type.
IfTrue< useConst, ConstIterator, typename MT::Iterator >::Type Iterator
Iterator over non-constant elements.
Definition: SparseColumn.h:413
Header file for the IsFloatingPoint type trait.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: StorageOrder.h:161
Iterator lowerBound(size_t index)
Returns an iterator to the first index not less then the given index.
Definition: SparseColumn.h:1867
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2511
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:116
Header file for the Or class template.
const MT::ElementType min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1602
BLAZE_ALWAYS_INLINE void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:635
Iterator set(size_t index, const ElementType &value)
Setting an element of the sparse column.
Definition: SparseColumn.h:1373
Base class for all columns.The Column class serves as a tag for all columns (i.e. dense and sparse co...
Definition: Column.h:64
ColumnTrait< MT >::Type ResultType
Result type for expression template evaluations.
Definition: SparseColumn.h:397
Header file for the subvector trait.
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
Header file for the IsLower type trait.
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:79
Constraint on the data type.
Header file for the SparseElement base class.
MT::ReturnType ReturnType
Return type for expression template evaluations.
Definition: SparseColumn.h:400
Constraint on the data type.
void reset()
Reset to the default initial values.
Definition: SparseColumn.h:1351
void erase(size_t index)
Erasing an element from the sparse column.
Definition: SparseColumn.h:1414
bool isUpper(const DenseMatrix< MT, SO > &dm)
Checks if the given dense matrix is an upper triangular matrix.
Definition: DenseMatrix.h:1197
Constraints on the storage order of matrix types.
Constraint on the data type.
void assign(const DenseVector< VT, false > &rhs)
Default implementation of the assignment of a dense vector.
Definition: SparseColumn.h:2049
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:195
Compile time check for strictly upper triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyUpper.h:86
Compile time check for floating point data types.This type trait tests whether or not the given templ...
Definition: IsFloatingPoint.h:94
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2505
size_t nonZeros() const
Returns the number of non-zero elements in the column.
Definition: SparseColumn.h:1336
Constraint on the data type.
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2509
const SparseColumn & CompositeType
Data type for composite expression templates.
Definition: SparseColumn.h:401
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:841
Header file for the IsAdaptor type trait.
Header file for the serial shim.
Header file for the isOne shim.
bool isAliased(const Other *alias) const
Returns whether the sparse column is aliased with the given address alias.
Definition: SparseColumn.h:2027
Compile time check for lower unitriangular matrices.This type trait tests whether or not the given te...
Definition: IsUniLower.h:85
Header file for the DerestrictTrait class template.
Constraint on the data type.
Header file for the IsNumeric type trait.
DisableIf< Or< IsComputation< MT >, IsTransExpr< MT > >, typename RowExprTrait< MT >::Type >::Type row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:103
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:116
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: StorageOrder.h:81
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2506
Header file for the IsConst type trait.
MT::ElementType ElementType
Type of the column elements.
Definition: SparseColumn.h:399
Header file for run time assertion macros.
Base template for the AddTrait class.
Definition: AddTrait.h:150
Base template for the MultTrait class.
Definition: MultTrait.h:150
Header file for the addition trait.
Header file for the division trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_RESTRICTED(T)
Constraint on the data type.In case the given data type T does have a restricted data access...
Definition: Restricted.h:118
const DenseIterator< Type > operator-(const DenseIterator< Type > &it, ptrdiff_t inc)
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:585
Substitution Failure Is Not An Error (SFINAE) class.The EnableIf class template is an auxiliary tool ...
Definition: EnableIf.h:184
Header file for the reset shim.
SparseColumn & operator=(const SparseColumn &rhs)
Copy assignment operator for SparseColumn.
Definition: SparseColumn.h:789
Compile time type negation.The Not class template negates the given compile time condition. In case the given condition would evaluate to true, the nested member enumeration is set to false and vice versa:
Definition: Not.h:70
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:116
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2510
Header file for the column trait.
Header file for the isDefault shim.
Constraint on the data type.
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:118
Evaluation of the return type of the derestrict function.Via this type trait it is possible to evalua...
Definition: DerestrictTrait.h:74
Header file for the IsReference type trait.
Header file for the RemoveReference type trait.
Compile time check for constant data types.The IsConst type trait tests whether or not the given temp...
Definition: IsConst.h:94
Base template for the DivTrait class.
Definition: DivTrait.h:150
Compile time check for strictly lower triangular matrices.This type trait tests whether or not the gi...
Definition: IsStrictlyLower.h:86
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:79
void addAssign(const DenseVector< VT, false > &rhs)
Default implementation of the addition assignment of a dense vector.
Definition: SparseColumn.h:2111
Iterator end()
Returns an iterator just past the last element of the column.
Definition: SparseColumn.h:724
Base class for N-dimensional vectors.The Vector class is a base class for all arbitrarily sized (N-di...
Definition: Forward.h:151
Iterator begin()
Returns an iterator to the first element of the column.
Definition: SparseColumn.h:673
Reference operator[](size_t index)
Subscript operator for the direct access to the column elements.
Definition: SparseColumn.h:637
boost::false_type FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
CompressedMatrix< Type,!SO > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:260
If< IsExpression< MT >, MT, MT & >::Type Operand
Composite data type of the dense matrix expression.
Definition: SparseColumn.h:380
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:108
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2502
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
size_t extendCapacity() const
Calculating a new sparse column capacity.
Definition: SparseColumn.h:1514
Compile time type check.This class tests whether the given template parameter T is a reference type (...
Definition: IsReference.h:94
SparseColumn< MT, SO, SF > This
Type of this SparseColumn instance.
Definition: SparseColumn.h:396
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2508
Base template for the SubTrait class.
Definition: SubTrait.h:150
Header file for the IsUpper type trait.
boost::true_type TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
#define BLAZE_STATIC_ASSERT(expr)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:143
EnableIf< IsNumeric< Type >, bool >::Type isOne(const Type &v)
Returns whether the given value/object represents the numeric value 1.
Definition: IsOne.h:80
Header file for the IsRestricted type trait.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional matrix type...
Definition: SparseMatrix.h:79
Reference to a specific column of a sparse matrix.The SparseColumn template represents a reference to...
Definition: Forward.h:51
Compile time type selection.The IfTrue class template selects one of the two given types T1 and T2 de...
Definition: If.h:59
MT::ConstReference ConstReference
Reference to a constant column value.
Definition: SparseColumn.h:404
Operand matrix_
The sparse matrix containing the column.
Definition: SparseColumn.h:560
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.
size_t size() const
Returns the current size/dimension of the sparse column.
Definition: SparseColumn.h:1303
SparseColumn(MT &matrix, size_t index)
The constructor for SparseColumn.
Definition: SparseColumn.h:609
Header file for a safe C++ NULL pointer implementation.