Sparse.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_BAND_SPARSE_H_
36 #define _BLAZE_MATH_VIEWS_BAND_SPARSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <iterator>
44 #include <blaze/math/Aliases.h>
53 #include <blaze/math/Exception.h>
78 #include <blaze/math/views/Check.h>
81 #include <blaze/util/Assert.h>
84 #include <blaze/util/DisableIf.h>
85 #include <blaze/util/mpl/If.h>
86 #include <blaze/util/TypeList.h>
87 #include <blaze/util/Types.h>
90 #include <blaze/util/Unused.h>
91 
92 
93 namespace blaze {
94 
95 //=================================================================================================
96 //
97 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES
98 //
99 //=================================================================================================
100 
101 //*************************************************************************************************
108 template< typename MT // Type of the sparse matrix
109  , bool TF // Transpose flag
110  , ptrdiff_t... CBAs > // Compile time band arguments
111 class Band<MT,TF,false,false,CBAs...>
112  : public View< SparseVector< Band<MT,TF,false,false,CBAs...>, TF > >
113  , private BandData<CBAs...>
114 {
115  private:
116  //**Type definitions****************************************************************************
117  using RT = ResultType_<MT>;
118  using DataType = BandData<CBAs...>;
119  using Operand = If_< IsExpression<MT>, MT, MT& >;
120  //**********************************************************************************************
121 
122  public:
123  //**Type definitions****************************************************************************
125  using This = Band<MT,TF,false,false,CBAs...>;
126 
127  using BaseType = SparseVector<This,TF>;
128  using ViewedType = MT;
129  using ResultType = BandTrait_<RT,CBAs...>;
130  using TransposeType = TransposeType_<ResultType>;
131  using ElementType = ElementType_<MT>;
132  using ReturnType = ReturnType_<MT>;
133 
135  using CompositeType = IfTrue_< RequiresEvaluation<MT>::value, const ResultType, const Band& >;
136 
138  using ConstReference = ConstReference_<MT>;
139 
141  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
142  //**********************************************************************************************
143 
144  //**BandElement class definition****************************************************************
147  template< typename MatrixType // Type of the sparse matrix
148  , typename IteratorType > // Type of the sparse matrix iterator
149  class BandElement
150  : private SparseElement
151  {
152  public:
153  //**Constructor******************************************************************************
159  inline BandElement( IteratorType pos, size_t index )
160  : pos_ ( pos ) // Iterator to the current position within the sparse band
161  , index_( index ) // Index of the element
162  {}
163  //*******************************************************************************************
164 
165  //**Assignment operator**********************************************************************
171  template< typename T > inline BandElement& operator=( const T& v ) {
172  *pos_ = v;
173  return *this;
174  }
175  //*******************************************************************************************
176 
177  //**Addition assignment operator*************************************************************
183  template< typename T > inline BandElement& operator+=( const T& v ) {
184  *pos_ += v;
185  return *this;
186  }
187  //*******************************************************************************************
188 
189  //**Subtraction assignment operator**********************************************************
195  template< typename T > inline BandElement& operator-=( const T& v ) {
196  *pos_ -= v;
197  return *this;
198  }
199  //*******************************************************************************************
200 
201  //**Multiplication assignment operator*******************************************************
207  template< typename T > inline BandElement& operator*=( const T& v ) {
208  *pos_ *= v;
209  return *this;
210  }
211  //*******************************************************************************************
212 
213  //**Division assignment operator*************************************************************
219  template< typename T > inline BandElement& operator/=( const T& v ) {
220  *pos_ /= v;
221  return *this;
222  }
223  //*******************************************************************************************
224 
225  //**Element access operator******************************************************************
230  inline const BandElement* operator->() const {
231  return this;
232  }
233  //*******************************************************************************************
234 
235  //**Value function***************************************************************************
240  inline decltype(auto) value() const {
241  return pos_->value();
242  }
243  //*******************************************************************************************
244 
245  //**Index function***************************************************************************
250  inline size_t index() const {
251  return index_;
252  }
253  //*******************************************************************************************
254 
255  private:
256  //**Member variables*************************************************************************
257  IteratorType pos_;
258  size_t index_;
259  //*******************************************************************************************
260  };
261  //**********************************************************************************************
262 
263  //**BandIterator class definition***************************************************************
266  template< typename MatrixType // Type of the sparse matrix
267  , typename IteratorType > // Type of the sparse matrix iterator
268  class BandIterator
269  {
270  public:
271  //**Type definitions*************************************************************************
272  using IteratorCategory = std::forward_iterator_tag;
273  using ValueType = BandElement<MatrixType,IteratorType>;
274  using PointerType = ValueType;
275  using ReferenceType = ValueType;
276  using DifferenceType = ptrdiff_t;
277 
278  // STL iterator requirements
279  using iterator_category = IteratorCategory;
280  using value_type = ValueType;
281  using pointer = PointerType;
282  using reference = ReferenceType;
283  using difference_type = DifferenceType;
284  //*******************************************************************************************
285 
286  //**Constructor******************************************************************************
289  inline BandIterator()
290  : matrix_( nullptr ) // The sparse matrix containing the band
291  , row_ ( 0UL ) // The current row index
292  , column_( 0UL ) // The current column index
293  , pos_ () // Iterator to the current sparse element
294  {}
295  //*******************************************************************************************
296 
297  //**Constructor******************************************************************************
304  inline BandIterator( MatrixType& matrix, size_t rowIndex, size_t columnIndex )
305  : matrix_( &matrix ) // The sparse matrix containing the band
306  , row_ ( rowIndex ) // The current row index
307  , column_( columnIndex ) // The current column index
308  , pos_ () // Iterator to the current sparse element
309  {
310  for( ; row_ < matrix_->rows() && column_ < matrix_->columns(); ++row_, ++column_ ) {
311  pos_ = matrix_->find( row_, column_ );
312  if( pos_ != matrix_->end( IsRowMajorMatrix<MatrixType>::value ? row_ : column_ ) )
313  break;
314  }
315  }
316  //*******************************************************************************************
317 
318  //**Constructor******************************************************************************
326  inline BandIterator( MatrixType& matrix, size_t rowIndex, size_t columnIndex, IteratorType pos )
327  : matrix_( &matrix ) // The sparse matrix containing the band
328  , row_ ( rowIndex ) // The current row index
329  , column_( columnIndex ) // The current column index
330  , pos_ ( pos ) // Iterator to the current sparse element
331  {
332  BLAZE_INTERNAL_ASSERT( matrix.find( row_, column_ ) == pos, "Invalid initial iterator position" );
333  }
334  //*******************************************************************************************
335 
336  //**Constructor******************************************************************************
341  template< typename MatrixType2, typename IteratorType2 >
342  inline BandIterator( const BandIterator<MatrixType2,IteratorType2>& it )
343  : matrix_( it.matrix_ ) // The sparse matrix containing the band
344  , row_ ( it.row_ ) // The current row index
345  , column_( it.column_ ) // The current column index
346  , pos_ ( it.pos_ ) // Iterator to the current sparse element
347  {}
348  //*******************************************************************************************
349 
350  //**Prefix increment operator****************************************************************
355  inline BandIterator& operator++() {
356  ++row_;
357  ++column_;
358 
359  for( ; row_ < matrix_->rows() && column_ < matrix_->columns(); ++row_, ++column_ ) {
360  pos_ = matrix_->find( row_, column_ );
361  if( pos_ != matrix_->end( IsRowMajorMatrix<MatrixType>::value ? row_ : column_ ) )
362  break;
363  }
364 
365  return *this;
366  }
367  //*******************************************************************************************
368 
369  //**Postfix increment operator***************************************************************
374  inline const BandIterator operator++( int ) {
375  const BandIterator tmp( *this );
376  ++(*this);
377  return tmp;
378  }
379  //*******************************************************************************************
380 
381  //**Element access operator******************************************************************
386  inline ReferenceType operator*() const {
387  return ReferenceType( pos_, min( row_, column_ ) );
388  }
389  //*******************************************************************************************
390 
391  //**Element access operator******************************************************************
396  inline PointerType operator->() const {
397  return PointerType( pos_, min( row_, column_ ) );
398  }
399  //*******************************************************************************************
400 
401  //**Equality operator************************************************************************
407  template< typename MatrixType2, typename IteratorType2 >
408  inline bool operator==( const BandIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
409  return row_ == rhs.row_;
410  }
411  //*******************************************************************************************
412 
413  //**Inequality operator**********************************************************************
419  template< typename MatrixType2, typename IteratorType2 >
420  inline bool operator!=( const BandIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
421  return !( *this == rhs );
422  }
423  //*******************************************************************************************
424 
425  //**Subtraction operator*********************************************************************
431  inline DifferenceType operator-( const BandIterator& rhs ) const {
432  size_t counter( 0UL );
433  size_t row( rhs.row_ );
434  size_t column( rhs.column_ );
435 
436  for( ; row<row_; ++row, ++column ) {
437  const auto end( matrix_->end( IsRowMajorMatrix<MatrixType>::value ? row : column ) );
438  if( matrix_->find( row, column ) != end )
439  ++counter;
440  }
441 
442  return counter;
443  }
444  //*******************************************************************************************
445 
446  private:
447  //**Member variables*************************************************************************
448  MatrixType* matrix_;
449  size_t row_;
450  size_t column_;
451  IteratorType pos_;
452  //*******************************************************************************************
453 
454  //**Friend declarations**********************************************************************
455  template< typename MatrixType2, typename IteratorType2 > friend class BandIterator;
456  template< typename MT2, bool DF2, bool TF2, bool MF2, ptrdiff_t... CBAs2 > friend class Band;
457  //*******************************************************************************************
458  };
459  //**********************************************************************************************
460 
461  //**Type definitions****************************************************************************
463  using ConstIterator = BandIterator< const MT, ConstIterator_<MT> >;
464 
466  using Iterator = If_< IsConst<MT>, ConstIterator, BandIterator< MT, Iterator_<MT> > >;
467  //**********************************************************************************************
468 
469  //**Compilation flags***************************************************************************
471  enum : bool { smpAssignable = false };
472  //**********************************************************************************************
473 
474  //**Constructors********************************************************************************
477  template< typename... RBAs >
478  explicit inline Band( MT& matrix, RBAs... args );
479  // No explicitly declared copy constructor.
481  //**********************************************************************************************
482 
483  //**Destructor**********************************************************************************
484  // No explicitly declared destructor.
485  //**********************************************************************************************
486 
487  //**Data access functions***********************************************************************
490  inline Reference operator[]( size_t index );
491  inline ConstReference operator[]( size_t index ) const;
492  inline Reference at( size_t index );
493  inline ConstReference at( size_t index ) const;
494  inline Iterator begin ();
495  inline ConstIterator begin () const;
496  inline ConstIterator cbegin() const;
497  inline Iterator end ();
498  inline ConstIterator end () const;
499  inline ConstIterator cend () const;
501  //**********************************************************************************************
502 
503  //**Assignment operators************************************************************************
506  inline Band& operator= ( initializer_list<ElementType> list );
507  inline Band& operator= ( const Band& rhs );
508  template< typename VT > inline Band& operator= ( const Vector<VT,TF>& rhs );
509  template< typename VT > inline Band& operator+=( const Vector<VT,TF>& rhs );
510  template< typename VT > inline Band& operator-=( const Vector<VT,TF>& rhs );
511  template< typename VT > inline Band& operator*=( const Vector<VT,TF>& rhs );
512  template< typename VT > inline Band& operator/=( const DenseVector<VT,TF>& rhs );
513  template< typename VT > inline Band& operator%=( const Vector<VT,TF>& rhs );
515  //**********************************************************************************************
516 
517  //**Utility functions***************************************************************************
520  using DataType::band;
521  using DataType::row;
522  using DataType::column;
523 
524  inline MT& operand() noexcept;
525  inline const MT& operand() const noexcept;
526 
527  inline size_t size() const noexcept;
528  inline size_t capacity() const noexcept;
529  inline size_t nonZeros() const;
530  inline void reset();
531  inline void reserve( size_t n );
533  //**********************************************************************************************
534 
535  //**Insertion functions*************************************************************************
538  inline Iterator set ( size_t index, const ElementType& value );
539  inline Iterator insert( size_t index, const ElementType& value );
540  inline void append( size_t index, const ElementType& value, bool check=false );
542  //**********************************************************************************************
543 
544  //**Erase functions*****************************************************************************
547  inline void erase( size_t index );
548  inline Iterator erase( Iterator pos );
549  inline Iterator erase( Iterator first, Iterator last );
550 
551  template< typename Pred, typename = DisableIf_< IsIntegral<Pred> > >
552  inline void erase( Pred predicate );
553 
554  template< typename Pred >
555  inline void erase( Iterator first, Iterator last, Pred predicate );
557  //**********************************************************************************************
558 
559  //**Lookup functions****************************************************************************
562  inline Iterator find ( size_t index );
563  inline ConstIterator find ( size_t index ) const;
564  inline Iterator lowerBound( size_t index );
565  inline ConstIterator lowerBound( size_t index ) const;
566  inline Iterator upperBound( size_t index );
567  inline ConstIterator upperBound( size_t index ) const;
569  //**********************************************************************************************
570 
571  //**Numeric functions***************************************************************************
574  template< typename Other > inline Band& scale( const Other& scalar );
576  //**********************************************************************************************
577 
578  //**Expression template evaluation functions****************************************************
581  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
582  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
583 
584  template< typename VT > inline void assign ( const DenseVector <VT,TF>& rhs );
585  template< typename VT > inline void assign ( const SparseVector<VT,TF>& rhs );
586  template< typename VT > inline void addAssign( const Vector<VT,TF>& rhs );
587  template< typename VT > inline void subAssign( const Vector<VT,TF>& rhs );
589  //**********************************************************************************************
590 
591  private:
592  //**Member variables****************************************************************************
595  Operand matrix_;
596 
597  //**********************************************************************************************
598 
599  //**Compile time checks*************************************************************************
605  //**********************************************************************************************
606 };
608 //*************************************************************************************************
609 
610 
611 
612 
613 //=================================================================================================
614 //
615 // CONSTRUCTORS
616 //
617 //=================================================================================================
618 
619 //*************************************************************************************************
632 template< typename MT // Type of the sparse matrix
633  , bool TF // Transpose flag
634  , ptrdiff_t... CBAs > // Compile time band arguments
635 template< typename... RBAs > // Runtime band arguments
636 inline Band<MT,TF,false,false,CBAs...>::Band( MT& matrix, RBAs... args )
637  : DataType( args... ) // Base class initialization
638  , matrix_ ( matrix ) // The matrix containing the band
639 {
640  if( !Contains< TypeList<RBAs...>, Unchecked >::value ) {
641  if( ( band() > 0L && column() >= matrix.columns() ) ||
642  ( band() < 0L && row() >= matrix.rows() ) ) {
643  BLAZE_THROW_INVALID_ARGUMENT( "Invalid band access index" );
644  }
645  }
646  else {
647  BLAZE_USER_ASSERT( band() < 0L || column() < matrix.columns(), "Invalid band access index" );
648  BLAZE_USER_ASSERT( band() > 0L || row() < matrix.rows(), "Invalid band access index" );
649  }
650 }
652 //*************************************************************************************************
653 
654 
655 
656 
657 //=================================================================================================
658 //
659 // DATA ACCESS FUNCTIONS
660 //
661 //=================================================================================================
662 
663 //*************************************************************************************************
673 template< typename MT // Type of the sparse matrix
674  , bool TF // Transpose flag
675  , ptrdiff_t... CBAs > // Compile time band arguments
676 inline typename Band<MT,TF,false,false,CBAs...>::Reference
677  Band<MT,TF,false,false,CBAs...>::operator[]( size_t index )
678 {
679  BLAZE_USER_ASSERT( index < size(), "Invalid band access index" );
680  return matrix_(row()+index,column()+index);
681 }
683 //*************************************************************************************************
684 
685 
686 //*************************************************************************************************
696 template< typename MT // Type of the sparse matrix
697  , bool TF // Transpose flag
698  , ptrdiff_t... CBAs > // Compile time band arguments
699 inline typename Band<MT,TF,false,false,CBAs...>::ConstReference
700  Band<MT,TF,false,false,CBAs...>::operator[]( size_t index ) const
701 {
702  BLAZE_USER_ASSERT( index < size(), "Invalid band access index" );
703  return const_cast<const MT&>( matrix_ )(row()+index,column()+index);
704 }
706 //*************************************************************************************************
707 
708 
709 //*************************************************************************************************
720 template< typename MT // Type of the sparse matrix
721  , bool TF // Transpose flag
722  , ptrdiff_t... CBAs > // Compile time band arguments
723 inline typename Band<MT,TF,false,false,CBAs...>::Reference
724  Band<MT,TF,false,false,CBAs...>::at( size_t index )
725 {
726  if( index >= size() ) {
727  BLAZE_THROW_OUT_OF_RANGE( "Invalid band access index" );
728  }
729  return (*this)[index];
730 }
732 //*************************************************************************************************
733 
734 
735 //*************************************************************************************************
746 template< typename MT // Type of the sparse matrix
747  , bool TF // Transpose flag
748  , ptrdiff_t... CBAs > // Compile time band arguments
749 inline typename Band<MT,TF,false,false,CBAs...>::ConstReference
750  Band<MT,TF,false,false,CBAs...>::at( size_t index ) const
751 {
752  if( index >= size() ) {
753  BLAZE_THROW_OUT_OF_RANGE( "Invalid band access index" );
754  }
755  return (*this)[index];
756 }
758 //*************************************************************************************************
759 
760 
761 //*************************************************************************************************
769 template< typename MT // Type of the sparse matrix
770  , bool TF // Transpose flag
771  , ptrdiff_t... CBAs > // Compile time band arguments
772 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
774 {
775  return Iterator( matrix_, row(), column() );
776 }
778 //*************************************************************************************************
779 
780 
781 //*************************************************************************************************
789 template< typename MT // Type of the sparse matrix
790  , bool TF // Transpose flag
791  , ptrdiff_t... CBAs > // Compile time band arguments
792 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
794 {
795  return ConstIterator( matrix_, row(), column() );
796 }
798 //*************************************************************************************************
799 
800 
801 //*************************************************************************************************
809 template< typename MT // Type of the sparse matrix
810  , bool TF // Transpose flag
811  , ptrdiff_t... CBAs > // Compile time band arguments
812 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
814 {
815  return ConstIterator( matrix_, row(), column() );
816 }
818 //*************************************************************************************************
819 
820 
821 //*************************************************************************************************
829 template< typename MT // Type of the sparse matrix
830  , bool TF // Transpose flag
831  , ptrdiff_t... CBAs > // Compile time band arguments
832 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
834 {
835  const size_t n( size() );
836  return Iterator( matrix_, row()+n, column()+n );
837 }
839 //*************************************************************************************************
840 
841 
842 //*************************************************************************************************
850 template< typename MT // Type of the sparse matrix
851  , bool TF // Transpose flag
852  , ptrdiff_t... CBAs > // Compile time band arguments
853 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
855 {
856  const size_t n( size() );
857  return ConstIterator( matrix_, row()+n, column()+n );
858 }
860 //*************************************************************************************************
861 
862 
863 //*************************************************************************************************
871 template< typename MT // Type of the sparse matrix
872  , bool TF // Transpose flag
873  , ptrdiff_t... CBAs > // Compile time band arguments
874 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
876 {
877  const size_t n( size() );
878  return ConstIterator( matrix_, row()+n, column()+n );
879 }
881 //*************************************************************************************************
882 
883 
884 
885 
886 //=================================================================================================
887 //
888 // ASSIGNMENT OPERATORS
889 //
890 //=================================================================================================
891 
892 //*************************************************************************************************
907 template< typename MT // Type of the dense matrix
908  , bool TF // Transpose flag
909  , ptrdiff_t... CBAs > // Compile time band arguments
910 inline Band<MT,TF,false,false,CBAs...>&
911  Band<MT,TF,false,false,CBAs...>::operator=( initializer_list<ElementType> list )
912 {
913  using blaze::assign;
914 
915  if( list.size() > size() ) {
916  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to band" );
917  }
918 
919  const InitializerVector<ElementType,false> tmp( list, size() );
920 
921  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
922  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
923  }
924 
925  decltype(auto) left( derestrict( *this ) );
926 
927  assign( left, tmp );
928 
929  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
930 
931  return *this;
932 }
934 //*************************************************************************************************
935 
936 
937 //*************************************************************************************************
951 template< typename MT // Type of the sparse matrix
952  , bool TF // Transpose flag
953  , ptrdiff_t... CBAs > // Compile time band arguments
954 inline Band<MT,TF,false,false,CBAs...>&
955  Band<MT,TF,false,false,CBAs...>::operator=( const Band& rhs )
956 {
957  using blaze::assign;
958 
962 
963  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && band() == rhs.band() ) )
964  return *this;
965 
966  if( size() != rhs.size() ) {
967  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
968  }
969 
970  if( !tryAssign( matrix_, rhs, band(), row(), column() ) ) {
971  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
972  }
973 
974  decltype(auto) left( derestrict( *this ) );
975 
976  if( rhs.canAlias( &matrix_ ) ) {
977  const ResultType tmp( rhs );
978  assign( left, tmp );
979  }
980  else {
981  assign( left, rhs );
982  }
983 
984  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
985 
986  return *this;
987 }
989 //*************************************************************************************************
990 
991 
992 //*************************************************************************************************
1006 template< typename MT // Type of the sparse matrix
1007  , bool TF // Transpose flag
1008  , ptrdiff_t... CBAs > // Compile time band arguments
1009 template< typename VT > // Type of the right-hand side vector
1010 inline Band<MT,TF,false,false,CBAs...>&
1011  Band<MT,TF,false,false,CBAs...>::operator=( const Vector<VT,TF>& rhs )
1012 {
1013  using blaze::assign;
1014 
1015  if( size() != (~rhs).size() ) {
1016  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1017  }
1018 
1019  const CompositeType_<VT> tmp( ~rhs );
1020 
1021  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1022  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1023  }
1024 
1025  decltype(auto) left( derestrict( *this ) );
1026 
1027  assign( left, tmp );
1028 
1029  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1030 
1031  return *this;
1032 }
1034 //*************************************************************************************************
1035 
1036 
1037 //*************************************************************************************************
1051 template< typename MT // Type of the sparse matrix
1052  , bool TF // Transpose flag
1053  , ptrdiff_t... CBAs > // Compile time band arguments
1054 template< typename VT > // Type of the right-hand side vector
1055 inline Band<MT,TF,false,false,CBAs...>&
1056  Band<MT,TF,false,false,CBAs...>::operator+=( const Vector<VT,TF>& rhs )
1057 {
1058  using blaze::assign;
1059 
1065 
1066  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
1067 
1070 
1071  if( size() != (~rhs).size() ) {
1072  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1073  }
1074 
1075  const AddType tmp( *this + (~rhs) );
1076 
1077  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1078  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1079  }
1080 
1081  decltype(auto) left( derestrict( *this ) );
1082 
1083  assign( left, tmp );
1084 
1085  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1086 
1087  return *this;
1088 }
1090 //*************************************************************************************************
1091 
1092 
1093 //*************************************************************************************************
1107 template< typename MT // Type of the sparse matrix
1108  , bool TF // Transpose flag
1109  , ptrdiff_t... CBAs > // Compile time band arguments
1110 template< typename VT > // Type of the right-hand side vector
1111 inline Band<MT,TF,false,false,CBAs...>&
1112  Band<MT,TF,false,false,CBAs...>::operator-=( const Vector<VT,TF>& rhs )
1113 {
1114  using blaze::assign;
1115 
1121 
1122  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
1123 
1126 
1127  if( size() != (~rhs).size() ) {
1128  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1129  }
1130 
1131  const SubType tmp( *this - (~rhs) );
1132 
1133  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1134  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1135  }
1136 
1137  decltype(auto) left( derestrict( *this ) );
1138 
1139  assign( left, tmp );
1140 
1141  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1142 
1143  return *this;
1144 }
1146 //*************************************************************************************************
1147 
1148 
1149 //*************************************************************************************************
1162 template< typename MT // Type of the sparse matrix
1163  , bool TF // Transpose flag
1164  , ptrdiff_t... CBAs > // Compile time band arguments
1165 template< typename VT > // Type of the right-hand side vector
1166 inline Band<MT,TF,false,false,CBAs...>&
1167  Band<MT,TF,false,false,CBAs...>::operator*=( const Vector<VT,TF>& rhs )
1168 {
1169  using blaze::assign;
1170 
1176 
1177  using MultType = MultTrait_< ResultType, ResultType_<VT> >;
1178 
1181 
1182  if( size() != (~rhs).size() ) {
1183  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1184  }
1185 
1186  const MultType tmp( *this * (~rhs) );
1187 
1188  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1189  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1190  }
1191 
1192  decltype(auto) left( derestrict( *this ) );
1193 
1194  assign( left, tmp );
1195 
1196  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1197 
1198  return *this;
1199 }
1201 //*************************************************************************************************
1202 
1203 
1204 //*************************************************************************************************
1216 template< typename MT // Type of the sparse matrix
1217  , bool TF // Transpose flag
1218  , ptrdiff_t... CBAs > // Compile time band arguments
1219 template< typename VT > // Type of the right-hand side vector
1220 inline Band<MT,TF,false,false,CBAs...>&
1221  Band<MT,TF,false,false,CBAs...>::operator/=( const DenseVector<VT,TF>& rhs )
1222 {
1223  using blaze::assign;
1224 
1228  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( ResultType_<VT> );
1231 
1232  using DivType = DivTrait_< ResultType, ResultType_<VT> >;
1233 
1237 
1238  if( size() != (~rhs).size() ) {
1239  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1240  }
1241 
1242  const DivType tmp( *this / (~rhs) );
1243 
1244  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1245  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1246  }
1247 
1248  decltype(auto) left( derestrict( *this ) );
1249 
1250  assign( left, tmp );
1251 
1252  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1253 
1254  return *this;
1255 }
1257 //*************************************************************************************************
1258 
1259 
1260 //*************************************************************************************************
1273 template< typename MT // Type of the sparse matrix
1274  , bool TF // Transpose flag
1275  , ptrdiff_t... CBAs > // Compile time band arguments
1276 template< typename VT > // Type of the right-hand side vector
1277 inline Band<MT,TF,false,false,CBAs...>&
1278  Band<MT,TF,false,false,CBAs...>::operator%=( const Vector<VT,TF>& rhs )
1279 {
1280  using blaze::assign;
1281 
1284 
1285  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
1286 
1290 
1291  if( size() != 3UL || (~rhs).size() != 3UL ) {
1292  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1293  }
1294 
1295  const CrossType tmp( *this % (~rhs) );
1296 
1297  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1298  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1299  }
1300 
1301  decltype(auto) left( derestrict( *this ) );
1302 
1303  assign( left, tmp );
1304 
1305  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1306 
1307  return *this;
1308 }
1310 //*************************************************************************************************
1311 
1312 
1313 
1314 
1315 //=================================================================================================
1316 //
1317 // UTILITY FUNCTIONS
1318 //
1319 //=================================================================================================
1320 
1321 //*************************************************************************************************
1327 template< typename MT // Type of the sparse matrix
1328  , bool TF // Transpose flag
1329  , ptrdiff_t... CBAs > // Compile time band arguments
1330 inline MT& Band<MT,TF,false,false,CBAs...>::operand() noexcept
1331 {
1332  return matrix_;
1333 }
1335 //*************************************************************************************************
1336 
1337 
1338 //*************************************************************************************************
1344 template< typename MT // Type of the sparse matrix
1345  , bool TF // Transpose flag
1346  , ptrdiff_t... CBAs > // Compile time band arguments
1347 inline const MT& Band<MT,TF,false,false,CBAs...>::operand() const noexcept
1348 {
1349  return matrix_;
1350 }
1352 //*************************************************************************************************
1353 
1354 
1355 //*************************************************************************************************
1361 template< typename MT // Type of the sparse matrix
1362  , bool TF // Transpose flag
1363  , ptrdiff_t... CBAs > // Compile time band arguments
1364 inline size_t Band<MT,TF,false,false,CBAs...>::size() const noexcept
1365 {
1366  return min( matrix_.rows() - row(), matrix_.columns() - column() );
1367 }
1369 //*************************************************************************************************
1370 
1371 
1372 //*************************************************************************************************
1378 template< typename MT // Type of the sparse matrix
1379  , bool TF // Transpose flag
1380  , ptrdiff_t... CBAs > // Compile time band arguments
1381 inline size_t Band<MT,TF,false,false,CBAs...>::capacity() const noexcept
1382 {
1383  return size();
1384 }
1386 //*************************************************************************************************
1387 
1388 
1389 //*************************************************************************************************
1398 template< typename MT // Type of the sparse matrix
1399  , bool TF // Transpose flag
1400  , ptrdiff_t... CBAs > // Compile time band arguments
1401 inline size_t Band<MT,TF,false,false,CBAs...>::nonZeros() const
1402 {
1403  return end() - begin();
1404 }
1406 //*************************************************************************************************
1407 
1408 
1409 //*************************************************************************************************
1415 template< typename MT // Type of the sparse matrix
1416  , bool TF // Transpose flag
1417  , ptrdiff_t... CBAs > // Compile time band arguments
1419 {
1420  using blaze::clear;
1421 
1422  if( ( IsLower<MT>::value && column() > 0UL ) ||
1423  ( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value ) && row() == 0UL ) ||
1424  ( IsUpper<MT>::value && row() > 0UL ) ||
1425  ( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value ) && column() == 0UL ) )
1426  return;
1427 
1428  const size_t n( size() );
1429  for( size_t i=0UL; i<n; ++i )
1430  matrix_.erase( row()+i, column()+i );
1431 }
1433 //*************************************************************************************************
1434 
1435 
1436 //*************************************************************************************************
1446 template< typename MT // Type of the sparse matrix
1447  , bool TF // Transpose flag
1448  , ptrdiff_t... CBAs > // Compile time band arguments
1449 void Band<MT,TF,false,false,CBAs...>::reserve( size_t n )
1450 {
1451  UNUSED_PARAMETER( n );
1452 
1453  return;
1454 }
1456 //*************************************************************************************************
1457 
1458 
1459 
1460 
1461 //=================================================================================================
1462 //
1463 // INSERTION FUNCTIONS
1464 //
1465 //=================================================================================================
1466 
1467 //*************************************************************************************************
1479 template< typename MT // Type of the sparse matrix
1480  , bool TF // Transpose flag
1481  , ptrdiff_t... CBAs > // Compile time band arguments
1482 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1483  Band<MT,TF,false,false,CBAs...>::set( size_t index, const ElementType& value )
1484 {
1485  const size_t rowIndex ( row() + index );
1486  const size_t columnIndex( column() + index );
1487  return Iterator( matrix_, rowIndex, columnIndex, matrix_.set( rowIndex, columnIndex, value ) );
1488 }
1490 //*************************************************************************************************
1491 
1492 
1493 //*************************************************************************************************
1506 template< typename MT // Type of the sparse matrix
1507  , bool TF // Transpose flag
1508  , ptrdiff_t... CBAs > // Compile time band arguments
1509 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1510  Band<MT,TF,false,false,CBAs...>::insert( size_t index, const ElementType& value )
1511 {
1512  const size_t rowIndex ( row() + index );
1513  const size_t columnIndex( column() + index );
1514  return Iterator( matrix_, rowIndex, columnIndex, matrix_.insert( rowIndex, columnIndex, value ) );
1515 }
1517 //*************************************************************************************************
1518 
1519 
1520 //*************************************************************************************************
1545 template< typename MT // Type of the sparse matrix
1546  , bool TF // Transpose flag
1547  , ptrdiff_t... CBAs > // Compile time band arguments
1548 inline void Band<MT,TF,false,false,CBAs...>::append( size_t index, const ElementType& value, bool check )
1549 {
1550  if( !check || !isDefault<strict>( value ) )
1551  matrix_.insert( row()+index, column()+index, value );
1552 }
1554 //*************************************************************************************************
1555 
1556 
1557 
1558 
1559 //=================================================================================================
1560 //
1561 // ERASE FUNCTIONS
1562 //
1563 //=================================================================================================
1564 
1565 //*************************************************************************************************
1574 template< typename MT // Type of the sparse matrix
1575  , bool TF // Transpose flag
1576  , ptrdiff_t... CBAs > // Compile time band arguments
1577 inline void Band<MT,TF,false,false,CBAs...>::erase( size_t index )
1578 {
1579  matrix_.erase( row()+index, column()+index );
1580 }
1582 //*************************************************************************************************
1583 
1584 
1585 //*************************************************************************************************
1594 template< typename MT // Type of the sparse matrix
1595  , bool TF // Transpose flag
1596  , ptrdiff_t... CBAs > // Compile time band arguments
1597 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1598  Band<MT,TF,false,false,CBAs...>::erase( Iterator pos )
1599 {
1600  const size_t rowIndex ( pos.row_ );
1601  const size_t columnIndex( pos.column_ );
1602 
1603  if( rowIndex == matrix_.rows() || columnIndex == matrix_.columns() )
1604  return pos;
1605 
1606  matrix_.erase( ( IsRowMajorMatrix<MT>::value ? rowIndex : columnIndex ), pos.pos_ );
1607  return Iterator( matrix_, rowIndex+1UL, columnIndex+1UL );
1608 }
1610 //*************************************************************************************************
1611 
1612 
1613 //*************************************************************************************************
1623 template< typename MT // Type of the sparse matrix
1624  , bool TF // Transpose flag
1625  , ptrdiff_t... CBAs > // Compile time band arguments
1626 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1627  Band<MT,TF,false,false,CBAs...>::erase( Iterator first, Iterator last )
1628 {
1629  for( ; first!=last; ++first ) {
1630  const size_t index( IsRowMajorMatrix<MT>::value ? first.row_ : first.column_ );
1631  matrix_.erase( index, first.pos_ );
1632  }
1633  return last;
1634 }
1636 //*************************************************************************************************
1637 
1638 
1639 //*************************************************************************************************
1662 template< typename MT // Type of the sparse matrix
1663  , bool TF // Transpose flag
1664  , ptrdiff_t... CBAs > // Compile time band arguments
1665 template< typename Pred // Type of the unary predicate
1666  , typename > // Type restriction on the unary predicate
1667 inline void Band<MT,TF,false,false,CBAs...>::erase( Pred predicate )
1668 {
1669  for( Iterator element=begin(); element!=end(); ++element ) {
1670  if( predicate( element->value() ) ) {
1671  const size_t index( IsRowMajorMatrix<MT>::value ? element.row_ : element.column_ );
1672  matrix_.erase( index, element.pos_ );
1673  }
1674  }
1675 }
1677 //*************************************************************************************************
1678 
1679 
1680 //*************************************************************************************************
1705 template< typename MT // Type of the sparse matrix
1706  , bool TF // Transpose flag
1707  , ptrdiff_t... CBAs > // Compile time band arguments
1708 template< typename Pred > // Type of the unary predicate
1709 inline void Band<MT,TF,false,false,CBAs...>::erase( Iterator first, Iterator last, Pred predicate )
1710 {
1711  for( ; first!=last; ++first ) {
1712  if( predicate( first->value() ) ) {
1713  const size_t index( IsRowMajorMatrix<MT>::value ? first.row_ : first.column_ );
1714  matrix_.erase( index, first.pos_ );
1715  }
1716  }
1717 }
1719 //*************************************************************************************************
1720 
1721 
1722 
1723 
1724 //=================================================================================================
1725 //
1726 // LOOKUP FUNCTIONS
1727 //
1728 //=================================================================================================
1729 
1730 //*************************************************************************************************
1744 template< typename MT // Type of the sparse matrix
1745  , bool TF // Transpose flag
1746  , ptrdiff_t... CBAs > // Compile time band arguments
1747 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1748  Band<MT,TF,false,false,CBAs...>::find( size_t index )
1749 {
1750  const size_t rowIndex ( row()+index );
1751  const size_t columnIndex( column()+index );
1752  const Iterator_<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1753 
1754  if( pos != matrix_.end( IsRowMajorMatrix<MT>::value ? rowIndex : columnIndex ) )
1755  return Iterator( matrix_, rowIndex, columnIndex, pos );
1756  else
1757  return end();
1758 }
1760 //*************************************************************************************************
1761 
1762 
1763 //*************************************************************************************************
1777 template< typename MT // Type of the sparse matrix
1778  , bool TF // Transpose flag
1779  , ptrdiff_t... CBAs > // Compile time band arguments
1780 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
1781  Band<MT,TF,false,false,CBAs...>::find( size_t index ) const
1782 {
1783  const size_t rowIndex ( row()+index );
1784  const size_t columnIndex( column()+index );
1785  const ConstIterator_<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1786 
1787  if( pos != matrix_.end( IsRowMajorMatrix<MT>::value ? rowIndex : columnIndex ) )
1788  return ConstIterator( matrix_, rowIndex, columnIndex, pos );
1789  else
1790  return end();
1791 }
1793 //*************************************************************************************************
1794 
1795 
1796 //*************************************************************************************************
1809 template< typename MT // Type of the sparse matrix
1810  , bool TF // Transpose flag
1811  , ptrdiff_t... CBAs > // Compile time band arguments
1812 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1813  Band<MT,TF,false,false,CBAs...>::lowerBound( size_t index )
1814 {
1815  for( size_t i=index; i<size(); ++i )
1816  {
1817  const size_t rowIndex ( row()+i );
1818  const size_t columnIndex( column()+i );
1819  const Iterator_<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1820 
1821  if( pos != matrix_.end( IsRowMajorMatrix<MT>::value ? rowIndex : columnIndex ) )
1822  return Iterator( matrix_, rowIndex, columnIndex, pos );
1823  }
1824 
1825  return end();
1826 }
1828 //*************************************************************************************************
1829 
1830 
1831 //*************************************************************************************************
1844 template< typename MT // Type of the sparse matrix
1845  , bool TF // Transpose flag
1846  , ptrdiff_t... CBAs > // Compile time band arguments
1847 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
1848  Band<MT,TF,false,false,CBAs...>::lowerBound( size_t index ) const
1849 {
1850  for( size_t i=index; i<size(); ++i )
1851  {
1852  const size_t rowIndex ( row()+i );
1853  const size_t columnIndex( column()+i );
1854  const ConstIterator_<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1855 
1856  if( pos != matrix_.end( IsRowMajorMatrix<MT>::value ? rowIndex : columnIndex ) )
1857  return ConstIterator( matrix_, rowIndex, columnIndex, pos );
1858  }
1859 
1860  return end();
1861 }
1863 //*************************************************************************************************
1864 
1865 
1866 //*************************************************************************************************
1879 template< typename MT // Type of the sparse matrix
1880  , bool TF // Transpose flag
1881  , ptrdiff_t... CBAs > // Compile time band arguments
1882 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1883  Band<MT,TF,false,false,CBAs...>::upperBound( size_t index )
1884 {
1885  for( size_t i=index+1UL; i<size(); ++i )
1886  {
1887  const size_t rowIndex ( row()+i );
1888  const size_t columnIndex( column()+i );
1889  const Iterator_<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1890 
1891  if( pos != matrix_.end( IsRowMajorMatrix<MT>::value ? rowIndex : columnIndex ) )
1892  return Iterator( matrix_, rowIndex, columnIndex, pos );
1893  }
1894 
1895  return end();
1896 }
1898 //*************************************************************************************************
1899 
1900 
1901 //*************************************************************************************************
1914 template< typename MT // Type of the sparse matrix
1915  , bool TF // Transpose flag
1916  , ptrdiff_t... CBAs > // Compile time band arguments
1917 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
1918  Band<MT,TF,false,false,CBAs...>::upperBound( size_t index ) const
1919 {
1920  for( size_t i=index+1UL; i<size(); ++i )
1921  {
1922  const size_t rowIndex ( row()+i );
1923  const size_t columnIndex( column()+i );
1924  const ConstIterator_<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1925 
1926  if( pos != matrix_.end( IsRowMajorMatrix<MT>::value ? rowIndex : columnIndex ) )
1927  return ConstIterator( matrix_, rowIndex, columnIndex, pos );
1928  }
1929 
1930  return end();
1931 }
1933 //*************************************************************************************************
1934 
1935 
1936 
1937 
1938 //=================================================================================================
1939 //
1940 // NUMERIC FUNCTIONS
1941 //
1942 //=================================================================================================
1943 
1944 //*************************************************************************************************
1957 template< typename MT // Type of the sparse matrix
1958  , bool TF // Transpose flag
1959  , ptrdiff_t... CBAs > // Compile time band arguments
1960 template< typename Other > // Data type of the scalar value
1961 inline Band<MT,TF,false,false,CBAs...>&
1962  Band<MT,TF,false,false,CBAs...>::scale( const Other& scalar )
1963 {
1965 
1966  if( ( IsLower<MT>::value && column() > 0UL ) ||
1967  ( IsStrictlyLower<MT>::value && row() == 0UL ) ||
1968  ( IsUpper<MT>::value && row() > 0UL ) ||
1969  ( IsStrictlyUpper<MT>::value && column() == 0UL ) )
1970  return *this;
1971 
1972  for( Iterator element=begin(); element!=end(); ++element )
1973  element->value() *= scalar;
1974 
1975  return *this;
1976 }
1978 //*************************************************************************************************
1979 
1980 
1981 
1982 
1983 //=================================================================================================
1984 //
1985 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1986 //
1987 //=================================================================================================
1988 
1989 //*************************************************************************************************
2000 template< typename MT // Type of the sparse matrix
2001  , bool TF // Transpose flag
2002  , ptrdiff_t... CBAs > // Compile time band arguments
2003 template< typename Other > // Data type of the foreign expression
2004 inline bool Band<MT,TF,false,false,CBAs...>::canAlias( const Other* alias ) const noexcept
2005 {
2006  return matrix_.isAliased( alias );
2007 }
2009 //*************************************************************************************************
2010 
2011 
2012 //*************************************************************************************************
2023 template< typename MT // Type of the sparse matrix
2024  , bool TF // Transpose flag
2025  , ptrdiff_t... CBAs > // Compile time band arguments
2026 template< typename Other > // Data type of the foreign expression
2027 inline bool Band<MT,TF,false,false,CBAs...>::isAliased( const Other* alias ) const noexcept
2028 {
2029  return matrix_.isAliased( alias );
2030 }
2032 //*************************************************************************************************
2033 
2034 
2035 //*************************************************************************************************
2047 template< typename MT // Type of the sparse matrix
2048  , bool TF // Transpose flag
2049  , ptrdiff_t... CBAs > // Compile time band arguments
2050 template< typename VT > // Type of the right-hand side dense vector
2051 inline void Band<MT,TF,false,false,CBAs...>::assign( const DenseVector<VT,TF>& rhs )
2052 {
2053  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2054 
2055  for( size_t i=0UL; i<(~rhs).size(); ++i ) {
2056  matrix_(row()+i,column()+i) = (~rhs)[i];
2057  }
2058 }
2060 //*************************************************************************************************
2061 
2062 
2063 //*************************************************************************************************
2075 template< typename MT // Type of the sparse matrix
2076  , bool TF // Transpose flag
2077  , ptrdiff_t... CBAs > // Compile time band arguments
2078 template< typename VT > // Type of the right-hand side sparse vector
2079 inline void Band<MT,TF,false,false,CBAs...>::assign( const SparseVector<VT,TF>& rhs )
2080 {
2081  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2082 
2083  size_t i( 0UL );
2084 
2085  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2086  for( ; i<element->index(); ++i )
2087  matrix_.erase( row()+i, column()+i );
2088  matrix_(row()+i,column()+i) = element->value();
2089  ++i;
2090  }
2091  for( ; i<size(); ++i ) {
2092  matrix_.erase( row()+i, column()+i );
2093  }
2094 }
2096 //*************************************************************************************************
2097 
2098 
2099 //*************************************************************************************************
2111 template< typename MT // Type of the sparse matrix
2112  , bool TF // Transpose flag
2113  , ptrdiff_t... CBAs > // Compile time band arguments
2114 template< typename VT > // Type of the right-hand side vector
2115 inline void Band<MT,TF,false,false,CBAs...>::addAssign( const Vector<VT,TF>& rhs )
2116 {
2117  using AddType = AddTrait_< ResultType, ResultType_<VT> >;
2118 
2121 
2122  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2123 
2124  const AddType tmp( serial( *this + (~rhs) ) );
2125  assign( tmp );
2126 }
2128 //*************************************************************************************************
2129 
2130 
2131 //*************************************************************************************************
2143 template< typename MT // Type of the sparse matrix
2144  , bool TF // Transpose flag
2145  , ptrdiff_t... CBAs > // Compile time band arguments
2146 template< typename VT > // Type of the right-hand side vector
2147 inline void Band<MT,TF,false,false,CBAs...>::subAssign( const Vector<VT,TF>& rhs )
2148 {
2149  using SubType = SubTrait_< ResultType, ResultType_<VT> >;
2150 
2153 
2154  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2155 
2156  const SubType tmp( serial( *this - (~rhs) ) );
2157  assign( tmp );
2158 }
2160 //*************************************************************************************************
2161 
2162 
2163 
2164 
2165 //=================================================================================================
2166 //
2167 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRIX MULTIPLICATIONS
2168 //
2169 //=================================================================================================
2170 
2171 //*************************************************************************************************
2179 template< typename MT // Type of the sparse matrix multiplication
2180  , bool TF // Transpose flag
2181  , ptrdiff_t... CBAs > // Compile time band arguments
2182 class Band<MT,TF,false,true,CBAs...>
2183  : public View< SparseVector< Band<MT,TF,false,true,CBAs...>, TF > >
2184  , private BandData<CBAs...>
2185  , private Computation
2186 {
2187  private:
2188  //**Type definitions****************************************************************************
2190  using DataType = BandData<CBAs...>;
2191 
2193  using LeftOperand = RemoveReference_< LeftOperand_<MT> >;
2194 
2196  using RightOperand = RemoveReference_< RightOperand_<MT> >;
2197  //**********************************************************************************************
2198 
2199  public:
2200  //**Type definitions****************************************************************************
2202  using This = Band<MT,TF,false,true,CBAs...>;
2203 
2205  using BaseType = SparseVector<This,TF>;
2206 
2208  using ViewedType = MT;
2209 
2211  using ResultType = BandTrait_<ResultType_<MT>,CBAs...>;
2212 
2213  using TransposeType = TransposeType_<ResultType>;
2214  using ElementType = ElementType_<ResultType>;
2215  using ReturnType = ReturnType_<MT>;
2216  using CompositeType = const ResultType;
2217 
2219  using LT = If_< And< IsSparseMatrix<LeftOperand>, IsColumnMajorMatrix<LeftOperand> >
2220  , ResultType_<LeftOperand>
2221  , CompositeType_<LeftOperand> >;
2222 
2224  using RT = If_< And< IsSparseMatrix<RightOperand>, IsRowMajorMatrix<RightOperand> >
2225  , ResultType_<RightOperand>
2226  , CompositeType_<RightOperand> >;
2227  //**********************************************************************************************
2228 
2229  //**Compilation flags***************************************************************************
2231  enum : bool { smpAssignable = false };
2232  //**********************************************************************************************
2233 
2234  //**Constructor*********************************************************************************
2241  template< typename... RBAs > // Runtime band arguments
2242  explicit inline Band( const MT& mmm, RBAs... args )
2243  : DataType( args... ) // Base class initialization
2244  , matrix_ ( mmm ) // The matrix multiplication containing the band
2245  {
2246  if( !Contains< TypeList<RBAs...>, Unchecked >::value ) {
2247  if( ( band() > 0L && column() >= mmm.columns() ) ||
2248  ( band() < 0L && row() >= mmm.rows() ) ) {
2249  BLAZE_THROW_INVALID_ARGUMENT( "Invalid band access index" );
2250  }
2251  }
2252  else {
2253  BLAZE_USER_ASSERT( band() < 0L || column() < mmm.columns(), "Invalid band access index" );
2254  BLAZE_USER_ASSERT( band() > 0L || row() < mmm.rows(), "Invalid band access index" );
2255  }
2256  }
2257  //**********************************************************************************************
2258 
2259  //**Subscript operator**************************************************************************
2265  inline ReturnType operator[]( size_t index ) const {
2266  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
2267  return matrix_(row()+index,column()+index);
2268  }
2269  //**********************************************************************************************
2270 
2271  //**At function*********************************************************************************
2278  inline ReturnType at( size_t index ) const {
2279  if( index >= size() ) {
2280  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
2281  }
2282  return (*this)[index];
2283  }
2284  //**********************************************************************************************
2285 
2286  //**Size function*******************************************************************************
2291  inline size_t size() const noexcept {
2292  return min( matrix_.rows() - row(), matrix_.columns() - column() );
2293  }
2294  //**********************************************************************************************
2295 
2296  //**NonZeros function***************************************************************************
2301  inline size_t nonZeros() const {
2302  return 0UL;
2303  }
2304  //**********************************************************************************************
2305 
2306  //**********************************************************************************************
2307  using DataType::band;
2308  using DataType::row;
2309  using DataType::column;
2310  //**********************************************************************************************
2311 
2312  //**Operand access******************************************************************************
2317  inline const MT& operand() const noexcept {
2318  return matrix_;
2319  }
2320  //**********************************************************************************************
2321 
2322  //**********************************************************************************************
2328  template< typename T >
2329  inline bool canAlias( const T* alias ) const noexcept {
2330  return matrix_.isAliased( alias );
2331  }
2332  //**********************************************************************************************
2333 
2334  //**********************************************************************************************
2340  template< typename T >
2341  inline bool isAliased( const T* alias ) const noexcept {
2342  return matrix_.isAliased( alias );
2343  }
2344  //**********************************************************************************************
2345 
2346  private:
2347  //**Member variables****************************************************************************
2348  MT matrix_;
2349  //**********************************************************************************************
2350 
2351  //**Assignment to dense vectors*****************************************************************
2363  template< typename VT > // Type of the target dense vector
2364  friend inline void assign( DenseVector<VT,TF>& lhs, const Band& rhs )
2365  {
2366  using blaze::row;
2367  using blaze::column;
2368 
2370 
2371  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2372 
2373  LT A( serial( rhs.operand().leftOperand() ) );
2374  RT B( serial( rhs.operand().rightOperand() ) );
2375 
2376  const size_t n( rhs.size() );
2377  for( size_t i=0UL; i<n; ++i ) {
2378  (~lhs)[i] = row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2379  }
2380  }
2382  //**********************************************************************************************
2383 
2384  //**Assignment to sparse vectors****************************************************************
2396  template< typename VT > // Type of the target sparse vector
2397  friend inline void assign( SparseVector<VT,TF>& lhs, const Band& rhs )
2398  {
2399  using blaze::row;
2400  using blaze::column;
2401 
2403 
2404  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2405 
2406  LT A( serial( rhs.operand().leftOperand() ) );
2407  RT B( serial( rhs.operand().rightOperand() ) );
2408 
2409  const size_t n( rhs.size() );
2410  ElementType_<VT> tmp{};
2411  size_t nonzeros( 0UL );
2412 
2413  for( size_t i=0UL; i<n; ++i ) {
2414  tmp = row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2415  if( !isDefault<strict>( tmp ) ) {
2416  if( (~lhs).capacity() <= nonzeros ) {
2417  (~lhs).reserve( min( max( 2UL*(~lhs).capacity(), 7UL ), (~lhs).size() ) );
2418  }
2419  (~lhs).append( i, tmp, false );
2420  ++nonzeros;
2421  }
2422  }
2423  }
2425  //**********************************************************************************************
2426 
2427  //**Addition assignment to dense vectors********************************************************
2439  template< typename VT > // Type of the target dense vector
2440  friend inline void addAssign( DenseVector<VT,TF>& lhs, const Band& rhs )
2441  {
2442  using blaze::row;
2443  using blaze::column;
2444 
2446 
2447  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2448 
2449  LT A( serial( rhs.operand().leftOperand() ) );
2450  RT B( serial( rhs.operand().rightOperand() ) );
2451 
2452  const size_t n( rhs.size() );
2453  for( size_t i=0UL; i<n; ++i ) {
2454  (~lhs)[i] += row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2455  }
2456  }
2458  //**********************************************************************************************
2459 
2460  //**Addition assignment to sparse vectors*******************************************************
2461  // No special implementation for the addition assignment to sparse vectors.
2462  //**********************************************************************************************
2463 
2464  //**Subtraction assignment to dense vectors*****************************************************
2476  template< typename VT > // Type of the target dense vector
2477  friend inline void subAssign( DenseVector<VT,TF>& lhs, const Band& rhs )
2478  {
2479  using blaze::row;
2480  using blaze::column;
2481 
2483 
2484  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2485 
2486  LT A( serial( rhs.operand().leftOperand() ) );
2487  RT B( serial( rhs.operand().rightOperand() ) );
2488 
2489  const size_t n( rhs.size() );
2490  for( size_t i=0UL; i<n; ++i ) {
2491  (~lhs)[i] -= row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2492  }
2493  }
2495  //**********************************************************************************************
2496 
2497  //**Subtraction assignment to sparse vectors****************************************************
2498  // No special implementation for the subtraction assignment to sparse vectors.
2499  //**********************************************************************************************
2500 
2501  //**Multiplication assignment to dense vectors**************************************************
2514  template< typename VT > // Type of the target dense vector
2515  friend inline void multAssign( DenseVector<VT,TF>& lhs, const Band& rhs )
2516  {
2517  using blaze::row;
2518  using blaze::column;
2519 
2521 
2522  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2523 
2524  LT A( serial( rhs.operand().leftOperand() ) );
2525  RT B( serial( rhs.operand().rightOperand() ) );
2526 
2527  const size_t n( rhs.size() );
2528  for( size_t i=0UL; i<n; ++i ) {
2529  (~lhs)[i] *= row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2530  }
2531  }
2533  //**********************************************************************************************
2534 
2535  //**Multiplication assignment to sparse vectors*************************************************
2536  // No special implementation for the multiplication assignment to sparse vectors.
2537  //**********************************************************************************************
2538 
2539  //**Compile time checks*************************************************************************
2546  //**********************************************************************************************
2547 };
2548 //*************************************************************************************************
2549 
2550 } // namespace blaze
2551 
2552 #endif
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:131
Headerfile for the generic min algorithm.
Header file for the blaze::checked and blaze::unchecked instances.
#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.
Header file for the subtraction trait.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:522
Header file for basic type definitions.
Header file for the SparseVector base class.
Header file for the View base class.
Header file for the IsSparseMatrix type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#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:81
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3076
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:364
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3074
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:588
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
Header file for the IsIntegral type trait.
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3078
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
Header file for the DenseVector base class.
#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:81
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3083
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:560
Header file for the implementation of the Band base template.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:733
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3084
#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:81
Header file for the IsUniLower type trait.
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1950
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:474
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:408
Header file for the band trait.
Constraint on the data type.
Constraint on the data type.
Headerfile for the generic max algorithm.
Header file for the DisableIf class template.
Header file for the multiplication trait.
Header file for the IsStrictlyUpper type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3082
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the If class template.
Header file for the implementation of a vector representation of an initializer list.
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
#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:79
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3079
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
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:61
Constraint on the data type.
Header file for the SparseElement base class.
Constraint on the data type.
Header file for the exception macros of the math module.
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:430
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Constraint on the data type.
typename BandTrait< MT, CBAs... >::Type BandTrait_
Auxiliary alias declaration for the BandTrait type trait.The BandTrait_ alias declaration provides a ...
Definition: BandTrait.h:145
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:608
decltype(auto) band(Matrix< MT, SO > &matrix, RBAs... args)
Creating a view on a specific band of the given matrix.
Definition: Band.h:134
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_MATMATMULTEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is not a matrix/matrix multiplication expre...
Definition: MatMatMultExpr.h:67
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:76
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the relaxation flag types.
Header file for the addition trait.
Header file for the cross product trait.
Header file for the division trait.
Header file for the Unique class template.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance...
Definition: Check.h:96
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:131
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
#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:79
Header file for the isDefault shim.
Constraint on the data type.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:816
#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:81
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
#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:61
EnableIf_< IsNumeric< ST >, MT &> operator/=(DenseMatrix< MT, SO > &mat, ST scalar)
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:655
Header file for the IsRowMajorMatrix type trait.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3081
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
EnableIf_< IsNumeric< ST >, MT &> operator*=(DenseMatrix< MT, SO > &mat, ST scalar)
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:593
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:63
#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:61
Header file for the IsExpression type trait class.
Header file for the implementation of the BandData class template.