Blaze  3.6
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/MaybeUnused.h>
86 #include <blaze/util/mpl/If.h>
87 #include <blaze/util/TypeList.h>
88 #include <blaze/util/Types.h>
92 
93 
94 namespace blaze {
95 
96 //=================================================================================================
97 //
98 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRICES
99 //
100 //=================================================================================================
101 
102 //*************************************************************************************************
109 template< typename MT // Type of the sparse matrix
110  , bool TF // Transpose flag
111  , ptrdiff_t... CBAs > // Compile time band arguments
112 class Band<MT,TF,false,false,CBAs...>
113  : public View< SparseVector< Band<MT,TF,false,false,CBAs...>, TF > >
114  , private BandData<CBAs...>
115 {
116  private:
117  //**Type definitions****************************************************************************
118  using RT = ResultType_t<MT>;
119  using DataType = BandData<CBAs...>;
120  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
121  //**********************************************************************************************
122 
123  public:
124  //**Type definitions****************************************************************************
126  using This = Band<MT,TF,false,false,CBAs...>;
127 
128  using BaseType = SparseVector<This,TF>;
129  using ViewedType = MT;
130  using ResultType = BandTrait_t<RT,CBAs...>;
131  using TransposeType = TransposeType_t<ResultType>;
132  using ElementType = ElementType_t<MT>;
133  using ReturnType = ReturnType_t<MT>;
134 
136  using CompositeType = If_t< RequiresEvaluation_v<MT>, const ResultType, const Band& >;
137 
139  using ConstReference = ConstReference_t<MT>;
140 
142  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
143  //**********************************************************************************************
144 
145  //**BandElement class definition****************************************************************
148  template< typename MatrixType // Type of the sparse matrix
149  , typename IteratorType > // Type of the sparse matrix iterator
150  class BandElement
151  : private SparseElement
152  {
153  public:
154  //**Constructor******************************************************************************
160  inline BandElement( IteratorType pos, size_t index )
161  : pos_ ( pos ) // Iterator to the current position within the sparse band
162  , index_( index ) // Index of the element
163  {}
164  //*******************************************************************************************
165 
166  //**Assignment operator**********************************************************************
172  template< typename T > inline BandElement& operator=( const T& v ) {
173  *pos_ = v;
174  return *this;
175  }
176  //*******************************************************************************************
177 
178  //**Addition assignment operator*************************************************************
184  template< typename T > inline BandElement& operator+=( const T& v ) {
185  *pos_ += v;
186  return *this;
187  }
188  //*******************************************************************************************
189 
190  //**Subtraction assignment operator**********************************************************
196  template< typename T > inline BandElement& operator-=( const T& v ) {
197  *pos_ -= v;
198  return *this;
199  }
200  //*******************************************************************************************
201 
202  //**Multiplication assignment operator*******************************************************
208  template< typename T > inline BandElement& operator*=( const T& v ) {
209  *pos_ *= v;
210  return *this;
211  }
212  //*******************************************************************************************
213 
214  //**Division assignment operator*************************************************************
220  template< typename T > inline BandElement& operator/=( const T& v ) {
221  *pos_ /= v;
222  return *this;
223  }
224  //*******************************************************************************************
225 
226  //**Element access operator******************************************************************
231  inline const BandElement* operator->() const {
232  return this;
233  }
234  //*******************************************************************************************
235 
236  //**Value function***************************************************************************
241  inline decltype(auto) value() const {
242  return pos_->value();
243  }
244  //*******************************************************************************************
245 
246  //**Index function***************************************************************************
251  inline size_t index() const {
252  return index_;
253  }
254  //*******************************************************************************************
255 
256  private:
257  //**Member variables*************************************************************************
258  IteratorType pos_;
259  size_t index_;
260  //*******************************************************************************************
261  };
262  //**********************************************************************************************
263 
264  //**BandIterator class definition***************************************************************
267  template< typename MatrixType // Type of the sparse matrix
268  , typename IteratorType > // Type of the sparse matrix iterator
269  class BandIterator
270  {
271  public:
272  //**Type definitions*************************************************************************
273  using IteratorCategory = std::forward_iterator_tag;
274  using ValueType = BandElement<MatrixType,IteratorType>;
275  using PointerType = ValueType;
276  using ReferenceType = ValueType;
277  using DifferenceType = ptrdiff_t;
278 
279  // STL iterator requirements
280  using iterator_category = IteratorCategory;
281  using value_type = ValueType;
282  using pointer = PointerType;
283  using reference = ReferenceType;
284  using difference_type = DifferenceType;
285  //*******************************************************************************************
286 
287  //**Constructor******************************************************************************
290  inline BandIterator()
291  : matrix_( nullptr ) // The sparse matrix containing the band
292  , row_ ( 0UL ) // The current row index
293  , column_( 0UL ) // The current column index
294  , pos_ () // Iterator to the current sparse element
295  {}
296  //*******************************************************************************************
297 
298  //**Constructor******************************************************************************
305  inline BandIterator( MatrixType& matrix, size_t rowIndex, size_t columnIndex )
306  : matrix_( &matrix ) // The sparse matrix containing the band
307  , row_ ( rowIndex ) // The current row index
308  , column_( columnIndex ) // The current column index
309  , pos_ () // Iterator to the current sparse element
310  {
311  for( ; row_ < matrix_->rows() && column_ < matrix_->columns(); ++row_, ++column_ ) {
312  pos_ = matrix_->find( row_, column_ );
313  if( pos_ != matrix_->end( IsRowMajorMatrix_v<MatrixType> ? row_ : column_ ) )
314  break;
315  }
316  }
317  //*******************************************************************************************
318 
319  //**Constructor******************************************************************************
327  inline BandIterator( MatrixType& matrix, size_t rowIndex, size_t columnIndex, IteratorType pos )
328  : matrix_( &matrix ) // The sparse matrix containing the band
329  , row_ ( rowIndex ) // The current row index
330  , column_( columnIndex ) // The current column index
331  , pos_ ( pos ) // Iterator to the current sparse element
332  {
333  BLAZE_INTERNAL_ASSERT( matrix.find( row_, column_ ) == pos, "Invalid initial iterator position" );
334  }
335  //*******************************************************************************************
336 
337  //**Constructor******************************************************************************
342  template< typename MatrixType2, typename IteratorType2 >
343  inline BandIterator( const BandIterator<MatrixType2,IteratorType2>& it )
344  : matrix_( it.matrix_ ) // The sparse matrix containing the band
345  , row_ ( it.row_ ) // The current row index
346  , column_( it.column_ ) // The current column index
347  , pos_ ( it.pos_ ) // Iterator to the current sparse element
348  {}
349  //*******************************************************************************************
350 
351  //**Prefix increment operator****************************************************************
356  inline BandIterator& operator++() {
357  ++row_;
358  ++column_;
359 
360  for( ; row_ < matrix_->rows() && column_ < matrix_->columns(); ++row_, ++column_ ) {
361  pos_ = matrix_->find( row_, column_ );
362  if( pos_ != matrix_->end( IsRowMajorMatrix_v<MatrixType> ? row_ : column_ ) )
363  break;
364  }
365 
366  return *this;
367  }
368  //*******************************************************************************************
369 
370  //**Postfix increment operator***************************************************************
375  inline const BandIterator operator++( int ) {
376  const BandIterator tmp( *this );
377  ++(*this);
378  return tmp;
379  }
380  //*******************************************************************************************
381 
382  //**Element access operator******************************************************************
387  inline ReferenceType operator*() const {
388  return ReferenceType( pos_, min( row_, column_ ) );
389  }
390  //*******************************************************************************************
391 
392  //**Element access operator******************************************************************
397  inline PointerType operator->() const {
398  return PointerType( pos_, min( row_, column_ ) );
399  }
400  //*******************************************************************************************
401 
402  //**Equality operator************************************************************************
408  template< typename MatrixType2, typename IteratorType2 >
409  inline bool operator==( const BandIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
410  return row_ == rhs.row_;
411  }
412  //*******************************************************************************************
413 
414  //**Inequality operator**********************************************************************
420  template< typename MatrixType2, typename IteratorType2 >
421  inline bool operator!=( const BandIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
422  return !( *this == rhs );
423  }
424  //*******************************************************************************************
425 
426  //**Subtraction operator*********************************************************************
432  inline DifferenceType operator-( const BandIterator& rhs ) const {
433  size_t counter( 0UL );
434  size_t row( rhs.row_ );
435  size_t column( rhs.column_ );
436 
437  for( ; row<row_; ++row, ++column ) {
438  const auto end( matrix_->end( IsRowMajorMatrix_v<MatrixType> ? row : column ) );
439  if( matrix_->find( row, column ) != end )
440  ++counter;
441  }
442 
443  return counter;
444  }
445  //*******************************************************************************************
446 
447  private:
448  //**Member variables*************************************************************************
449  MatrixType* matrix_;
450  size_t row_;
451  size_t column_;
452  IteratorType pos_;
453  //*******************************************************************************************
454 
455  //**Friend declarations**********************************************************************
456  template< typename MatrixType2, typename IteratorType2 > friend class BandIterator;
457  template< typename MT2, bool DF2, bool TF2, bool MF2, ptrdiff_t... CBAs2 > friend class Band;
458  //*******************************************************************************************
459  };
460  //**********************************************************************************************
461 
462  //**Type definitions****************************************************************************
464  using ConstIterator = BandIterator< const MT, ConstIterator_t<MT> >;
465 
467  using Iterator = If_t< IsConst_v<MT>, ConstIterator, BandIterator< MT, Iterator_t<MT> > >;
468  //**********************************************************************************************
469 
470  //**Compilation flags***************************************************************************
472  static constexpr bool smpAssignable = false;
473 
475  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
476  //**********************************************************************************************
477 
478  //**Constructors********************************************************************************
481  template< typename... RBAs >
482  explicit inline Band( MT& matrix, RBAs... args );
483 
484  Band( const Band& ) = default;
486  //**********************************************************************************************
487 
488  //**Destructor**********************************************************************************
491  ~Band() = default;
493  //**********************************************************************************************
494 
495  //**Data access functions***********************************************************************
498  inline Reference operator[]( size_t index );
499  inline ConstReference operator[]( size_t index ) const;
500  inline Reference at( size_t index );
501  inline ConstReference at( size_t index ) const;
502  inline Iterator begin ();
503  inline ConstIterator begin () const;
504  inline ConstIterator cbegin() const;
505  inline Iterator end ();
506  inline ConstIterator end () const;
507  inline ConstIterator cend () const;
509  //**********************************************************************************************
510 
511  //**Assignment operators************************************************************************
514  inline Band& operator= ( initializer_list<ElementType> list );
515  inline Band& operator= ( const Band& rhs );
516  template< typename VT > inline Band& operator= ( const Vector<VT,TF>& rhs );
517  template< typename VT > inline Band& operator+=( const Vector<VT,TF>& rhs );
518  template< typename VT > inline Band& operator-=( const Vector<VT,TF>& rhs );
519  template< typename VT > inline Band& operator*=( const Vector<VT,TF>& rhs );
520  template< typename VT > inline Band& operator/=( const DenseVector<VT,TF>& rhs );
521  template< typename VT > inline Band& operator%=( const Vector<VT,TF>& rhs );
523  //**********************************************************************************************
524 
525  //**Utility functions***************************************************************************
528  using DataType::band;
529  using DataType::row;
530  using DataType::column;
531 
532  inline MT& operand() noexcept;
533  inline const MT& operand() const noexcept;
534 
535  inline size_t size() const noexcept;
536  inline size_t capacity() const noexcept;
537  inline size_t nonZeros() const;
538  inline void reset();
539  inline void reserve( size_t n );
541  //**********************************************************************************************
542 
543  //**Insertion functions*************************************************************************
546  inline Iterator set ( size_t index, const ElementType& value );
547  inline Iterator insert( size_t index, const ElementType& value );
548  inline void append( size_t index, const ElementType& value, bool check=false );
550  //**********************************************************************************************
551 
552  //**Erase functions*****************************************************************************
555  inline void erase( size_t index );
556  inline Iterator erase( Iterator pos );
557  inline Iterator erase( Iterator first, Iterator last );
558 
559  template< typename Pred, typename = DisableIf_t< IsIntegral_v<Pred> > >
560  inline void erase( Pred predicate );
561 
562  template< typename Pred >
563  inline void erase( Iterator first, Iterator last, Pred predicate );
565  //**********************************************************************************************
566 
567  //**Lookup functions****************************************************************************
570  inline Iterator find ( size_t index );
571  inline ConstIterator find ( size_t index ) const;
572  inline Iterator lowerBound( size_t index );
573  inline ConstIterator lowerBound( size_t index ) const;
574  inline Iterator upperBound( size_t index );
575  inline ConstIterator upperBound( size_t index ) const;
577  //**********************************************************************************************
578 
579  //**Numeric functions***************************************************************************
582  template< typename Other > inline Band& scale( const Other& scalar );
584  //**********************************************************************************************
585 
586  //**Expression template evaluation functions****************************************************
589  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
590  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
591 
592  template< typename VT > inline void assign ( const DenseVector <VT,TF>& rhs );
593  template< typename VT > inline void assign ( const SparseVector<VT,TF>& rhs );
594  template< typename VT > inline void addAssign( const Vector<VT,TF>& rhs );
595  template< typename VT > inline void subAssign( const Vector<VT,TF>& rhs );
597  //**********************************************************************************************
598 
599  private:
600  //**Member variables****************************************************************************
603  Operand matrix_;
604 
605  //**********************************************************************************************
606 
607  //**Compile time checks*************************************************************************
613  //**********************************************************************************************
614 };
616 //*************************************************************************************************
617 
618 
619 
620 
621 //=================================================================================================
622 //
623 // CONSTRUCTORS
624 //
625 //=================================================================================================
626 
627 //*************************************************************************************************
640 template< typename MT // Type of the sparse matrix
641  , bool TF // Transpose flag
642  , ptrdiff_t... CBAs > // Compile time band arguments
643 template< typename... RBAs > // Runtime band arguments
644 inline Band<MT,TF,false,false,CBAs...>::Band( MT& matrix, RBAs... args )
645  : DataType( args... ) // Base class initialization
646  , matrix_ ( matrix ) // The matrix containing the band
647 {
648  if( !Contains_v< TypeList<RBAs...>, Unchecked > ) {
649  if( ( band() > 0L && column() >= matrix.columns() ) ||
650  ( band() < 0L && row() >= matrix.rows() ) ) {
651  BLAZE_THROW_INVALID_ARGUMENT( "Invalid band access index" );
652  }
653  }
654  else {
655  BLAZE_USER_ASSERT( band() <= 0L || column() < matrix.columns(), "Invalid band access index" );
656  BLAZE_USER_ASSERT( band() >= 0L || row() < matrix.rows(), "Invalid band access index" );
657  }
658 }
660 //*************************************************************************************************
661 
662 
663 
664 
665 //=================================================================================================
666 //
667 // DATA ACCESS FUNCTIONS
668 //
669 //=================================================================================================
670 
671 //*************************************************************************************************
681 template< typename MT // Type of the sparse matrix
682  , bool TF // Transpose flag
683  , ptrdiff_t... CBAs > // Compile time band arguments
684 inline typename Band<MT,TF,false,false,CBAs...>::Reference
685  Band<MT,TF,false,false,CBAs...>::operator[]( size_t index )
686 {
687  BLAZE_USER_ASSERT( index < size(), "Invalid band access index" );
688  return matrix_(row()+index,column()+index);
689 }
691 //*************************************************************************************************
692 
693 
694 //*************************************************************************************************
704 template< typename MT // Type of the sparse matrix
705  , bool TF // Transpose flag
706  , ptrdiff_t... CBAs > // Compile time band arguments
707 inline typename Band<MT,TF,false,false,CBAs...>::ConstReference
708  Band<MT,TF,false,false,CBAs...>::operator[]( size_t index ) const
709 {
710  BLAZE_USER_ASSERT( index < size(), "Invalid band access index" );
711  return const_cast<const MT&>( matrix_ )(row()+index,column()+index);
712 }
714 //*************************************************************************************************
715 
716 
717 //*************************************************************************************************
728 template< typename MT // Type of the sparse matrix
729  , bool TF // Transpose flag
730  , ptrdiff_t... CBAs > // Compile time band arguments
731 inline typename Band<MT,TF,false,false,CBAs...>::Reference
732  Band<MT,TF,false,false,CBAs...>::at( size_t index )
733 {
734  if( index >= size() ) {
735  BLAZE_THROW_OUT_OF_RANGE( "Invalid band access index" );
736  }
737  return (*this)[index];
738 }
740 //*************************************************************************************************
741 
742 
743 //*************************************************************************************************
754 template< typename MT // Type of the sparse matrix
755  , bool TF // Transpose flag
756  , ptrdiff_t... CBAs > // Compile time band arguments
757 inline typename Band<MT,TF,false,false,CBAs...>::ConstReference
758  Band<MT,TF,false,false,CBAs...>::at( size_t index ) const
759 {
760  if( index >= size() ) {
761  BLAZE_THROW_OUT_OF_RANGE( "Invalid band access index" );
762  }
763  return (*this)[index];
764 }
766 //*************************************************************************************************
767 
768 
769 //*************************************************************************************************
777 template< typename MT // Type of the sparse matrix
778  , bool TF // Transpose flag
779  , ptrdiff_t... CBAs > // Compile time band arguments
780 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
782 {
783  return Iterator( matrix_, row(), column() );
784 }
786 //*************************************************************************************************
787 
788 
789 //*************************************************************************************************
797 template< typename MT // Type of the sparse matrix
798  , bool TF // Transpose flag
799  , ptrdiff_t... CBAs > // Compile time band arguments
800 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
802 {
803  return ConstIterator( matrix_, row(), column() );
804 }
806 //*************************************************************************************************
807 
808 
809 //*************************************************************************************************
817 template< typename MT // Type of the sparse matrix
818  , bool TF // Transpose flag
819  , ptrdiff_t... CBAs > // Compile time band arguments
820 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
822 {
823  return ConstIterator( matrix_, row(), column() );
824 }
826 //*************************************************************************************************
827 
828 
829 //*************************************************************************************************
837 template< typename MT // Type of the sparse matrix
838  , bool TF // Transpose flag
839  , ptrdiff_t... CBAs > // Compile time band arguments
840 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
842 {
843  const size_t n( size() );
844  return Iterator( matrix_, row()+n, column()+n );
845 }
847 //*************************************************************************************************
848 
849 
850 //*************************************************************************************************
858 template< typename MT // Type of the sparse matrix
859  , bool TF // Transpose flag
860  , ptrdiff_t... CBAs > // Compile time band arguments
861 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
863 {
864  const size_t n( size() );
865  return ConstIterator( matrix_, row()+n, column()+n );
866 }
868 //*************************************************************************************************
869 
870 
871 //*************************************************************************************************
879 template< typename MT // Type of the sparse matrix
880  , bool TF // Transpose flag
881  , ptrdiff_t... CBAs > // Compile time band arguments
882 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
884 {
885  const size_t n( size() );
886  return ConstIterator( matrix_, row()+n, column()+n );
887 }
889 //*************************************************************************************************
890 
891 
892 
893 
894 //=================================================================================================
895 //
896 // ASSIGNMENT OPERATORS
897 //
898 //=================================================================================================
899 
900 //*************************************************************************************************
915 template< typename MT // Type of the dense matrix
916  , bool TF // Transpose flag
917  , ptrdiff_t... CBAs > // Compile time band arguments
918 inline Band<MT,TF,false,false,CBAs...>&
919  Band<MT,TF,false,false,CBAs...>::operator=( initializer_list<ElementType> list )
920 {
921  using blaze::assign;
922 
923  if( list.size() > size() ) {
924  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to band" );
925  }
926 
927  const InitializerVector<ElementType,false> tmp( list, size() );
928 
929  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
930  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
931  }
932 
933  decltype(auto) left( derestrict( *this ) );
934 
935  assign( left, tmp );
936 
937  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
938 
939  return *this;
940 }
942 //*************************************************************************************************
943 
944 
945 //*************************************************************************************************
959 template< typename MT // Type of the sparse matrix
960  , bool TF // Transpose flag
961  , ptrdiff_t... CBAs > // Compile time band arguments
962 inline Band<MT,TF,false,false,CBAs...>&
963  Band<MT,TF,false,false,CBAs...>::operator=( const Band& rhs )
964 {
965  using blaze::assign;
966 
970 
971  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && band() == rhs.band() ) )
972  return *this;
973 
974  if( size() != rhs.size() ) {
975  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
976  }
977 
978  if( !tryAssign( matrix_, rhs, band(), row(), column() ) ) {
979  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
980  }
981 
982  decltype(auto) left( derestrict( *this ) );
983 
984  if( rhs.canAlias( &matrix_ ) ) {
985  const ResultType tmp( rhs );
986  assign( left, tmp );
987  }
988  else {
989  assign( left, rhs );
990  }
991 
992  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
993 
994  return *this;
995 }
997 //*************************************************************************************************
998 
999 
1000 //*************************************************************************************************
1014 template< typename MT // Type of the sparse matrix
1015  , bool TF // Transpose flag
1016  , ptrdiff_t... CBAs > // Compile time band arguments
1017 template< typename VT > // Type of the right-hand side vector
1018 inline Band<MT,TF,false,false,CBAs...>&
1019  Band<MT,TF,false,false,CBAs...>::operator=( const Vector<VT,TF>& rhs )
1020 {
1021  using blaze::assign;
1022 
1023  if( size() != (~rhs).size() ) {
1024  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1025  }
1026 
1027  const CompositeType_t<VT> tmp( ~rhs );
1028 
1029  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1030  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1031  }
1032 
1033  decltype(auto) left( derestrict( *this ) );
1034 
1035  assign( left, tmp );
1036 
1037  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1038 
1039  return *this;
1040 }
1042 //*************************************************************************************************
1043 
1044 
1045 //*************************************************************************************************
1059 template< typename MT // Type of the sparse matrix
1060  , bool TF // Transpose flag
1061  , ptrdiff_t... CBAs > // Compile time band arguments
1062 template< typename VT > // Type of the right-hand side vector
1063 inline Band<MT,TF,false,false,CBAs...>&
1064  Band<MT,TF,false,false,CBAs...>::operator+=( const Vector<VT,TF>& rhs )
1065 {
1066  using blaze::assign;
1067 
1073 
1074  using AddType = AddTrait_t< ResultType, ResultType_t<VT> >;
1075 
1078 
1079  if( size() != (~rhs).size() ) {
1080  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1081  }
1082 
1083  const AddType tmp( *this + (~rhs) );
1084 
1085  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1086  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1087  }
1088 
1089  decltype(auto) left( derestrict( *this ) );
1090 
1091  assign( left, tmp );
1092 
1093  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1094 
1095  return *this;
1096 }
1098 //*************************************************************************************************
1099 
1100 
1101 //*************************************************************************************************
1115 template< typename MT // Type of the sparse matrix
1116  , bool TF // Transpose flag
1117  , ptrdiff_t... CBAs > // Compile time band arguments
1118 template< typename VT > // Type of the right-hand side vector
1119 inline Band<MT,TF,false,false,CBAs...>&
1120  Band<MT,TF,false,false,CBAs...>::operator-=( const Vector<VT,TF>& rhs )
1121 {
1122  using blaze::assign;
1123 
1129 
1130  using SubType = SubTrait_t< ResultType, ResultType_t<VT> >;
1131 
1134 
1135  if( size() != (~rhs).size() ) {
1136  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1137  }
1138 
1139  const SubType tmp( *this - (~rhs) );
1140 
1141  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1142  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1143  }
1144 
1145  decltype(auto) left( derestrict( *this ) );
1146 
1147  assign( left, tmp );
1148 
1149  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1150 
1151  return *this;
1152 }
1154 //*************************************************************************************************
1155 
1156 
1157 //*************************************************************************************************
1170 template< typename MT // Type of the sparse matrix
1171  , bool TF // Transpose flag
1172  , ptrdiff_t... CBAs > // Compile time band arguments
1173 template< typename VT > // Type of the right-hand side vector
1174 inline Band<MT,TF,false,false,CBAs...>&
1175  Band<MT,TF,false,false,CBAs...>::operator*=( const Vector<VT,TF>& rhs )
1176 {
1177  using blaze::assign;
1178 
1184 
1185  using MultType = MultTrait_t< ResultType, ResultType_t<VT> >;
1186 
1189 
1190  if( size() != (~rhs).size() ) {
1191  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1192  }
1193 
1194  const MultType tmp( *this * (~rhs) );
1195 
1196  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1197  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1198  }
1199 
1200  decltype(auto) left( derestrict( *this ) );
1201 
1202  assign( left, tmp );
1203 
1204  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1205 
1206  return *this;
1207 }
1209 //*************************************************************************************************
1210 
1211 
1212 //*************************************************************************************************
1224 template< typename MT // Type of the sparse matrix
1225  , bool TF // Transpose flag
1226  , ptrdiff_t... CBAs > // Compile time band arguments
1227 template< typename VT > // Type of the right-hand side vector
1228 inline Band<MT,TF,false,false,CBAs...>&
1229  Band<MT,TF,false,false,CBAs...>::operator/=( const DenseVector<VT,TF>& rhs )
1230 {
1231  using blaze::assign;
1232 
1236  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( ResultType_t<VT> );
1239 
1240  using DivType = DivTrait_t< ResultType, ResultType_t<VT> >;
1241 
1245 
1246  if( size() != (~rhs).size() ) {
1247  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1248  }
1249 
1250  const DivType tmp( *this / (~rhs) );
1251 
1252  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1253  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1254  }
1255 
1256  decltype(auto) left( derestrict( *this ) );
1257 
1258  assign( left, tmp );
1259 
1260  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1261 
1262  return *this;
1263 }
1265 //*************************************************************************************************
1266 
1267 
1268 //*************************************************************************************************
1281 template< typename MT // Type of the sparse matrix
1282  , bool TF // Transpose flag
1283  , ptrdiff_t... CBAs > // Compile time band arguments
1284 template< typename VT > // Type of the right-hand side vector
1285 inline Band<MT,TF,false,false,CBAs...>&
1286  Band<MT,TF,false,false,CBAs...>::operator%=( const Vector<VT,TF>& rhs )
1287 {
1288  using blaze::assign;
1289 
1292 
1293  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
1294 
1298 
1299  if( size() != 3UL || (~rhs).size() != 3UL ) {
1300  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1301  }
1302 
1303  const CrossType tmp( *this % (~rhs) );
1304 
1305  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1306  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1307  }
1308 
1309  decltype(auto) left( derestrict( *this ) );
1310 
1311  assign( left, tmp );
1312 
1313  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1314 
1315  return *this;
1316 }
1318 //*************************************************************************************************
1319 
1320 
1321 
1322 
1323 //=================================================================================================
1324 //
1325 // UTILITY FUNCTIONS
1326 //
1327 //=================================================================================================
1328 
1329 //*************************************************************************************************
1335 template< typename MT // Type of the sparse matrix
1336  , bool TF // Transpose flag
1337  , ptrdiff_t... CBAs > // Compile time band arguments
1338 inline MT& Band<MT,TF,false,false,CBAs...>::operand() noexcept
1339 {
1340  return matrix_;
1341 }
1343 //*************************************************************************************************
1344 
1345 
1346 //*************************************************************************************************
1352 template< typename MT // Type of the sparse matrix
1353  , bool TF // Transpose flag
1354  , ptrdiff_t... CBAs > // Compile time band arguments
1355 inline const MT& Band<MT,TF,false,false,CBAs...>::operand() const noexcept
1356 {
1357  return matrix_;
1358 }
1360 //*************************************************************************************************
1361 
1362 
1363 //*************************************************************************************************
1369 template< typename MT // Type of the sparse matrix
1370  , bool TF // Transpose flag
1371  , ptrdiff_t... CBAs > // Compile time band arguments
1372 inline size_t Band<MT,TF,false,false,CBAs...>::size() const noexcept
1373 {
1374  return min( matrix_.rows() - row(), matrix_.columns() - column() );
1375 }
1377 //*************************************************************************************************
1378 
1379 
1380 //*************************************************************************************************
1386 template< typename MT // Type of the sparse matrix
1387  , bool TF // Transpose flag
1388  , ptrdiff_t... CBAs > // Compile time band arguments
1389 inline size_t Band<MT,TF,false,false,CBAs...>::capacity() const noexcept
1390 {
1391  return size();
1392 }
1394 //*************************************************************************************************
1395 
1396 
1397 //*************************************************************************************************
1406 template< typename MT // Type of the sparse matrix
1407  , bool TF // Transpose flag
1408  , ptrdiff_t... CBAs > // Compile time band arguments
1409 inline size_t Band<MT,TF,false,false,CBAs...>::nonZeros() const
1410 {
1411  return end() - begin();
1412 }
1414 //*************************************************************************************************
1415 
1416 
1417 //*************************************************************************************************
1423 template< typename MT // Type of the sparse matrix
1424  , bool TF // Transpose flag
1425  , ptrdiff_t... CBAs > // Compile time band arguments
1427 {
1428  using blaze::clear;
1429 
1430  if( ( IsLower_v<MT> && column() > 0UL ) ||
1431  ( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> ) && row() == 0UL ) ||
1432  ( IsUpper_v<MT> && row() > 0UL ) ||
1433  ( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> ) && column() == 0UL ) )
1434  return;
1435 
1436  const size_t n( size() );
1437  for( size_t i=0UL; i<n; ++i )
1438  matrix_.erase( row()+i, column()+i );
1439 }
1441 //*************************************************************************************************
1442 
1443 
1444 //*************************************************************************************************
1454 template< typename MT // Type of the sparse matrix
1455  , bool TF // Transpose flag
1456  , ptrdiff_t... CBAs > // Compile time band arguments
1457 void Band<MT,TF,false,false,CBAs...>::reserve( size_t n )
1458 {
1459  MAYBE_UNUSED( n );
1460 
1461  return;
1462 }
1464 //*************************************************************************************************
1465 
1466 
1467 
1468 
1469 //=================================================================================================
1470 //
1471 // INSERTION FUNCTIONS
1472 //
1473 //=================================================================================================
1474 
1475 //*************************************************************************************************
1487 template< typename MT // Type of the sparse matrix
1488  , bool TF // Transpose flag
1489  , ptrdiff_t... CBAs > // Compile time band arguments
1490 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1491  Band<MT,TF,false,false,CBAs...>::set( size_t index, const ElementType& value )
1492 {
1493  const size_t rowIndex ( row() + index );
1494  const size_t columnIndex( column() + index );
1495  return Iterator( matrix_, rowIndex, columnIndex, matrix_.set( rowIndex, columnIndex, value ) );
1496 }
1498 //*************************************************************************************************
1499 
1500 
1501 //*************************************************************************************************
1514 template< typename MT // Type of the sparse matrix
1515  , bool TF // Transpose flag
1516  , ptrdiff_t... CBAs > // Compile time band arguments
1517 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1518  Band<MT,TF,false,false,CBAs...>::insert( size_t index, const ElementType& value )
1519 {
1520  const size_t rowIndex ( row() + index );
1521  const size_t columnIndex( column() + index );
1522  return Iterator( matrix_, rowIndex, columnIndex, matrix_.insert( rowIndex, columnIndex, value ) );
1523 }
1525 //*************************************************************************************************
1526 
1527 
1528 //*************************************************************************************************
1553 template< typename MT // Type of the sparse matrix
1554  , bool TF // Transpose flag
1555  , ptrdiff_t... CBAs > // Compile time band arguments
1556 inline void Band<MT,TF,false,false,CBAs...>::append( size_t index, const ElementType& value, bool check )
1557 {
1558  if( !check || !isDefault<strict>( value ) )
1559  matrix_.insert( row()+index, column()+index, value );
1560 }
1562 //*************************************************************************************************
1563 
1564 
1565 
1566 
1567 //=================================================================================================
1568 //
1569 // ERASE FUNCTIONS
1570 //
1571 //=================================================================================================
1572 
1573 //*************************************************************************************************
1582 template< typename MT // Type of the sparse matrix
1583  , bool TF // Transpose flag
1584  , ptrdiff_t... CBAs > // Compile time band arguments
1585 inline void Band<MT,TF,false,false,CBAs...>::erase( size_t index )
1586 {
1587  matrix_.erase( row()+index, column()+index );
1588 }
1590 //*************************************************************************************************
1591 
1592 
1593 //*************************************************************************************************
1602 template< typename MT // Type of the sparse matrix
1603  , bool TF // Transpose flag
1604  , ptrdiff_t... CBAs > // Compile time band arguments
1605 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1606  Band<MT,TF,false,false,CBAs...>::erase( Iterator pos )
1607 {
1608  const size_t rowIndex ( pos.row_ );
1609  const size_t columnIndex( pos.column_ );
1610 
1611  if( rowIndex == matrix_.rows() || columnIndex == matrix_.columns() )
1612  return pos;
1613 
1614  matrix_.erase( ( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ), pos.pos_ );
1615  return Iterator( matrix_, rowIndex+1UL, columnIndex+1UL );
1616 }
1618 //*************************************************************************************************
1619 
1620 
1621 //*************************************************************************************************
1631 template< typename MT // Type of the sparse matrix
1632  , bool TF // Transpose flag
1633  , ptrdiff_t... CBAs > // Compile time band arguments
1634 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1635  Band<MT,TF,false,false,CBAs...>::erase( Iterator first, Iterator last )
1636 {
1637  for( ; first!=last; ++first ) {
1638  const size_t index( IsRowMajorMatrix<MT>::value ? first.row_ : first.column_ );
1639  matrix_.erase( index, first.pos_ );
1640  }
1641  return last;
1642 }
1644 //*************************************************************************************************
1645 
1646 
1647 //*************************************************************************************************
1670 template< typename MT // Type of the sparse matrix
1671  , bool TF // Transpose flag
1672  , ptrdiff_t... CBAs > // Compile time band arguments
1673 template< typename Pred // Type of the unary predicate
1674  , typename > // Type restriction on the unary predicate
1675 inline void Band<MT,TF,false,false,CBAs...>::erase( Pred predicate )
1676 {
1677  for( Iterator element=begin(); element!=end(); ++element ) {
1678  if( predicate( element->value() ) ) {
1679  const size_t index( IsRowMajorMatrix<MT>::value ? element.row_ : element.column_ );
1680  matrix_.erase( index, element.pos_ );
1681  }
1682  }
1683 }
1685 //*************************************************************************************************
1686 
1687 
1688 //*************************************************************************************************
1713 template< typename MT // Type of the sparse matrix
1714  , bool TF // Transpose flag
1715  , ptrdiff_t... CBAs > // Compile time band arguments
1716 template< typename Pred > // Type of the unary predicate
1717 inline void Band<MT,TF,false,false,CBAs...>::erase( Iterator first, Iterator last, Pred predicate )
1718 {
1719  for( ; first!=last; ++first ) {
1720  if( predicate( first->value() ) ) {
1721  const size_t index( IsRowMajorMatrix<MT>::value ? first.row_ : first.column_ );
1722  matrix_.erase( index, first.pos_ );
1723  }
1724  }
1725 }
1727 //*************************************************************************************************
1728 
1729 
1730 
1731 
1732 //=================================================================================================
1733 //
1734 // LOOKUP FUNCTIONS
1735 //
1736 //=================================================================================================
1737 
1738 //*************************************************************************************************
1752 template< typename MT // Type of the sparse matrix
1753  , bool TF // Transpose flag
1754  , ptrdiff_t... CBAs > // Compile time band arguments
1755 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1756  Band<MT,TF,false,false,CBAs...>::find( size_t index )
1757 {
1758  const size_t rowIndex ( row()+index );
1759  const size_t columnIndex( column()+index );
1760  const Iterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1761 
1762  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1763  return Iterator( matrix_, rowIndex, columnIndex, pos );
1764  else
1765  return end();
1766 }
1768 //*************************************************************************************************
1769 
1770 
1771 //*************************************************************************************************
1785 template< typename MT // Type of the sparse matrix
1786  , bool TF // Transpose flag
1787  , ptrdiff_t... CBAs > // Compile time band arguments
1788 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
1789  Band<MT,TF,false,false,CBAs...>::find( size_t index ) const
1790 {
1791  const size_t rowIndex ( row()+index );
1792  const size_t columnIndex( column()+index );
1793  const ConstIterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1794 
1795  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1796  return ConstIterator( matrix_, rowIndex, columnIndex, pos );
1797  else
1798  return end();
1799 }
1801 //*************************************************************************************************
1802 
1803 
1804 //*************************************************************************************************
1817 template< typename MT // Type of the sparse matrix
1818  , bool TF // Transpose flag
1819  , ptrdiff_t... CBAs > // Compile time band arguments
1820 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1821  Band<MT,TF,false,false,CBAs...>::lowerBound( size_t index )
1822 {
1823  for( size_t i=index; i<size(); ++i )
1824  {
1825  const size_t rowIndex ( row()+i );
1826  const size_t columnIndex( column()+i );
1827  const Iterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1828 
1829  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1830  return Iterator( matrix_, rowIndex, columnIndex, pos );
1831  }
1832 
1833  return end();
1834 }
1836 //*************************************************************************************************
1837 
1838 
1839 //*************************************************************************************************
1852 template< typename MT // Type of the sparse matrix
1853  , bool TF // Transpose flag
1854  , ptrdiff_t... CBAs > // Compile time band arguments
1855 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
1856  Band<MT,TF,false,false,CBAs...>::lowerBound( size_t index ) const
1857 {
1858  for( size_t i=index; i<size(); ++i )
1859  {
1860  const size_t rowIndex ( row()+i );
1861  const size_t columnIndex( column()+i );
1862  const ConstIterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1863 
1864  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1865  return ConstIterator( matrix_, rowIndex, columnIndex, pos );
1866  }
1867 
1868  return end();
1869 }
1871 //*************************************************************************************************
1872 
1873 
1874 //*************************************************************************************************
1887 template< typename MT // Type of the sparse matrix
1888  , bool TF // Transpose flag
1889  , ptrdiff_t... CBAs > // Compile time band arguments
1890 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1891  Band<MT,TF,false,false,CBAs...>::upperBound( size_t index )
1892 {
1893  for( size_t i=index+1UL; i<size(); ++i )
1894  {
1895  const size_t rowIndex ( row()+i );
1896  const size_t columnIndex( column()+i );
1897  const Iterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1898 
1899  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1900  return Iterator( matrix_, rowIndex, columnIndex, pos );
1901  }
1902 
1903  return end();
1904 }
1906 //*************************************************************************************************
1907 
1908 
1909 //*************************************************************************************************
1922 template< typename MT // Type of the sparse matrix
1923  , bool TF // Transpose flag
1924  , ptrdiff_t... CBAs > // Compile time band arguments
1925 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
1926  Band<MT,TF,false,false,CBAs...>::upperBound( size_t index ) const
1927 {
1928  for( size_t i=index+1UL; i<size(); ++i )
1929  {
1930  const size_t rowIndex ( row()+i );
1931  const size_t columnIndex( column()+i );
1932  const ConstIterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1933 
1934  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1935  return ConstIterator( matrix_, rowIndex, columnIndex, pos );
1936  }
1937 
1938  return end();
1939 }
1941 //*************************************************************************************************
1942 
1943 
1944 
1945 
1946 //=================================================================================================
1947 //
1948 // NUMERIC FUNCTIONS
1949 //
1950 //=================================================================================================
1951 
1952 //*************************************************************************************************
1965 template< typename MT // Type of the sparse matrix
1966  , bool TF // Transpose flag
1967  , ptrdiff_t... CBAs > // Compile time band arguments
1968 template< typename Other > // Data type of the scalar value
1969 inline Band<MT,TF,false,false,CBAs...>&
1970  Band<MT,TF,false,false,CBAs...>::scale( const Other& scalar )
1971 {
1973 
1974  if( ( IsLower_v<MT> && column() > 0UL ) ||
1975  ( IsStrictlyLower_v<MT> && row() == 0UL ) ||
1976  ( IsUpper_v<MT> && row() > 0UL ) ||
1977  ( IsStrictlyUpper_v<MT> && column() == 0UL ) )
1978  return *this;
1979 
1980  for( Iterator element=begin(); element!=end(); ++element )
1981  element->value() *= scalar;
1982 
1983  return *this;
1984 }
1986 //*************************************************************************************************
1987 
1988 
1989 
1990 
1991 //=================================================================================================
1992 //
1993 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1994 //
1995 //=================================================================================================
1996 
1997 //*************************************************************************************************
2008 template< typename MT // Type of the sparse matrix
2009  , bool TF // Transpose flag
2010  , ptrdiff_t... CBAs > // Compile time band arguments
2011 template< typename Other > // Data type of the foreign expression
2012 inline bool Band<MT,TF,false,false,CBAs...>::canAlias( const Other* alias ) const noexcept
2013 {
2014  return matrix_.isAliased( alias );
2015 }
2017 //*************************************************************************************************
2018 
2019 
2020 //*************************************************************************************************
2031 template< typename MT // Type of the sparse matrix
2032  , bool TF // Transpose flag
2033  , ptrdiff_t... CBAs > // Compile time band arguments
2034 template< typename Other > // Data type of the foreign expression
2035 inline bool Band<MT,TF,false,false,CBAs...>::isAliased( const Other* alias ) const noexcept
2036 {
2037  return matrix_.isAliased( alias );
2038 }
2040 //*************************************************************************************************
2041 
2042 
2043 //*************************************************************************************************
2055 template< typename MT // Type of the sparse matrix
2056  , bool TF // Transpose flag
2057  , ptrdiff_t... CBAs > // Compile time band arguments
2058 template< typename VT > // Type of the right-hand side dense vector
2059 inline void Band<MT,TF,false,false,CBAs...>::assign( const DenseVector<VT,TF>& rhs )
2060 {
2061  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2062 
2063  for( size_t i=0UL; i<(~rhs).size(); ++i ) {
2064  matrix_(row()+i,column()+i) = (~rhs)[i];
2065  }
2066 }
2068 //*************************************************************************************************
2069 
2070 
2071 //*************************************************************************************************
2083 template< typename MT // Type of the sparse matrix
2084  , bool TF // Transpose flag
2085  , ptrdiff_t... CBAs > // Compile time band arguments
2086 template< typename VT > // Type of the right-hand side sparse vector
2087 inline void Band<MT,TF,false,false,CBAs...>::assign( const SparseVector<VT,TF>& rhs )
2088 {
2089  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2090 
2091  size_t i( 0UL );
2092 
2093  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2094  for( ; i<element->index(); ++i )
2095  matrix_.erase( row()+i, column()+i );
2096  matrix_(row()+i,column()+i) = element->value();
2097  ++i;
2098  }
2099  for( ; i<size(); ++i ) {
2100  matrix_.erase( row()+i, column()+i );
2101  }
2102 }
2104 //*************************************************************************************************
2105 
2106 
2107 //*************************************************************************************************
2119 template< typename MT // Type of the sparse matrix
2120  , bool TF // Transpose flag
2121  , ptrdiff_t... CBAs > // Compile time band arguments
2122 template< typename VT > // Type of the right-hand side vector
2123 inline void Band<MT,TF,false,false,CBAs...>::addAssign( const Vector<VT,TF>& rhs )
2124 {
2125  using AddType = AddTrait_t< ResultType, ResultType_t<VT> >;
2126 
2129 
2130  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2131 
2132  const AddType tmp( serial( *this + (~rhs) ) );
2133  assign( tmp );
2134 }
2136 //*************************************************************************************************
2137 
2138 
2139 //*************************************************************************************************
2151 template< typename MT // Type of the sparse matrix
2152  , bool TF // Transpose flag
2153  , ptrdiff_t... CBAs > // Compile time band arguments
2154 template< typename VT > // Type of the right-hand side vector
2155 inline void Band<MT,TF,false,false,CBAs...>::subAssign( const Vector<VT,TF>& rhs )
2156 {
2157  using SubType = SubTrait_t< ResultType, ResultType_t<VT> >;
2158 
2161 
2162  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2163 
2164  const SubType tmp( serial( *this - (~rhs) ) );
2165  assign( tmp );
2166 }
2168 //*************************************************************************************************
2169 
2170 
2171 
2172 
2173 //=================================================================================================
2174 //
2175 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRIX MULTIPLICATIONS
2176 //
2177 //=================================================================================================
2178 
2179 //*************************************************************************************************
2187 template< typename MT // Type of the sparse matrix multiplication
2188  , bool TF // Transpose flag
2189  , ptrdiff_t... CBAs > // Compile time band arguments
2190 class Band<MT,TF,false,true,CBAs...>
2191  : public View< SparseVector< Band<MT,TF,false,true,CBAs...>, TF > >
2192  , private BandData<CBAs...>
2193  , private Computation
2194 {
2195  private:
2196  //**Type definitions****************************************************************************
2198  using DataType = BandData<CBAs...>;
2199 
2201  using LeftOperand = RemoveReference_t< LeftOperand_t<MT> >;
2202 
2204  using RightOperand = RemoveReference_t< RightOperand_t<MT> >;
2205  //**********************************************************************************************
2206 
2207  public:
2208  //**Type definitions****************************************************************************
2210  using This = Band<MT,TF,false,true,CBAs...>;
2211 
2213  using BaseType = SparseVector<This,TF>;
2214 
2216  using ViewedType = MT;
2217 
2219  using ResultType = BandTrait_t<ResultType_t<MT>,CBAs...>;
2220 
2221  using TransposeType = TransposeType_t<ResultType>;
2222  using ElementType = ElementType_t<ResultType>;
2223  using ReturnType = ReturnType_t<MT>;
2224  using CompositeType = const ResultType;
2225 
2227  using LT = If_t< IsSparseMatrix_v<LeftOperand> && IsColumnMajorMatrix_v<LeftOperand>
2228  , ResultType_t<LeftOperand>
2229  , CompositeType_t<LeftOperand> >;
2230 
2232  using RT = If_t< IsSparseMatrix_v<RightOperand> && IsRowMajorMatrix_v<RightOperand>
2233  , ResultType_t<RightOperand>
2234  , CompositeType_t<RightOperand> >;
2235  //**********************************************************************************************
2236 
2237  //**Compilation flags***************************************************************************
2239  static constexpr bool smpAssignable = false;
2240 
2242  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2243  //**********************************************************************************************
2244 
2245  //**Constructor*********************************************************************************
2252  template< typename... RBAs > // Runtime band arguments
2253  explicit inline Band( const MT& mmm, RBAs... args )
2254  : DataType( args... ) // Base class initialization
2255  , matrix_ ( mmm ) // The matrix multiplication containing the band
2256  {
2257  if( !Contains_v< TypeList<RBAs...>, Unchecked > ) {
2258  if( ( band() > 0L && column() >= mmm.columns() ) ||
2259  ( band() < 0L && row() >= mmm.rows() ) ) {
2260  BLAZE_THROW_INVALID_ARGUMENT( "Invalid band access index" );
2261  }
2262  }
2263  else {
2264  BLAZE_USER_ASSERT( band() <= 0L || column() < mmm.columns(), "Invalid band access index" );
2265  BLAZE_USER_ASSERT( band() >= 0L || row() < mmm.rows(), "Invalid band access index" );
2266  }
2267  }
2268  //**********************************************************************************************
2269 
2270  //**Subscript operator**************************************************************************
2276  inline ReturnType operator[]( size_t index ) const {
2277  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
2278  return matrix_(row()+index,column()+index);
2279  }
2280  //**********************************************************************************************
2281 
2282  //**At function*********************************************************************************
2289  inline ReturnType at( size_t index ) const {
2290  if( index >= size() ) {
2291  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
2292  }
2293  return (*this)[index];
2294  }
2295  //**********************************************************************************************
2296 
2297  //**Size function*******************************************************************************
2302  inline size_t size() const noexcept {
2303  return min( matrix_.rows() - row(), matrix_.columns() - column() );
2304  }
2305  //**********************************************************************************************
2306 
2307  //**NonZeros function***************************************************************************
2312  inline size_t nonZeros() const {
2313  return 0UL;
2314  }
2315  //**********************************************************************************************
2316 
2317  //**********************************************************************************************
2318  using DataType::band;
2319  using DataType::row;
2320  using DataType::column;
2321  //**********************************************************************************************
2322 
2323  //**Operand access******************************************************************************
2328  inline const MT& operand() const noexcept {
2329  return matrix_;
2330  }
2331  //**********************************************************************************************
2332 
2333  //**********************************************************************************************
2339  template< typename T >
2340  inline bool canAlias( const T* alias ) const noexcept {
2341  return matrix_.isAliased( alias );
2342  }
2343  //**********************************************************************************************
2344 
2345  //**********************************************************************************************
2351  template< typename T >
2352  inline bool isAliased( const T* alias ) const noexcept {
2353  return matrix_.isAliased( alias );
2354  }
2355  //**********************************************************************************************
2356 
2357  private:
2358  //**Member variables****************************************************************************
2359  MT matrix_;
2360  //**********************************************************************************************
2361 
2362  //**Assignment to dense vectors*****************************************************************
2374  template< typename VT > // Type of the target dense vector
2375  friend inline void assign( DenseVector<VT,TF>& lhs, const Band& rhs )
2376  {
2377  using blaze::row;
2378  using blaze::column;
2379 
2381 
2382  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2383 
2384  LT A( serial( rhs.operand().leftOperand() ) );
2385  RT B( serial( rhs.operand().rightOperand() ) );
2386 
2387  const size_t n( rhs.size() );
2388  for( size_t i=0UL; i<n; ++i ) {
2389  (~lhs)[i] = row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2390  }
2391  }
2393  //**********************************************************************************************
2394 
2395  //**Assignment to sparse vectors****************************************************************
2407  template< typename VT > // Type of the target sparse vector
2408  friend inline void assign( SparseVector<VT,TF>& lhs, const Band& rhs )
2409  {
2410  using blaze::row;
2411  using blaze::column;
2412 
2414 
2415  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2416 
2417  LT A( serial( rhs.operand().leftOperand() ) );
2418  RT B( serial( rhs.operand().rightOperand() ) );
2419 
2420  const size_t n( rhs.size() );
2421  ElementType_t<VT> tmp{};
2422  size_t nonzeros( 0UL );
2423 
2424  for( size_t i=0UL; i<n; ++i ) {
2425  tmp = row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2426  if( !isDefault<strict>( tmp ) ) {
2427  if( (~lhs).capacity() <= nonzeros ) {
2428  (~lhs).reserve( min( max( 2UL*(~lhs).capacity(), 7UL ), (~lhs).size() ) );
2429  }
2430  (~lhs).append( i, tmp, false );
2431  ++nonzeros;
2432  }
2433  }
2434  }
2436  //**********************************************************************************************
2437 
2438  //**Addition assignment to dense vectors********************************************************
2450  template< typename VT > // Type of the target dense vector
2451  friend inline void addAssign( DenseVector<VT,TF>& lhs, const Band& rhs )
2452  {
2453  using blaze::row;
2454  using blaze::column;
2455 
2457 
2458  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2459 
2460  LT A( serial( rhs.operand().leftOperand() ) );
2461  RT B( serial( rhs.operand().rightOperand() ) );
2462 
2463  const size_t n( rhs.size() );
2464  for( size_t i=0UL; i<n; ++i ) {
2465  (~lhs)[i] += row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2466  }
2467  }
2469  //**********************************************************************************************
2470 
2471  //**Addition assignment to sparse vectors*******************************************************
2472  // No special implementation for the addition assignment to sparse vectors.
2473  //**********************************************************************************************
2474 
2475  //**Subtraction assignment to dense vectors*****************************************************
2487  template< typename VT > // Type of the target dense vector
2488  friend inline void subAssign( DenseVector<VT,TF>& lhs, const Band& rhs )
2489  {
2490  using blaze::row;
2491  using blaze::column;
2492 
2494 
2495  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2496 
2497  LT A( serial( rhs.operand().leftOperand() ) );
2498  RT B( serial( rhs.operand().rightOperand() ) );
2499 
2500  const size_t n( rhs.size() );
2501  for( size_t i=0UL; i<n; ++i ) {
2502  (~lhs)[i] -= row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2503  }
2504  }
2506  //**********************************************************************************************
2507 
2508  //**Subtraction assignment to sparse vectors****************************************************
2509  // No special implementation for the subtraction assignment to sparse vectors.
2510  //**********************************************************************************************
2511 
2512  //**Multiplication assignment to dense vectors**************************************************
2525  template< typename VT > // Type of the target dense vector
2526  friend inline void multAssign( DenseVector<VT,TF>& lhs, const Band& rhs )
2527  {
2528  using blaze::row;
2529  using blaze::column;
2530 
2532 
2533  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2534 
2535  LT A( serial( rhs.operand().leftOperand() ) );
2536  RT B( serial( rhs.operand().rightOperand() ) );
2537 
2538  const size_t n( rhs.size() );
2539  for( size_t i=0UL; i<n; ++i ) {
2540  (~lhs)[i] *= row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2541  }
2542  }
2544  //**********************************************************************************************
2545 
2546  //**Multiplication assignment to sparse vectors*************************************************
2547  // No special implementation for the multiplication assignment to sparse vectors.
2548  //**********************************************************************************************
2549 
2550  //**Compile time checks*************************************************************************
2557  //**********************************************************************************************
2558 };
2559 //*************************************************************************************************
2560 
2561 } // namespace blaze
2562 
2563 #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:133
Headerfile for the generic min algorithm.
Header file for the blaze::checked and blaze::unchecked instances.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
Header file for the IsUniUpper type trait.
Header file for the subtraction trait.
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr 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:750
Header file for the SparseVector base class.
Header file for the View base class.
Header file for the IsSparseMatrix 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:81
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
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:595
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
Header file for the IsIntegral type trait.
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
Header file for the MAYBE_UNUSED function template.
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
Header file for the implementation of the Band base template.
#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.
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:482
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:416
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.
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.
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:9091
#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
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1162
#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
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
constexpr bool Contains_v
Auxiliary variable template for the Contains type trait.The Contains_v variable template provides a c...
Definition: Contains.h:138
Header file for the IsLower type trait.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#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.
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1198
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:438
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
Constraint on the data type.
Constraint on the data type.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:615
decltype(auto) band(Matrix< MT, SO > &matrix, RBAs... args)
Creating a view on a specific band of the given matrix.
Definition: Band.h:137
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:63
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:558
Header file for the IsConst type trait.
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:133
#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,...
Definition: Reference.h:79
Header file for the isDefault shim.
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > set(T value) noexcept
Sets all values in the vector to the given 1-byte integral value.
Definition: Set.h:75
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
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:808
#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
Header file for the RemoveReference type trait.
#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
Header file for the IsRowMajorMatrix type trait.
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
auto operator *=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:494
constexpr bool IsIntegral_v
Auxiliary variable template for the IsIntegral type trait.The IsIntegral_v variable template provides...
Definition: IsIntegral.h:95
Header file for the IsUpper type trait.
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
typename BandTrait< MT, CBAs... >::Type BandTrait_t
Auxiliary alias declaration for the BandTrait type trait.The BandTrait_t alias declaration provides a...
Definition: BandTrait.h:170
#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,...
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.