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_t<MT>;
118  using DataType = BandData<CBAs...>;
119  using Operand = If_t< IsExpression_v<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_t<RT,CBAs...>;
130  using TransposeType = TransposeType_t<ResultType>;
131  using ElementType = ElementType_t<MT>;
132  using ReturnType = ReturnType_t<MT>;
133 
135  using CompositeType = If_t< RequiresEvaluation_v<MT>, const ResultType, const Band& >;
136 
138  using ConstReference = ConstReference_t<MT>;
139 
141  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<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_v<MatrixType> ? 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_v<MatrixType> ? 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_v<MatrixType> ? 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_t<MT> >;
464 
466  using Iterator = If_t< IsConst_v<MT>, ConstIterator, BandIterator< MT, Iterator_t<MT> > >;
467  //**********************************************************************************************
468 
469  //**Compilation flags***************************************************************************
471  static constexpr bool smpAssignable = false;
472  //**********************************************************************************************
473 
474  //**Constructors********************************************************************************
477  template< typename... RBAs >
478  explicit inline Band( MT& matrix, RBAs... args );
479 
480  Band( const Band& ) = default;
482  //**********************************************************************************************
483 
484  //**Destructor**********************************************************************************
487  ~Band() = default;
489  //**********************************************************************************************
490 
491  //**Data access functions***********************************************************************
494  inline Reference operator[]( size_t index );
495  inline ConstReference operator[]( size_t index ) const;
496  inline Reference at( size_t index );
497  inline ConstReference at( size_t index ) const;
498  inline Iterator begin ();
499  inline ConstIterator begin () const;
500  inline ConstIterator cbegin() const;
501  inline Iterator end ();
502  inline ConstIterator end () const;
503  inline ConstIterator cend () const;
505  //**********************************************************************************************
506 
507  //**Assignment operators************************************************************************
510  inline Band& operator= ( initializer_list<ElementType> list );
511  inline Band& operator= ( const Band& rhs );
512  template< typename VT > inline Band& operator= ( const Vector<VT,TF>& rhs );
513  template< typename VT > inline Band& operator+=( const Vector<VT,TF>& rhs );
514  template< typename VT > inline Band& operator-=( const Vector<VT,TF>& rhs );
515  template< typename VT > inline Band& operator*=( const Vector<VT,TF>& rhs );
516  template< typename VT > inline Band& operator/=( const DenseVector<VT,TF>& rhs );
517  template< typename VT > inline Band& operator%=( const Vector<VT,TF>& rhs );
519  //**********************************************************************************************
520 
521  //**Utility functions***************************************************************************
524  using DataType::band;
525  using DataType::row;
526  using DataType::column;
527 
528  inline MT& operand() noexcept;
529  inline const MT& operand() const noexcept;
530 
531  inline size_t size() const noexcept;
532  inline size_t capacity() const noexcept;
533  inline size_t nonZeros() const;
534  inline void reset();
535  inline void reserve( size_t n );
537  //**********************************************************************************************
538 
539  //**Insertion functions*************************************************************************
542  inline Iterator set ( size_t index, const ElementType& value );
543  inline Iterator insert( size_t index, const ElementType& value );
544  inline void append( size_t index, const ElementType& value, bool check=false );
546  //**********************************************************************************************
547 
548  //**Erase functions*****************************************************************************
551  inline void erase( size_t index );
552  inline Iterator erase( Iterator pos );
553  inline Iterator erase( Iterator first, Iterator last );
554 
555  template< typename Pred, typename = DisableIf_t< IsIntegral_v<Pred> > >
556  inline void erase( Pred predicate );
557 
558  template< typename Pred >
559  inline void erase( Iterator first, Iterator last, Pred predicate );
561  //**********************************************************************************************
562 
563  //**Lookup functions****************************************************************************
566  inline Iterator find ( size_t index );
567  inline ConstIterator find ( size_t index ) const;
568  inline Iterator lowerBound( size_t index );
569  inline ConstIterator lowerBound( size_t index ) const;
570  inline Iterator upperBound( size_t index );
571  inline ConstIterator upperBound( size_t index ) const;
573  //**********************************************************************************************
574 
575  //**Numeric functions***************************************************************************
578  template< typename Other > inline Band& scale( const Other& scalar );
580  //**********************************************************************************************
581 
582  //**Expression template evaluation functions****************************************************
585  template< typename Other > inline bool canAlias ( const Other* alias ) const noexcept;
586  template< typename Other > inline bool isAliased( const Other* alias ) const noexcept;
587 
588  template< typename VT > inline void assign ( const DenseVector <VT,TF>& rhs );
589  template< typename VT > inline void assign ( const SparseVector<VT,TF>& rhs );
590  template< typename VT > inline void addAssign( const Vector<VT,TF>& rhs );
591  template< typename VT > inline void subAssign( const Vector<VT,TF>& rhs );
593  //**********************************************************************************************
594 
595  private:
596  //**Member variables****************************************************************************
599  Operand matrix_;
600 
601  //**********************************************************************************************
602 
603  //**Compile time checks*************************************************************************
609  //**********************************************************************************************
610 };
612 //*************************************************************************************************
613 
614 
615 
616 
617 //=================================================================================================
618 //
619 // CONSTRUCTORS
620 //
621 //=================================================================================================
622 
623 //*************************************************************************************************
636 template< typename MT // Type of the sparse matrix
637  , bool TF // Transpose flag
638  , ptrdiff_t... CBAs > // Compile time band arguments
639 template< typename... RBAs > // Runtime band arguments
640 inline Band<MT,TF,false,false,CBAs...>::Band( MT& matrix, RBAs... args )
641  : DataType( args... ) // Base class initialization
642  , matrix_ ( matrix ) // The matrix containing the band
643 {
644  if( !Contains_v< TypeList<RBAs...>, Unchecked > ) {
645  if( ( band() > 0L && column() >= matrix.columns() ) ||
646  ( band() < 0L && row() >= matrix.rows() ) ) {
647  BLAZE_THROW_INVALID_ARGUMENT( "Invalid band access index" );
648  }
649  }
650  else {
651  BLAZE_USER_ASSERT( band() <= 0L || column() < matrix.columns(), "Invalid band access index" );
652  BLAZE_USER_ASSERT( band() >= 0L || row() < matrix.rows(), "Invalid band access index" );
653  }
654 }
656 //*************************************************************************************************
657 
658 
659 
660 
661 //=================================================================================================
662 //
663 // DATA ACCESS FUNCTIONS
664 //
665 //=================================================================================================
666 
667 //*************************************************************************************************
677 template< typename MT // Type of the sparse matrix
678  , bool TF // Transpose flag
679  , ptrdiff_t... CBAs > // Compile time band arguments
680 inline typename Band<MT,TF,false,false,CBAs...>::Reference
681  Band<MT,TF,false,false,CBAs...>::operator[]( size_t index )
682 {
683  BLAZE_USER_ASSERT( index < size(), "Invalid band access index" );
684  return matrix_(row()+index,column()+index);
685 }
687 //*************************************************************************************************
688 
689 
690 //*************************************************************************************************
700 template< typename MT // Type of the sparse matrix
701  , bool TF // Transpose flag
702  , ptrdiff_t... CBAs > // Compile time band arguments
703 inline typename Band<MT,TF,false,false,CBAs...>::ConstReference
704  Band<MT,TF,false,false,CBAs...>::operator[]( size_t index ) const
705 {
706  BLAZE_USER_ASSERT( index < size(), "Invalid band access index" );
707  return const_cast<const MT&>( matrix_ )(row()+index,column()+index);
708 }
710 //*************************************************************************************************
711 
712 
713 //*************************************************************************************************
724 template< typename MT // Type of the sparse matrix
725  , bool TF // Transpose flag
726  , ptrdiff_t... CBAs > // Compile time band arguments
727 inline typename Band<MT,TF,false,false,CBAs...>::Reference
728  Band<MT,TF,false,false,CBAs...>::at( size_t index )
729 {
730  if( index >= size() ) {
731  BLAZE_THROW_OUT_OF_RANGE( "Invalid band access index" );
732  }
733  return (*this)[index];
734 }
736 //*************************************************************************************************
737 
738 
739 //*************************************************************************************************
750 template< typename MT // Type of the sparse matrix
751  , bool TF // Transpose flag
752  , ptrdiff_t... CBAs > // Compile time band arguments
753 inline typename Band<MT,TF,false,false,CBAs...>::ConstReference
754  Band<MT,TF,false,false,CBAs...>::at( size_t index ) const
755 {
756  if( index >= size() ) {
757  BLAZE_THROW_OUT_OF_RANGE( "Invalid band access index" );
758  }
759  return (*this)[index];
760 }
762 //*************************************************************************************************
763 
764 
765 //*************************************************************************************************
773 template< typename MT // Type of the sparse matrix
774  , bool TF // Transpose flag
775  , ptrdiff_t... CBAs > // Compile time band arguments
776 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
778 {
779  return Iterator( matrix_, row(), column() );
780 }
782 //*************************************************************************************************
783 
784 
785 //*************************************************************************************************
793 template< typename MT // Type of the sparse matrix
794  , bool TF // Transpose flag
795  , ptrdiff_t... CBAs > // Compile time band arguments
796 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
798 {
799  return ConstIterator( matrix_, row(), column() );
800 }
802 //*************************************************************************************************
803 
804 
805 //*************************************************************************************************
813 template< typename MT // Type of the sparse matrix
814  , bool TF // Transpose flag
815  , ptrdiff_t... CBAs > // Compile time band arguments
816 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
818 {
819  return ConstIterator( matrix_, row(), column() );
820 }
822 //*************************************************************************************************
823 
824 
825 //*************************************************************************************************
833 template< typename MT // Type of the sparse matrix
834  , bool TF // Transpose flag
835  , ptrdiff_t... CBAs > // Compile time band arguments
836 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
838 {
839  const size_t n( size() );
840  return Iterator( matrix_, row()+n, column()+n );
841 }
843 //*************************************************************************************************
844 
845 
846 //*************************************************************************************************
854 template< typename MT // Type of the sparse matrix
855  , bool TF // Transpose flag
856  , ptrdiff_t... CBAs > // Compile time band arguments
857 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
859 {
860  const size_t n( size() );
861  return ConstIterator( matrix_, row()+n, column()+n );
862 }
864 //*************************************************************************************************
865 
866 
867 //*************************************************************************************************
875 template< typename MT // Type of the sparse matrix
876  , bool TF // Transpose flag
877  , ptrdiff_t... CBAs > // Compile time band arguments
878 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
880 {
881  const size_t n( size() );
882  return ConstIterator( matrix_, row()+n, column()+n );
883 }
885 //*************************************************************************************************
886 
887 
888 
889 
890 //=================================================================================================
891 //
892 // ASSIGNMENT OPERATORS
893 //
894 //=================================================================================================
895 
896 //*************************************************************************************************
911 template< typename MT // Type of the dense matrix
912  , bool TF // Transpose flag
913  , ptrdiff_t... CBAs > // Compile time band arguments
914 inline Band<MT,TF,false,false,CBAs...>&
915  Band<MT,TF,false,false,CBAs...>::operator=( initializer_list<ElementType> list )
916 {
917  using blaze::assign;
918 
919  if( list.size() > size() ) {
920  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to band" );
921  }
922 
923  const InitializerVector<ElementType,false> tmp( list, size() );
924 
925  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
926  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
927  }
928 
929  decltype(auto) left( derestrict( *this ) );
930 
931  assign( left, tmp );
932 
933  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
934 
935  return *this;
936 }
938 //*************************************************************************************************
939 
940 
941 //*************************************************************************************************
955 template< typename MT // Type of the sparse matrix
956  , bool TF // Transpose flag
957  , ptrdiff_t... CBAs > // Compile time band arguments
958 inline Band<MT,TF,false,false,CBAs...>&
959  Band<MT,TF,false,false,CBAs...>::operator=( const Band& rhs )
960 {
961  using blaze::assign;
962 
966 
967  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && band() == rhs.band() ) )
968  return *this;
969 
970  if( size() != rhs.size() ) {
971  BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
972  }
973 
974  if( !tryAssign( matrix_, rhs, band(), row(), column() ) ) {
975  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
976  }
977 
978  decltype(auto) left( derestrict( *this ) );
979 
980  if( rhs.canAlias( &matrix_ ) ) {
981  const ResultType tmp( rhs );
982  assign( left, tmp );
983  }
984  else {
985  assign( left, rhs );
986  }
987 
988  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
989 
990  return *this;
991 }
993 //*************************************************************************************************
994 
995 
996 //*************************************************************************************************
1010 template< typename MT // Type of the sparse matrix
1011  , bool TF // Transpose flag
1012  , ptrdiff_t... CBAs > // Compile time band arguments
1013 template< typename VT > // Type of the right-hand side vector
1014 inline Band<MT,TF,false,false,CBAs...>&
1015  Band<MT,TF,false,false,CBAs...>::operator=( const Vector<VT,TF>& rhs )
1016 {
1017  using blaze::assign;
1018 
1019  if( size() != (~rhs).size() ) {
1020  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1021  }
1022 
1023  const CompositeType_t<VT> tmp( ~rhs );
1024 
1025  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1026  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1027  }
1028 
1029  decltype(auto) left( derestrict( *this ) );
1030 
1031  assign( left, tmp );
1032 
1033  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1034 
1035  return *this;
1036 }
1038 //*************************************************************************************************
1039 
1040 
1041 //*************************************************************************************************
1055 template< typename MT // Type of the sparse matrix
1056  , bool TF // Transpose flag
1057  , ptrdiff_t... CBAs > // Compile time band arguments
1058 template< typename VT > // Type of the right-hand side vector
1059 inline Band<MT,TF,false,false,CBAs...>&
1060  Band<MT,TF,false,false,CBAs...>::operator+=( const Vector<VT,TF>& rhs )
1061 {
1062  using blaze::assign;
1063 
1069 
1070  using AddType = AddTrait_t< ResultType, ResultType_t<VT> >;
1071 
1074 
1075  if( size() != (~rhs).size() ) {
1076  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1077  }
1078 
1079  const AddType tmp( *this + (~rhs) );
1080 
1081  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1082  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1083  }
1084 
1085  decltype(auto) left( derestrict( *this ) );
1086 
1087  assign( left, tmp );
1088 
1089  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1090 
1091  return *this;
1092 }
1094 //*************************************************************************************************
1095 
1096 
1097 //*************************************************************************************************
1111 template< typename MT // Type of the sparse matrix
1112  , bool TF // Transpose flag
1113  , ptrdiff_t... CBAs > // Compile time band arguments
1114 template< typename VT > // Type of the right-hand side vector
1115 inline Band<MT,TF,false,false,CBAs...>&
1116  Band<MT,TF,false,false,CBAs...>::operator-=( const Vector<VT,TF>& rhs )
1117 {
1118  using blaze::assign;
1119 
1125 
1126  using SubType = SubTrait_t< ResultType, ResultType_t<VT> >;
1127 
1130 
1131  if( size() != (~rhs).size() ) {
1132  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1133  }
1134 
1135  const SubType tmp( *this - (~rhs) );
1136 
1137  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1138  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1139  }
1140 
1141  decltype(auto) left( derestrict( *this ) );
1142 
1143  assign( left, tmp );
1144 
1145  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1146 
1147  return *this;
1148 }
1150 //*************************************************************************************************
1151 
1152 
1153 //*************************************************************************************************
1166 template< typename MT // Type of the sparse matrix
1167  , bool TF // Transpose flag
1168  , ptrdiff_t... CBAs > // Compile time band arguments
1169 template< typename VT > // Type of the right-hand side vector
1170 inline Band<MT,TF,false,false,CBAs...>&
1171  Band<MT,TF,false,false,CBAs...>::operator*=( const Vector<VT,TF>& rhs )
1172 {
1173  using blaze::assign;
1174 
1180 
1181  using MultType = MultTrait_t< ResultType, ResultType_t<VT> >;
1182 
1185 
1186  if( size() != (~rhs).size() ) {
1187  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1188  }
1189 
1190  const MultType tmp( *this * (~rhs) );
1191 
1192  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1193  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1194  }
1195 
1196  decltype(auto) left( derestrict( *this ) );
1197 
1198  assign( left, tmp );
1199 
1200  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1201 
1202  return *this;
1203 }
1205 //*************************************************************************************************
1206 
1207 
1208 //*************************************************************************************************
1220 template< typename MT // Type of the sparse matrix
1221  , bool TF // Transpose flag
1222  , ptrdiff_t... CBAs > // Compile time band arguments
1223 template< typename VT > // Type of the right-hand side vector
1224 inline Band<MT,TF,false,false,CBAs...>&
1225  Band<MT,TF,false,false,CBAs...>::operator/=( const DenseVector<VT,TF>& rhs )
1226 {
1227  using blaze::assign;
1228 
1232  BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( ResultType_t<VT> );
1235 
1236  using DivType = DivTrait_t< ResultType, ResultType_t<VT> >;
1237 
1241 
1242  if( size() != (~rhs).size() ) {
1243  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1244  }
1245 
1246  const DivType tmp( *this / (~rhs) );
1247 
1248  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1249  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1250  }
1251 
1252  decltype(auto) left( derestrict( *this ) );
1253 
1254  assign( left, tmp );
1255 
1256  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1257 
1258  return *this;
1259 }
1261 //*************************************************************************************************
1262 
1263 
1264 //*************************************************************************************************
1277 template< typename MT // Type of the sparse matrix
1278  , bool TF // Transpose flag
1279  , ptrdiff_t... CBAs > // Compile time band arguments
1280 template< typename VT > // Type of the right-hand side vector
1281 inline Band<MT,TF,false,false,CBAs...>&
1282  Band<MT,TF,false,false,CBAs...>::operator%=( const Vector<VT,TF>& rhs )
1283 {
1284  using blaze::assign;
1285 
1288 
1289  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
1290 
1294 
1295  if( size() != 3UL || (~rhs).size() != 3UL ) {
1296  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1297  }
1298 
1299  const CrossType tmp( *this % (~rhs) );
1300 
1301  if( !tryAssign( matrix_, tmp, band(), row(), column() ) ) {
1302  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1303  }
1304 
1305  decltype(auto) left( derestrict( *this ) );
1306 
1307  assign( left, tmp );
1308 
1309  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1310 
1311  return *this;
1312 }
1314 //*************************************************************************************************
1315 
1316 
1317 
1318 
1319 //=================================================================================================
1320 //
1321 // UTILITY FUNCTIONS
1322 //
1323 //=================================================================================================
1324 
1325 //*************************************************************************************************
1331 template< typename MT // Type of the sparse matrix
1332  , bool TF // Transpose flag
1333  , ptrdiff_t... CBAs > // Compile time band arguments
1334 inline MT& Band<MT,TF,false,false,CBAs...>::operand() noexcept
1335 {
1336  return matrix_;
1337 }
1339 //*************************************************************************************************
1340 
1341 
1342 //*************************************************************************************************
1348 template< typename MT // Type of the sparse matrix
1349  , bool TF // Transpose flag
1350  , ptrdiff_t... CBAs > // Compile time band arguments
1351 inline const MT& Band<MT,TF,false,false,CBAs...>::operand() const noexcept
1352 {
1353  return matrix_;
1354 }
1356 //*************************************************************************************************
1357 
1358 
1359 //*************************************************************************************************
1365 template< typename MT // Type of the sparse matrix
1366  , bool TF // Transpose flag
1367  , ptrdiff_t... CBAs > // Compile time band arguments
1368 inline size_t Band<MT,TF,false,false,CBAs...>::size() const noexcept
1369 {
1370  return min( matrix_.rows() - row(), matrix_.columns() - column() );
1371 }
1373 //*************************************************************************************************
1374 
1375 
1376 //*************************************************************************************************
1382 template< typename MT // Type of the sparse matrix
1383  , bool TF // Transpose flag
1384  , ptrdiff_t... CBAs > // Compile time band arguments
1385 inline size_t Band<MT,TF,false,false,CBAs...>::capacity() const noexcept
1386 {
1387  return size();
1388 }
1390 //*************************************************************************************************
1391 
1392 
1393 //*************************************************************************************************
1402 template< typename MT // Type of the sparse matrix
1403  , bool TF // Transpose flag
1404  , ptrdiff_t... CBAs > // Compile time band arguments
1405 inline size_t Band<MT,TF,false,false,CBAs...>::nonZeros() const
1406 {
1407  return end() - begin();
1408 }
1410 //*************************************************************************************************
1411 
1412 
1413 //*************************************************************************************************
1419 template< typename MT // Type of the sparse matrix
1420  , bool TF // Transpose flag
1421  , ptrdiff_t... CBAs > // Compile time band arguments
1423 {
1424  using blaze::clear;
1425 
1426  if( ( IsLower_v<MT> && column() > 0UL ) ||
1427  ( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> ) && row() == 0UL ) ||
1428  ( IsUpper_v<MT> && row() > 0UL ) ||
1429  ( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> ) && column() == 0UL ) )
1430  return;
1431 
1432  const size_t n( size() );
1433  for( size_t i=0UL; i<n; ++i )
1434  matrix_.erase( row()+i, column()+i );
1435 }
1437 //*************************************************************************************************
1438 
1439 
1440 //*************************************************************************************************
1450 template< typename MT // Type of the sparse matrix
1451  , bool TF // Transpose flag
1452  , ptrdiff_t... CBAs > // Compile time band arguments
1453 void Band<MT,TF,false,false,CBAs...>::reserve( size_t n )
1454 {
1455  UNUSED_PARAMETER( n );
1456 
1457  return;
1458 }
1460 //*************************************************************************************************
1461 
1462 
1463 
1464 
1465 //=================================================================================================
1466 //
1467 // INSERTION FUNCTIONS
1468 //
1469 //=================================================================================================
1470 
1471 //*************************************************************************************************
1483 template< typename MT // Type of the sparse matrix
1484  , bool TF // Transpose flag
1485  , ptrdiff_t... CBAs > // Compile time band arguments
1486 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1487  Band<MT,TF,false,false,CBAs...>::set( size_t index, const ElementType& value )
1488 {
1489  const size_t rowIndex ( row() + index );
1490  const size_t columnIndex( column() + index );
1491  return Iterator( matrix_, rowIndex, columnIndex, matrix_.set( rowIndex, columnIndex, value ) );
1492 }
1494 //*************************************************************************************************
1495 
1496 
1497 //*************************************************************************************************
1510 template< typename MT // Type of the sparse matrix
1511  , bool TF // Transpose flag
1512  , ptrdiff_t... CBAs > // Compile time band arguments
1513 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1514  Band<MT,TF,false,false,CBAs...>::insert( size_t index, const ElementType& value )
1515 {
1516  const size_t rowIndex ( row() + index );
1517  const size_t columnIndex( column() + index );
1518  return Iterator( matrix_, rowIndex, columnIndex, matrix_.insert( rowIndex, columnIndex, value ) );
1519 }
1521 //*************************************************************************************************
1522 
1523 
1524 //*************************************************************************************************
1549 template< typename MT // Type of the sparse matrix
1550  , bool TF // Transpose flag
1551  , ptrdiff_t... CBAs > // Compile time band arguments
1552 inline void Band<MT,TF,false,false,CBAs...>::append( size_t index, const ElementType& value, bool check )
1553 {
1554  if( !check || !isDefault<strict>( value ) )
1555  matrix_.insert( row()+index, column()+index, value );
1556 }
1558 //*************************************************************************************************
1559 
1560 
1561 
1562 
1563 //=================================================================================================
1564 //
1565 // ERASE FUNCTIONS
1566 //
1567 //=================================================================================================
1568 
1569 //*************************************************************************************************
1578 template< typename MT // Type of the sparse matrix
1579  , bool TF // Transpose flag
1580  , ptrdiff_t... CBAs > // Compile time band arguments
1581 inline void Band<MT,TF,false,false,CBAs...>::erase( size_t index )
1582 {
1583  matrix_.erase( row()+index, column()+index );
1584 }
1586 //*************************************************************************************************
1587 
1588 
1589 //*************************************************************************************************
1598 template< typename MT // Type of the sparse matrix
1599  , bool TF // Transpose flag
1600  , ptrdiff_t... CBAs > // Compile time band arguments
1601 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1602  Band<MT,TF,false,false,CBAs...>::erase( Iterator pos )
1603 {
1604  const size_t rowIndex ( pos.row_ );
1605  const size_t columnIndex( pos.column_ );
1606 
1607  if( rowIndex == matrix_.rows() || columnIndex == matrix_.columns() )
1608  return pos;
1609 
1610  matrix_.erase( ( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ), pos.pos_ );
1611  return Iterator( matrix_, rowIndex+1UL, columnIndex+1UL );
1612 }
1614 //*************************************************************************************************
1615 
1616 
1617 //*************************************************************************************************
1627 template< typename MT // Type of the sparse matrix
1628  , bool TF // Transpose flag
1629  , ptrdiff_t... CBAs > // Compile time band arguments
1630 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1631  Band<MT,TF,false,false,CBAs...>::erase( Iterator first, Iterator last )
1632 {
1633  for( ; first!=last; ++first ) {
1634  const size_t index( IsRowMajorMatrix<MT>::value ? first.row_ : first.column_ );
1635  matrix_.erase( index, first.pos_ );
1636  }
1637  return last;
1638 }
1640 //*************************************************************************************************
1641 
1642 
1643 //*************************************************************************************************
1666 template< typename MT // Type of the sparse matrix
1667  , bool TF // Transpose flag
1668  , ptrdiff_t... CBAs > // Compile time band arguments
1669 template< typename Pred // Type of the unary predicate
1670  , typename > // Type restriction on the unary predicate
1671 inline void Band<MT,TF,false,false,CBAs...>::erase( Pred predicate )
1672 {
1673  for( Iterator element=begin(); element!=end(); ++element ) {
1674  if( predicate( element->value() ) ) {
1675  const size_t index( IsRowMajorMatrix<MT>::value ? element.row_ : element.column_ );
1676  matrix_.erase( index, element.pos_ );
1677  }
1678  }
1679 }
1681 //*************************************************************************************************
1682 
1683 
1684 //*************************************************************************************************
1709 template< typename MT // Type of the sparse matrix
1710  , bool TF // Transpose flag
1711  , ptrdiff_t... CBAs > // Compile time band arguments
1712 template< typename Pred > // Type of the unary predicate
1713 inline void Band<MT,TF,false,false,CBAs...>::erase( Iterator first, Iterator last, Pred predicate )
1714 {
1715  for( ; first!=last; ++first ) {
1716  if( predicate( first->value() ) ) {
1717  const size_t index( IsRowMajorMatrix<MT>::value ? first.row_ : first.column_ );
1718  matrix_.erase( index, first.pos_ );
1719  }
1720  }
1721 }
1723 //*************************************************************************************************
1724 
1725 
1726 
1727 
1728 //=================================================================================================
1729 //
1730 // LOOKUP FUNCTIONS
1731 //
1732 //=================================================================================================
1733 
1734 //*************************************************************************************************
1748 template< typename MT // Type of the sparse matrix
1749  , bool TF // Transpose flag
1750  , ptrdiff_t... CBAs > // Compile time band arguments
1751 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1752  Band<MT,TF,false,false,CBAs...>::find( size_t index )
1753 {
1754  const size_t rowIndex ( row()+index );
1755  const size_t columnIndex( column()+index );
1756  const Iterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1757 
1758  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1759  return Iterator( matrix_, rowIndex, columnIndex, pos );
1760  else
1761  return end();
1762 }
1764 //*************************************************************************************************
1765 
1766 
1767 //*************************************************************************************************
1781 template< typename MT // Type of the sparse matrix
1782  , bool TF // Transpose flag
1783  , ptrdiff_t... CBAs > // Compile time band arguments
1784 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
1785  Band<MT,TF,false,false,CBAs...>::find( size_t index ) const
1786 {
1787  const size_t rowIndex ( row()+index );
1788  const size_t columnIndex( column()+index );
1789  const ConstIterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1790 
1791  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1792  return ConstIterator( matrix_, rowIndex, columnIndex, pos );
1793  else
1794  return end();
1795 }
1797 //*************************************************************************************************
1798 
1799 
1800 //*************************************************************************************************
1813 template< typename MT // Type of the sparse matrix
1814  , bool TF // Transpose flag
1815  , ptrdiff_t... CBAs > // Compile time band arguments
1816 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1817  Band<MT,TF,false,false,CBAs...>::lowerBound( size_t index )
1818 {
1819  for( size_t i=index; i<size(); ++i )
1820  {
1821  const size_t rowIndex ( row()+i );
1822  const size_t columnIndex( column()+i );
1823  const Iterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1824 
1825  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1826  return Iterator( matrix_, rowIndex, columnIndex, pos );
1827  }
1828 
1829  return end();
1830 }
1832 //*************************************************************************************************
1833 
1834 
1835 //*************************************************************************************************
1848 template< typename MT // Type of the sparse matrix
1849  , bool TF // Transpose flag
1850  , ptrdiff_t... CBAs > // Compile time band arguments
1851 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
1852  Band<MT,TF,false,false,CBAs...>::lowerBound( size_t index ) const
1853 {
1854  for( size_t i=index; i<size(); ++i )
1855  {
1856  const size_t rowIndex ( row()+i );
1857  const size_t columnIndex( column()+i );
1858  const ConstIterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1859 
1860  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1861  return ConstIterator( matrix_, rowIndex, columnIndex, pos );
1862  }
1863 
1864  return end();
1865 }
1867 //*************************************************************************************************
1868 
1869 
1870 //*************************************************************************************************
1883 template< typename MT // Type of the sparse matrix
1884  , bool TF // Transpose flag
1885  , ptrdiff_t... CBAs > // Compile time band arguments
1886 inline typename Band<MT,TF,false,false,CBAs...>::Iterator
1887  Band<MT,TF,false,false,CBAs...>::upperBound( size_t index )
1888 {
1889  for( size_t i=index+1UL; i<size(); ++i )
1890  {
1891  const size_t rowIndex ( row()+i );
1892  const size_t columnIndex( column()+i );
1893  const Iterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1894 
1895  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1896  return Iterator( matrix_, rowIndex, columnIndex, pos );
1897  }
1898 
1899  return end();
1900 }
1902 //*************************************************************************************************
1903 
1904 
1905 //*************************************************************************************************
1918 template< typename MT // Type of the sparse matrix
1919  , bool TF // Transpose flag
1920  , ptrdiff_t... CBAs > // Compile time band arguments
1921 inline typename Band<MT,TF,false,false,CBAs...>::ConstIterator
1922  Band<MT,TF,false,false,CBAs...>::upperBound( size_t index ) const
1923 {
1924  for( size_t i=index+1UL; i<size(); ++i )
1925  {
1926  const size_t rowIndex ( row()+i );
1927  const size_t columnIndex( column()+i );
1928  const ConstIterator_t<MT> pos( matrix_.find( rowIndex, columnIndex ) );
1929 
1930  if( pos != matrix_.end( IsRowMajorMatrix_v<MT> ? rowIndex : columnIndex ) )
1931  return ConstIterator( matrix_, rowIndex, columnIndex, pos );
1932  }
1933 
1934  return end();
1935 }
1937 //*************************************************************************************************
1938 
1939 
1940 
1941 
1942 //=================================================================================================
1943 //
1944 // NUMERIC FUNCTIONS
1945 //
1946 //=================================================================================================
1947 
1948 //*************************************************************************************************
1961 template< typename MT // Type of the sparse matrix
1962  , bool TF // Transpose flag
1963  , ptrdiff_t... CBAs > // Compile time band arguments
1964 template< typename Other > // Data type of the scalar value
1965 inline Band<MT,TF,false,false,CBAs...>&
1966  Band<MT,TF,false,false,CBAs...>::scale( const Other& scalar )
1967 {
1969 
1970  if( ( IsLower_v<MT> && column() > 0UL ) ||
1971  ( IsStrictlyLower_v<MT> && row() == 0UL ) ||
1972  ( IsUpper_v<MT> && row() > 0UL ) ||
1973  ( IsStrictlyUpper_v<MT> && column() == 0UL ) )
1974  return *this;
1975 
1976  for( Iterator element=begin(); element!=end(); ++element )
1977  element->value() *= scalar;
1978 
1979  return *this;
1980 }
1982 //*************************************************************************************************
1983 
1984 
1985 
1986 
1987 //=================================================================================================
1988 //
1989 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1990 //
1991 //=================================================================================================
1992 
1993 //*************************************************************************************************
2004 template< typename MT // Type of the sparse matrix
2005  , bool TF // Transpose flag
2006  , ptrdiff_t... CBAs > // Compile time band arguments
2007 template< typename Other > // Data type of the foreign expression
2008 inline bool Band<MT,TF,false,false,CBAs...>::canAlias( const Other* alias ) const noexcept
2009 {
2010  return matrix_.isAliased( alias );
2011 }
2013 //*************************************************************************************************
2014 
2015 
2016 //*************************************************************************************************
2027 template< typename MT // Type of the sparse matrix
2028  , bool TF // Transpose flag
2029  , ptrdiff_t... CBAs > // Compile time band arguments
2030 template< typename Other > // Data type of the foreign expression
2031 inline bool Band<MT,TF,false,false,CBAs...>::isAliased( const Other* alias ) const noexcept
2032 {
2033  return matrix_.isAliased( alias );
2034 }
2036 //*************************************************************************************************
2037 
2038 
2039 //*************************************************************************************************
2051 template< typename MT // Type of the sparse matrix
2052  , bool TF // Transpose flag
2053  , ptrdiff_t... CBAs > // Compile time band arguments
2054 template< typename VT > // Type of the right-hand side dense vector
2055 inline void Band<MT,TF,false,false,CBAs...>::assign( const DenseVector<VT,TF>& rhs )
2056 {
2057  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2058 
2059  for( size_t i=0UL; i<(~rhs).size(); ++i ) {
2060  matrix_(row()+i,column()+i) = (~rhs)[i];
2061  }
2062 }
2064 //*************************************************************************************************
2065 
2066 
2067 //*************************************************************************************************
2079 template< typename MT // Type of the sparse matrix
2080  , bool TF // Transpose flag
2081  , ptrdiff_t... CBAs > // Compile time band arguments
2082 template< typename VT > // Type of the right-hand side sparse vector
2083 inline void Band<MT,TF,false,false,CBAs...>::assign( const SparseVector<VT,TF>& rhs )
2084 {
2085  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2086 
2087  size_t i( 0UL );
2088 
2089  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2090  for( ; i<element->index(); ++i )
2091  matrix_.erase( row()+i, column()+i );
2092  matrix_(row()+i,column()+i) = element->value();
2093  ++i;
2094  }
2095  for( ; i<size(); ++i ) {
2096  matrix_.erase( row()+i, column()+i );
2097  }
2098 }
2100 //*************************************************************************************************
2101 
2102 
2103 //*************************************************************************************************
2115 template< typename MT // Type of the sparse matrix
2116  , bool TF // Transpose flag
2117  , ptrdiff_t... CBAs > // Compile time band arguments
2118 template< typename VT > // Type of the right-hand side vector
2119 inline void Band<MT,TF,false,false,CBAs...>::addAssign( const Vector<VT,TF>& rhs )
2120 {
2121  using AddType = AddTrait_t< ResultType, ResultType_t<VT> >;
2122 
2125 
2126  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2127 
2128  const AddType tmp( serial( *this + (~rhs) ) );
2129  assign( tmp );
2130 }
2132 //*************************************************************************************************
2133 
2134 
2135 //*************************************************************************************************
2147 template< typename MT // Type of the sparse matrix
2148  , bool TF // Transpose flag
2149  , ptrdiff_t... CBAs > // Compile time band arguments
2150 template< typename VT > // Type of the right-hand side vector
2151 inline void Band<MT,TF,false,false,CBAs...>::subAssign( const Vector<VT,TF>& rhs )
2152 {
2153  using SubType = SubTrait_t< ResultType, ResultType_t<VT> >;
2154 
2157 
2158  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2159 
2160  const SubType tmp( serial( *this - (~rhs) ) );
2161  assign( tmp );
2162 }
2164 //*************************************************************************************************
2165 
2166 
2167 
2168 
2169 //=================================================================================================
2170 //
2171 // CLASS TEMPLATE SPECIALIZATION FOR SPARSE MATRIX MULTIPLICATIONS
2172 //
2173 //=================================================================================================
2174 
2175 //*************************************************************************************************
2183 template< typename MT // Type of the sparse matrix multiplication
2184  , bool TF // Transpose flag
2185  , ptrdiff_t... CBAs > // Compile time band arguments
2186 class Band<MT,TF,false,true,CBAs...>
2187  : public View< SparseVector< Band<MT,TF,false,true,CBAs...>, TF > >
2188  , private BandData<CBAs...>
2189  , private Computation
2190 {
2191  private:
2192  //**Type definitions****************************************************************************
2194  using DataType = BandData<CBAs...>;
2195 
2197  using LeftOperand = RemoveReference_t< LeftOperand_t<MT> >;
2198 
2200  using RightOperand = RemoveReference_t< RightOperand_t<MT> >;
2201  //**********************************************************************************************
2202 
2203  public:
2204  //**Type definitions****************************************************************************
2206  using This = Band<MT,TF,false,true,CBAs...>;
2207 
2209  using BaseType = SparseVector<This,TF>;
2210 
2212  using ViewedType = MT;
2213 
2215  using ResultType = BandTrait_t<ResultType_t<MT>,CBAs...>;
2216 
2217  using TransposeType = TransposeType_t<ResultType>;
2218  using ElementType = ElementType_t<ResultType>;
2219  using ReturnType = ReturnType_t<MT>;
2220  using CompositeType = const ResultType;
2221 
2223  using LT = If_t< IsSparseMatrix_v<LeftOperand> && IsColumnMajorMatrix_v<LeftOperand>
2224  , ResultType_t<LeftOperand>
2225  , CompositeType_t<LeftOperand> >;
2226 
2228  using RT = If_t< IsSparseMatrix_v<RightOperand> && IsRowMajorMatrix_v<RightOperand>
2229  , ResultType_t<RightOperand>
2230  , CompositeType_t<RightOperand> >;
2231  //**********************************************************************************************
2232 
2233  //**Compilation flags***************************************************************************
2235  static constexpr bool smpAssignable = false;
2236  //**********************************************************************************************
2237 
2238  //**Constructor*********************************************************************************
2245  template< typename... RBAs > // Runtime band arguments
2246  explicit inline Band( const MT& mmm, RBAs... args )
2247  : DataType( args... ) // Base class initialization
2248  , matrix_ ( mmm ) // The matrix multiplication containing the band
2249  {
2250  if( !Contains_v< TypeList<RBAs...>, Unchecked > ) {
2251  if( ( band() > 0L && column() >= mmm.columns() ) ||
2252  ( band() < 0L && row() >= mmm.rows() ) ) {
2253  BLAZE_THROW_INVALID_ARGUMENT( "Invalid band access index" );
2254  }
2255  }
2256  else {
2257  BLAZE_USER_ASSERT( band() <= 0L || column() < mmm.columns(), "Invalid band access index" );
2258  BLAZE_USER_ASSERT( band() >= 0L || row() < mmm.rows(), "Invalid band access index" );
2259  }
2260  }
2261  //**********************************************************************************************
2262 
2263  //**Subscript operator**************************************************************************
2269  inline ReturnType operator[]( size_t index ) const {
2270  BLAZE_INTERNAL_ASSERT( index < size(), "Invalid vector access index" );
2271  return matrix_(row()+index,column()+index);
2272  }
2273  //**********************************************************************************************
2274 
2275  //**At function*********************************************************************************
2282  inline ReturnType at( size_t index ) const {
2283  if( index >= size() ) {
2284  BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
2285  }
2286  return (*this)[index];
2287  }
2288  //**********************************************************************************************
2289 
2290  //**Size function*******************************************************************************
2295  inline size_t size() const noexcept {
2296  return min( matrix_.rows() - row(), matrix_.columns() - column() );
2297  }
2298  //**********************************************************************************************
2299 
2300  //**NonZeros function***************************************************************************
2305  inline size_t nonZeros() const {
2306  return 0UL;
2307  }
2308  //**********************************************************************************************
2309 
2310  //**********************************************************************************************
2311  using DataType::band;
2312  using DataType::row;
2313  using DataType::column;
2314  //**********************************************************************************************
2315 
2316  //**Operand access******************************************************************************
2321  inline const MT& operand() const noexcept {
2322  return matrix_;
2323  }
2324  //**********************************************************************************************
2325 
2326  //**********************************************************************************************
2332  template< typename T >
2333  inline bool canAlias( const T* alias ) const noexcept {
2334  return matrix_.isAliased( alias );
2335  }
2336  //**********************************************************************************************
2337 
2338  //**********************************************************************************************
2344  template< typename T >
2345  inline bool isAliased( const T* alias ) const noexcept {
2346  return matrix_.isAliased( alias );
2347  }
2348  //**********************************************************************************************
2349 
2350  private:
2351  //**Member variables****************************************************************************
2352  MT matrix_;
2353  //**********************************************************************************************
2354 
2355  //**Assignment to dense vectors*****************************************************************
2367  template< typename VT > // Type of the target dense vector
2368  friend inline void assign( DenseVector<VT,TF>& lhs, const Band& rhs )
2369  {
2370  using blaze::row;
2371  using blaze::column;
2372 
2374 
2375  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2376 
2377  LT A( serial( rhs.operand().leftOperand() ) );
2378  RT B( serial( rhs.operand().rightOperand() ) );
2379 
2380  const size_t n( rhs.size() );
2381  for( size_t i=0UL; i<n; ++i ) {
2382  (~lhs)[i] = row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2383  }
2384  }
2386  //**********************************************************************************************
2387 
2388  //**Assignment to sparse vectors****************************************************************
2400  template< typename VT > // Type of the target sparse vector
2401  friend inline void assign( SparseVector<VT,TF>& lhs, const Band& rhs )
2402  {
2403  using blaze::row;
2404  using blaze::column;
2405 
2407 
2408  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2409 
2410  LT A( serial( rhs.operand().leftOperand() ) );
2411  RT B( serial( rhs.operand().rightOperand() ) );
2412 
2413  const size_t n( rhs.size() );
2414  ElementType_t<VT> tmp{};
2415  size_t nonzeros( 0UL );
2416 
2417  for( size_t i=0UL; i<n; ++i ) {
2418  tmp = row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2419  if( !isDefault<strict>( tmp ) ) {
2420  if( (~lhs).capacity() <= nonzeros ) {
2421  (~lhs).reserve( min( max( 2UL*(~lhs).capacity(), 7UL ), (~lhs).size() ) );
2422  }
2423  (~lhs).append( i, tmp, false );
2424  ++nonzeros;
2425  }
2426  }
2427  }
2429  //**********************************************************************************************
2430 
2431  //**Addition assignment to dense vectors********************************************************
2443  template< typename VT > // Type of the target dense vector
2444  friend inline void addAssign( DenseVector<VT,TF>& lhs, const Band& rhs )
2445  {
2446  using blaze::row;
2447  using blaze::column;
2448 
2450 
2451  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2452 
2453  LT A( serial( rhs.operand().leftOperand() ) );
2454  RT B( serial( rhs.operand().rightOperand() ) );
2455 
2456  const size_t n( rhs.size() );
2457  for( size_t i=0UL; i<n; ++i ) {
2458  (~lhs)[i] += row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2459  }
2460  }
2462  //**********************************************************************************************
2463 
2464  //**Addition assignment to sparse vectors*******************************************************
2465  // No special implementation for the addition assignment to sparse vectors.
2466  //**********************************************************************************************
2467 
2468  //**Subtraction assignment to dense vectors*****************************************************
2480  template< typename VT > // Type of the target dense vector
2481  friend inline void subAssign( DenseVector<VT,TF>& lhs, const Band& rhs )
2482  {
2483  using blaze::row;
2484  using blaze::column;
2485 
2487 
2488  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2489 
2490  LT A( serial( rhs.operand().leftOperand() ) );
2491  RT B( serial( rhs.operand().rightOperand() ) );
2492 
2493  const size_t n( rhs.size() );
2494  for( size_t i=0UL; i<n; ++i ) {
2495  (~lhs)[i] -= row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2496  }
2497  }
2499  //**********************************************************************************************
2500 
2501  //**Subtraction assignment to sparse vectors****************************************************
2502  // No special implementation for the subtraction assignment to sparse vectors.
2503  //**********************************************************************************************
2504 
2505  //**Multiplication assignment to dense vectors**************************************************
2518  template< typename VT > // Type of the target dense vector
2519  friend inline void multAssign( DenseVector<VT,TF>& lhs, const Band& rhs )
2520  {
2521  using blaze::row;
2522  using blaze::column;
2523 
2525 
2526  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
2527 
2528  LT A( serial( rhs.operand().leftOperand() ) );
2529  RT B( serial( rhs.operand().rightOperand() ) );
2530 
2531  const size_t n( rhs.size() );
2532  for( size_t i=0UL; i<n; ++i ) {
2533  (~lhs)[i] *= row( A, rhs.row()+i, unchecked ) * column( B, rhs.column()+i, unchecked );
2534  }
2535  }
2537  //**********************************************************************************************
2538 
2539  //**Multiplication assignment to sparse vectors*************************************************
2540  // No special implementation for the multiplication assignment to sparse vectors.
2541  //**********************************************************************************************
2542 
2543  //**Compile time checks*************************************************************************
2550  //**********************************************************************************************
2551 };
2552 //*************************************************************************************************
2553 
2554 } // namespace blaze
2555 
2556 #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.
#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
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:354
Header file for the UNUSED_PARAMETER function template.
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
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3077
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
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
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:591
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
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.
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3079
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:3084
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.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3085
#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
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.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.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3083
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:3076
#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:3080
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:1147
#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:3086
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:139
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.
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:1179
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
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:8908
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:611
decltype(auto) band(Matrix< MT, SO > &matrix, RBAs... args)
Creating a view on a specific band of the given matrix.
Definition: Band.h:135
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
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: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, a compilation error is created.
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
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
#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.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3082
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:290
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
constexpr bool IsIntegral_v
Auxiliary variable template for the IsIntegral type trait.The IsIntegral_v variable template provides...
Definition: IsIntegral.h:95
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.
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, 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.