Blaze  3.6
Dense.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_ROWS_DENSE_H_
36 #define _BLAZE_MATH_VIEWS_ROWS_DENSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <blaze/math/Aliases.h>
57 #include <blaze/math/Exception.h>
61 #include <blaze/math/shims/Reset.h>
62 #include <blaze/math/SIMD.h>
81 #include <blaze/math/views/Check.h>
84 #include <blaze/system/Blocking.h>
85 #include <blaze/system/CacheSize.h>
86 #include <blaze/system/Inline.h>
89 #include <blaze/util/Assert.h>
93 #include <blaze/util/DisableIf.h>
94 #include <blaze/util/EnableIf.h>
95 #include <blaze/util/MaybeUnused.h>
96 #include <blaze/util/mpl/If.h>
97 #include <blaze/util/TypeList.h>
98 #include <blaze/util/Types.h>
101 
102 
103 namespace blaze {
104 
105 //=================================================================================================
106 //
107 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR DENSE MATRICES
108 //
109 //=================================================================================================
110 
111 //*************************************************************************************************
119 template< typename MT // Type of the dense matrix
120  , bool SF // Symmetry flag
121  , typename... CRAs > // Compile time row arguments
122 class Rows<MT,true,true,SF,CRAs...>
123  : public View< DenseMatrix< Rows<MT,true,true,SF,CRAs...>, false > >
124  , private RowsData<CRAs...>
125 {
126  private:
127  //**Type definitions****************************************************************************
128  using DataType = RowsData<CRAs...>;
129  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
130  //**********************************************************************************************
131 
132  //**Compile time flags**************************************************************************
133  using DataType::N;
134  //**********************************************************************************************
135 
136  //**********************************************************************************************
138  template< typename MT1, typename MT2 >
139  static constexpr bool EnforceEvaluation_v =
140  ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
141  //**********************************************************************************************
142 
143  public:
144  //**Type definitions****************************************************************************
146  using This = Rows<MT,true,true,SF,CRAs...>;
147 
148  using BaseType = DenseMatrix<This,false>;
149  using ViewedType = MT;
150  using ResultType = RowsTrait_t<MT,N>;
151  using OppositeType = OppositeType_t<ResultType>;
152  using TransposeType = TransposeType_t<ResultType>;
153  using ElementType = ElementType_t<MT>;
154  using SIMDType = SIMDTrait_t<ElementType>;
155  using ReturnType = ReturnType_t<MT>;
156  using CompositeType = const Rows&;
157 
159  using ConstReference = ConstReference_t<MT>;
160 
162  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
163 
165  using ConstPointer = ConstPointer_t<MT>;
166 
168  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
169 
171  using ConstIterator = ConstIterator_t<MT>;
172 
174  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
175  //**********************************************************************************************
176 
177  //**Compilation flags***************************************************************************
179  static constexpr bool simdEnabled = MT::simdEnabled;
180 
182  static constexpr bool smpAssignable = MT::smpAssignable;
183 
185  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
186  //**********************************************************************************************
187 
188  //**Constructors********************************************************************************
191  template< typename... RRAs >
192  explicit inline Rows( MT& matrix, RRAs... args );
193 
194  Rows( const Rows& ) = default;
195  Rows( Rows&& ) = default;
197  //**********************************************************************************************
198 
199  //**Destructor**********************************************************************************
202  ~Rows() = default;
204  //**********************************************************************************************
205 
206  //**Data access functions***********************************************************************
209  inline Reference operator()( size_t i, size_t j );
210  inline ConstReference operator()( size_t i, size_t j ) const;
211  inline Reference at( size_t i, size_t j );
212  inline ConstReference at( size_t i, size_t j ) const;
213  inline Pointer data () noexcept;
214  inline ConstPointer data () const noexcept;
215  inline Pointer data ( size_t i ) noexcept;
216  inline ConstPointer data ( size_t i ) const noexcept;
217  inline Iterator begin ( size_t i );
218  inline ConstIterator begin ( size_t i ) const;
219  inline ConstIterator cbegin( size_t i ) const;
220  inline Iterator end ( size_t i );
221  inline ConstIterator end ( size_t i ) const;
222  inline ConstIterator cend ( size_t i ) const;
224  //**********************************************************************************************
225 
226  //**Assignment operators************************************************************************
229  inline Rows& operator=( const ElementType& rhs );
230  inline Rows& operator=( initializer_list< initializer_list<ElementType> > list );
231  inline Rows& operator=( const Rows& rhs );
232 
233  template< typename MT2, bool SO2 >
234  inline Rows& operator=( const Matrix<MT2,SO2>& rhs );
235 
236  template< typename MT2, bool SO2 >
237  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
238  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
239 
240  template< typename MT2, bool SO2 >
241  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
242  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
243 
244  template< typename MT2, bool SO2 >
245  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
246  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
247 
248  template< typename MT2, bool SO2 >
249  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
250  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
251 
252  template< typename MT2, bool SO2 >
253  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
254  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
255 
256  template< typename MT2, bool SO2 >
257  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
258  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
260  //**********************************************************************************************
261 
262  //**Utility functions***************************************************************************
265  using DataType::idx;
266  using DataType::idces;
267  using DataType::rows;
268 
269  inline MT& operand() noexcept;
270  inline const MT& operand() const noexcept;
271 
272  inline size_t columns() const noexcept;
273  inline size_t spacing() const noexcept;
274  inline size_t capacity() const noexcept;
275  inline size_t capacity( size_t i ) const noexcept;
276  inline size_t nonZeros() const;
277  inline size_t nonZeros( size_t i ) const;
278  inline void reset();
279  inline void reset( size_t i );
281  //**********************************************************************************************
282 
283  //**Numeric functions***************************************************************************
286  inline Rows& transpose();
287  inline Rows& ctranspose();
288 
289  template< typename Other > inline Rows& scale( const Other& scalar );
291  //**********************************************************************************************
292 
293  private:
294  //**********************************************************************************************
296  template< typename MT2 >
297  static constexpr bool VectorizedAssign_v =
298  ( useOptimizedKernels &&
299  simdEnabled && MT2::simdEnabled &&
300  IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > );
301  //**********************************************************************************************
302 
303  //**********************************************************************************************
305  template< typename MT2 >
306  static constexpr bool VectorizedAddAssign_v =
307  ( useOptimizedKernels &&
308  simdEnabled && MT2::simdEnabled &&
309  IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > &&
310  HasSIMDAdd_v< ElementType, ElementType_t<MT2> > &&
311  !IsDiagonal_v<MT2> );
312  //**********************************************************************************************
313 
314  //**********************************************************************************************
316  template< typename MT2 >
317  static constexpr bool VectorizedSubAssign_v =
318  ( useOptimizedKernels &&
319  simdEnabled && MT2::simdEnabled &&
320  IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > &&
321  HasSIMDSub_v< ElementType, ElementType_t<MT2> > &&
322  !IsDiagonal_v<MT2> );
323  //**********************************************************************************************
324 
325  //**********************************************************************************************
327  template< typename MT2 >
328  static constexpr bool VectorizedSchurAssign_v =
329  ( useOptimizedKernels &&
330  simdEnabled && MT2::simdEnabled &&
331  IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > &&
332  HasSIMDMult_v< ElementType, ElementType_t<MT2> > );
333  //**********************************************************************************************
334 
335  //**SIMD properties*****************************************************************************
337  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
338  //**********************************************************************************************
339 
340  public:
341  //**Expression template evaluation functions****************************************************
344  template< typename Other >
345  inline bool canAlias( const Other* alias ) const noexcept;
346 
347  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
348  inline bool canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
349 
350  template< typename Other >
351  inline bool isAliased( const Other* alias ) const noexcept;
352 
353  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
354  inline bool isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
355 
356  inline bool isAligned () const noexcept;
357  inline bool canSMPAssign() const noexcept;
358 
359  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
360  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
361  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
362 
363  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
364  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
365  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
366  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
367 
368  template< typename MT2 >
369  inline auto assign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT2> >;
370 
371  template< typename MT2 >
372  inline auto assign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT2> >;
373 
374  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
375 
376  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
377  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
378 
379  template< typename MT2 >
380  inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT2> >;
381 
382  template< typename MT2 >
383  inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT2> >;
384 
385  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
386  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
387  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
388 
389  template< typename MT2 >
390  inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT2> >;
391 
392  template< typename MT2 >
393  inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT2> >;
394 
395  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
396  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
397  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
398 
399  template< typename MT2 >
400  inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT2> >;
401 
402  template< typename MT2 >
403  inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT2> >;
404 
405  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
406  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
407  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
409  //**********************************************************************************************
410 
411  private:
412  //**Member variables****************************************************************************
415  Operand matrix_;
416 
417  //**********************************************************************************************
418 
419  //**Friend declarations*************************************************************************
420  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CRAs2 > friend class Rows;
421  //**********************************************************************************************
422 
423  //**Compile time checks*************************************************************************
432  //**********************************************************************************************
433 };
435 //*************************************************************************************************
436 
437 
438 
439 
440 //=================================================================================================
441 //
442 // CONSTRUCTORS
443 //
444 //=================================================================================================
445 
446 //*************************************************************************************************
459 template< typename MT // Type of the dense matrix
460  , bool SF // Symmetry flag
461  , typename... CRAs > // Compile time row arguments
462 template< typename... RRAs > // Runtime row arguments
463 inline Rows<MT,true,true,SF,CRAs...>::Rows( MT& matrix, RRAs... args )
464  : DataType( args... ) // Base class initialization
465  , matrix_ ( matrix ) // The matrix containing the rows
466 {
467  if( !Contains_v< TypeList<RRAs...>, Unchecked > ) {
468  for( size_t i=0UL; i<rows(); ++i ) {
469  if( matrix_.rows() <= idx(i) ) {
470  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
471  }
472  }
473  }
474 }
476 //*************************************************************************************************
477 
478 
479 
480 
481 //=================================================================================================
482 //
483 // DATA ACCESS FUNCTIONS
484 //
485 //=================================================================================================
486 
487 //*************************************************************************************************
498 template< typename MT // Type of the dense matrix
499  , bool SF // Symmetry flag
500  , typename... CRAs > // Compile time row arguments
501 inline typename Rows<MT,true,true,SF,CRAs...>::Reference
502  Rows<MT,true,true,SF,CRAs...>::operator()( size_t i, size_t j )
503 {
504  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
505  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
506 
507  return matrix_(idx(i),j);
508 }
510 //*************************************************************************************************
511 
512 
513 //*************************************************************************************************
524 template< typename MT // Type of the dense matrix
525  , bool SF // Symmetry flag
526  , typename... CRAs > // Compile time row arguments
527 inline typename Rows<MT,true,true,SF,CRAs...>::ConstReference
528  Rows<MT,true,true,SF,CRAs...>::operator()( size_t i, size_t j ) const
529 {
530  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
531  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
532 
533  return const_cast<const MT&>( matrix_ )(idx(i),j);
534 }
536 //*************************************************************************************************
537 
538 
539 //*************************************************************************************************
551 template< typename MT // Type of the dense matrix
552  , bool SF // Symmetry flag
553  , typename... CRAs > // Compile time row arguments
554 inline typename Rows<MT,true,true,SF,CRAs...>::Reference
555  Rows<MT,true,true,SF,CRAs...>::at( size_t i, size_t j )
556 {
557  if( i >= rows() ) {
558  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
559  }
560  if( j >= columns() ) {
561  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
562  }
563  return (*this)(i,j);
564 }
566 //*************************************************************************************************
567 
568 
569 //*************************************************************************************************
581 template< typename MT // Type of the dense matrix
582  , bool SF // Symmetry flag
583  , typename... CRAs > // Compile time row arguments
584 inline typename Rows<MT,true,true,SF,CRAs...>::ConstReference
585  Rows<MT,true,true,SF,CRAs...>::at( size_t i, size_t j ) const
586 {
587  if( i >= rows() ) {
588  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
589  }
590  if( j >= columns() ) {
591  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
592  }
593  return (*this)(i,j);
594 }
596 //*************************************************************************************************
597 
598 
599 //*************************************************************************************************
609 template< typename MT // Type of the dense matrix
610  , bool SF // Symmetry flag
611  , typename... CRAs > // Compile time row arguments
612 inline typename Rows<MT,true,true,SF,CRAs...>::Pointer
614 {
615  return matrix_.data( idx(0UL) );
616 }
618 //*************************************************************************************************
619 
620 
621 //*************************************************************************************************
631 template< typename MT // Type of the dense matrix
632  , bool SF // Symmetry flag
633  , typename... CRAs > // Compile time row arguments
634 inline typename Rows<MT,true,true,SF,CRAs...>::ConstPointer
635  Rows<MT,true,true,SF,CRAs...>::data() const noexcept
636 {
637  return matrix_.data( idx(0UL) );
638 }
640 //*************************************************************************************************
641 
642 
643 //*************************************************************************************************
652 template< typename MT // Type of the dense matrix
653  , bool SF // Symmetry flag
654  , typename... CRAs > // Compile time row arguments
655 inline typename Rows<MT,true,true,SF,CRAs...>::Pointer
656  Rows<MT,true,true,SF,CRAs...>::data( size_t i ) noexcept
657 {
658  return matrix_.data( idx(i) );
659 }
661 //*************************************************************************************************
662 
663 
664 //*************************************************************************************************
673 template< typename MT // Type of the dense matrix
674  , bool SF // Symmetry flag
675  , typename... CRAs > // Compile time row arguments
676 inline typename Rows<MT,true,true,SF,CRAs...>::ConstPointer
677  Rows<MT,true,true,SF,CRAs...>::data( size_t i ) const noexcept
678 {
679  return matrix_.data( idx(i) );
680 }
682 //*************************************************************************************************
683 
684 
685 //*************************************************************************************************
694 template< typename MT // Type of the dense matrix
695  , bool SF // Symmetry flag
696  , typename... CRAs > // Compile time row arguments
697 inline typename Rows<MT,true,true,SF,CRAs...>::Iterator
699 {
700  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
701  return matrix_.begin( idx(i) );
702 }
704 //*************************************************************************************************
705 
706 
707 //*************************************************************************************************
716 template< typename MT // Type of the dense matrix
717  , bool SF // Symmetry flag
718  , typename... CRAs > // Compile time row arguments
719 inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
720  Rows<MT,true,true,SF,CRAs...>::begin( size_t i ) const
721 {
722  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
723  return matrix_.cbegin( idx(i) );
724 }
726 //*************************************************************************************************
727 
728 
729 //*************************************************************************************************
738 template< typename MT // Type of the dense matrix
739  , bool SF // Symmetry flag
740  , typename... CRAs > // Compile time row arguments
741 inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
742  Rows<MT,true,true,SF,CRAs...>::cbegin( size_t i ) const
743 {
744  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
745  return matrix_.cbegin( idx(i) );
746 }
748 //*************************************************************************************************
749 
750 
751 //*************************************************************************************************
760 template< typename MT // Type of the dense matrix
761  , bool SF // Symmetry flag
762  , typename... CRAs > // Compile time row arguments
763 inline typename Rows<MT,true,true,SF,CRAs...>::Iterator
765 {
766  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
767  return matrix_.end( idx(i) );
768 }
770 //*************************************************************************************************
771 
772 
773 //*************************************************************************************************
782 template< typename MT // Type of the dense matrix
783  , bool SF // Symmetry flag
784  , typename... CRAs > // Compile time row arguments
785 inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
786  Rows<MT,true,true,SF,CRAs...>::end( size_t i ) const
787 {
788  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
789  return matrix_.cend( idx(i) );
790 }
792 //*************************************************************************************************
793 
794 
795 //*************************************************************************************************
804 template< typename MT // Type of the dense matrix
805  , bool SF // Symmetry flag
806  , typename... CRAs > // Compile time row arguments
807 inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
808  Rows<MT,true,true,SF,CRAs...>::cend( size_t i ) const
809 {
810  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
811  return matrix_.cend( idx(i) );
812 }
814 //*************************************************************************************************
815 
816 
817 
818 
819 //=================================================================================================
820 //
821 // ASSIGNMENT OPERATORS
822 //
823 //=================================================================================================
824 
825 //*************************************************************************************************
836 template< typename MT // Type of the dense matrix
837  , bool SF // Symmetry flag
838  , typename... CRAs > // Compile time row arguments
839 inline Rows<MT,true,true,SF,CRAs...>&
840  Rows<MT,true,true,SF,CRAs...>::operator=( const ElementType& rhs )
841 {
842  for( size_t i=0UL; i<rows(); ++i ) {
843  row( matrix_, idx(i), unchecked ) = rhs;
844  }
845 
846  return *this;
847 }
849 //*************************************************************************************************
850 
851 
852 //*************************************************************************************************
868 template< typename MT // Type of the dense matrix
869  , bool SF // Symmetry flag
870  , typename... CRAs > // Compile time row arguments
871 inline Rows<MT,true,true,SF,CRAs...>&
872  Rows<MT,true,true,SF,CRAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
873 {
876 
877  if( list.size() != rows() ) {
878  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row selection" );
879  }
880 
881  if( IsRestricted_v<MT> ) {
882  size_t i( 0UL );
883  for( const auto& rowList : list ) {
884  const InitializerVector<ElementType> tmp( rowList, columns() );
885  if( !tryAssign( row( matrix_, idx(i), unchecked ), tmp, 0UL ) ){
886  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
887  }
888  ++i;
889  }
890  }
891 
892  decltype(auto) left( derestrict( *this ) );
893  size_t i( 0UL );
894 
895  for( const auto& rowList : list ) {
896  std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
897  ++i;
898  }
899 
900  return *this;
901 }
903 //*************************************************************************************************
904 
905 
906 //*************************************************************************************************
921 template< typename MT // Type of the dense matrix
922  , bool SF // Symmetry flag
923  , typename... CRAs > // Compile time row arguments
924 inline Rows<MT,true,true,SF,CRAs...>&
925  Rows<MT,true,true,SF,CRAs...>::operator=( const Rows& rhs )
926 {
929 
932 
933  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
934  return *this;
935 
936  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
937  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
938  }
939 
940  if( IsRestricted_v<MT> ) {
941  for( size_t i=0UL; i<rows(); ++i ) {
942  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( rhs, i, unchecked ), 0UL ) ) {
943  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
944  }
945  }
946  }
947 
948  decltype(auto) left( derestrict( *this ) );
949 
950  if( rhs.canAlias( &matrix_ ) ) {
951  const ResultType tmp( rhs );
952  smpAssign( left, tmp );
953  }
954  else {
955  smpAssign( left, rhs );
956  }
957 
958  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
959 
960  return *this;
961 }
963 //*************************************************************************************************
964 
965 
966 //*************************************************************************************************
981 template< typename MT // Type of the dense matrix
982  , bool SF // Symmetry flag
983  , typename... CRAs > // Compile time row arguments
984 template< typename MT2 // Type of the right-hand side matrix
985  , bool SO2 > // Storage order of the right-hand side matrix
986 inline Rows<MT,true,true,SF,CRAs...>&
987  Rows<MT,true,true,SF,CRAs...>::operator=( const Matrix<MT2,SO2>& rhs )
988 {
991 
993 
994  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
995  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
996  }
997 
998  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
999  Right right( ~rhs );
1000 
1001  if( IsRestricted_v<MT> ) {
1002  for( size_t i=0UL; i<rows(); ++i ) {
1003  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( right, i, unchecked ), 0UL ) ) {
1004  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1005  }
1006  }
1007  }
1008 
1009  decltype(auto) left( derestrict( *this ) );
1010 
1011  if( IsSparseMatrix_v<MT2> ) {
1012  reset();
1013  }
1014 
1015  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
1016  const ResultType_t<MT2> tmp( right );
1017  smpAssign( left, tmp );
1018  }
1019  else {
1020  smpAssign( left, right );
1021  }
1022 
1023  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1024 
1025  return *this;
1026 }
1028 //*************************************************************************************************
1029 
1030 
1031 //*************************************************************************************************
1045 template< typename MT // Type of the dense matrix
1046  , bool SF // Symmetry flag
1047  , typename... CRAs > // Compile time row arguments
1048 template< typename MT2 // Type of the right-hand side matrix
1049  , bool SO2 > // Storage order of the right-hand side matrix
1050 inline auto Rows<MT,true,true,SF,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1051  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1052 {
1055 
1058  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1059 
1060  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1061 
1064 
1065  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1066  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1067  }
1068 
1069  if( IsRestricted_v<MT> ) {
1070  for( size_t i=0UL; i<rows(); ++i ) {
1071  if( !tryAddAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
1072  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1073  }
1074  }
1075  }
1076 
1077  decltype(auto) left( derestrict( *this ) );
1078 
1079  if( (~rhs).canAlias( &matrix_ ) ) {
1080  const AddType tmp( *this + (~rhs) );
1081  smpAssign( left, tmp );
1082  }
1083  else {
1084  smpAddAssign( left, ~rhs );
1085  }
1086 
1087  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1088 
1089  return *this;
1090 }
1092 //*************************************************************************************************
1093 
1094 
1095 //*************************************************************************************************
1109 template< typename MT // Type of the dense matrix
1110  , bool SF // Symmetry flag
1111  , typename... CRAs > // Compile time row arguments
1112 template< typename MT2 // Type of the right-hand side matrix
1113  , bool SO2 > // Storage order of the right-hand side matrix
1114 inline auto Rows<MT,true,true,SF,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1115  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1116 {
1119 
1122  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1123 
1124  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1125 
1128 
1129  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1130  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1131  }
1132 
1133  const AddType tmp( *this + (~rhs) );
1134 
1135  if( IsRestricted_v<MT> ) {
1136  for( size_t i=0UL; i<rows(); ++i ) {
1137  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
1138  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1139  }
1140  }
1141  }
1142 
1143  decltype(auto) left( derestrict( *this ) );
1144 
1145  smpAssign( left, tmp );
1146 
1147  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1148 
1149  return *this;
1150 }
1152 //*************************************************************************************************
1153 
1154 
1155 //*************************************************************************************************
1169 template< typename MT // Type of the dense matrix
1170  , bool SF // Symmetry flag
1171  , typename... CRAs > // Compile time row arguments
1172 template< typename MT2 // Type of the right-hand side matrix
1173  , bool SO2 > // Storage order of the right-hand side matrix
1174 inline auto Rows<MT,true,true,SF,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1175  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1176 {
1179 
1182  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1183 
1184  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1185 
1188 
1189  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1190  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1191  }
1192 
1193  if( IsRestricted_v<MT> ) {
1194  for( size_t i=0UL; i<rows(); ++i ) {
1195  if( !trySubAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
1196  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1197  }
1198  }
1199  }
1200 
1201  decltype(auto) left( derestrict( *this ) );
1202 
1203  if( (~rhs).canAlias( &matrix_ ) ) {
1204  const SubType tmp( *this - (~rhs ) );
1205  smpAssign( left, tmp );
1206  }
1207  else {
1208  smpSubAssign( left, ~rhs );
1209  }
1210 
1211  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1212 
1213  return *this;
1214 }
1216 //*************************************************************************************************
1217 
1218 
1219 //*************************************************************************************************
1233 template< typename MT // Type of the dense matrix
1234  , bool SF // Symmetry flag
1235  , typename... CRAs > // Compile time row arguments
1236 template< typename MT2 // Type of the right-hand side matrix
1237  , bool SO2 > // Storage order of the right-hand side matrix
1238 inline auto Rows<MT,true,true,SF,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1239  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1240 {
1243 
1246  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1247 
1248  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1249 
1252 
1253  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1254  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1255  }
1256 
1257  const SubType tmp( *this - (~rhs) );
1258 
1259  if( IsRestricted_v<MT> ) {
1260  for( size_t i=0UL; i<rows(); ++i ) {
1261  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
1262  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1263  }
1264  }
1265  }
1266 
1267  decltype(auto) left( derestrict( *this ) );
1268 
1269  smpAssign( left, tmp );
1270 
1271  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1272 
1273  return *this;
1274 }
1276 //*************************************************************************************************
1277 
1278 
1279 //*************************************************************************************************
1293 template< typename MT // Type of the dense matrix
1294  , bool SF // Symmetry flag
1295  , typename... CRAs > // Compile time row arguments
1296 template< typename MT2 // Type of the right-hand side matrix
1297  , bool SO2 > // Storage order of the right-hand side matrix
1298 inline auto Rows<MT,true,true,SF,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1299  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1300 {
1303 
1306  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1307 
1308  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1309 
1311 
1312  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1313  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1314  }
1315 
1316  if( IsRestricted_v<MT> ) {
1317  for( size_t i=0UL; i<rows(); ++i ) {
1318  if( !tryMultAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
1319  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1320  }
1321  }
1322  }
1323 
1324  decltype(auto) left( derestrict( *this ) );
1325 
1326  if( (~rhs).canAlias( &matrix_ ) ) {
1327  const SchurType tmp( *this % (~rhs) );
1328  if( IsSparseMatrix_v<SchurType> )
1329  reset();
1330  smpAssign( left, tmp );
1331  }
1332  else {
1333  smpSchurAssign( left, ~rhs );
1334  }
1335 
1336  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1337 
1338  return *this;
1339 }
1341 //*************************************************************************************************
1342 
1343 
1344 //*************************************************************************************************
1358 template< typename MT // Type of the dense matrix
1359  , bool SF // Symmetry flag
1360  , typename... CRAs > // Compile time row arguments
1361 template< typename MT2 // Type of the right-hand side matrix
1362  , bool SO2 > // Storage order of the right-hand side matrix
1363 inline auto Rows<MT,true,true,SF,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1364  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1365 {
1368 
1371  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1372 
1373  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1374 
1376 
1377  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1378  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1379  }
1380 
1381  const SchurType tmp( *this % (~rhs) );
1382 
1383  if( IsRestricted_v<MT> ) {
1384  for( size_t i=0UL; i<rows(); ++i ) {
1385  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
1386  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1387  }
1388  }
1389  }
1390 
1391  decltype(auto) left( derestrict( *this ) );
1392 
1393  if( IsSparseMatrix_v<SchurType> ) {
1394  reset();
1395  }
1396 
1397  smpAssign( left, tmp );
1398 
1399  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1400 
1401  return *this;
1402 }
1404 //*************************************************************************************************
1405 
1406 
1407 
1408 
1409 //=================================================================================================
1410 //
1411 // UTILITY FUNCTIONS
1412 //
1413 //=================================================================================================
1414 
1415 //*************************************************************************************************
1421 template< typename MT // Type of the dense matrix
1422  , bool SF // Symmetry flag
1423  , typename... CRAs > // Compile time row arguments
1424 inline MT& Rows<MT,true,true,SF,CRAs...>::operand() noexcept
1425 {
1426  return matrix_;
1427 }
1429 //*************************************************************************************************
1430 
1431 
1432 //*************************************************************************************************
1438 template< typename MT // Type of the dense matrix
1439  , bool SF // Symmetry flag
1440  , typename... CRAs > // Compile time row arguments
1441 inline const MT& Rows<MT,true,true,SF,CRAs...>::operand() const noexcept
1442 {
1443  return matrix_;
1444 }
1446 //*************************************************************************************************
1447 
1448 
1449 //*************************************************************************************************
1455 template< typename MT // Type of the dense matrix
1456  , bool SF // Symmetry flag
1457  , typename... CRAs > // Compile time row arguments
1458 inline size_t Rows<MT,true,true,SF,CRAs...>::columns() const noexcept
1459 {
1460  return matrix_.columns();
1461 }
1463 //*************************************************************************************************
1464 
1465 
1466 //*************************************************************************************************
1475 template< typename MT // Type of the dense matrix
1476  , bool SF // Symmetry flag
1477  , typename... CRAs > // Compile time row arguments
1478 inline size_t Rows<MT,true,true,SF,CRAs...>::spacing() const noexcept
1479 {
1480  return matrix_.spacing();
1481 }
1483 //*************************************************************************************************
1484 
1485 
1486 //*************************************************************************************************
1492 template< typename MT // Type of the dense matrix
1493  , bool SF // Symmetry flag
1494  , typename... CRAs > // Compile time row arguments
1495 inline size_t Rows<MT,true,true,SF,CRAs...>::capacity() const noexcept
1496 {
1497  return rows() * columns();
1498 }
1500 //*************************************************************************************************
1501 
1502 
1503 //*************************************************************************************************
1512 template< typename MT // Type of the dense matrix
1513  , bool SF // Symmetry flag
1514  , typename... CRAs > // Compile time row arguments
1515 inline size_t Rows<MT,true,true,SF,CRAs...>::capacity( size_t i ) const noexcept
1516 {
1517  MAYBE_UNUSED( i );
1518 
1519  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1520 
1521  return columns();
1522 }
1524 //*************************************************************************************************
1525 
1526 
1527 //*************************************************************************************************
1533 template< typename MT // Type of the dense matrix
1534  , bool SF // Symmetry flag
1535  , typename... CRAs > // Compile time row arguments
1536 inline size_t Rows<MT,true,true,SF,CRAs...>::nonZeros() const
1537 {
1538  size_t nonzeros( 0UL );
1539 
1540  for( size_t i=0UL; i<rows(); ++i ) {
1541  nonzeros += matrix_.nonZeros( idx(i) );
1542  }
1543 
1544  return nonzeros;
1545 }
1547 //*************************************************************************************************
1548 
1549 
1550 //*************************************************************************************************
1559 template< typename MT // Type of the dense matrix
1560  , bool SF // Symmetry flag
1561  , typename... CRAs > // Compile time row arguments
1562 inline size_t Rows<MT,true,true,SF,CRAs...>::nonZeros( size_t i ) const
1563 {
1564  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1565 
1566  return matrix_.nonZeros( idx(i) );
1567 }
1569 //*************************************************************************************************
1570 
1571 
1572 //*************************************************************************************************
1578 template< typename MT // Type of the dense matrix
1579  , bool SF // Symmetry flag
1580  , typename... CRAs > // Compile time row arguments
1582 {
1583  for( size_t i=0UL; i<rows(); ++i ) {
1584  matrix_.reset( idx(i) );
1585  }
1586 }
1588 //*************************************************************************************************
1589 
1590 
1591 //*************************************************************************************************
1600 template< typename MT // Type of the dense matrix
1601  , bool SF // Symmetry flag
1602  , typename... CRAs > // Compile time row arguments
1603 inline void Rows<MT,true,true,SF,CRAs...>::reset( size_t i )
1604 {
1605  matrix_.reset( idx(i) );
1606 }
1608 //*************************************************************************************************
1609 
1610 
1611 
1612 
1613 //=================================================================================================
1614 //
1615 // NUMERIC FUNCTIONS
1616 //
1617 //=================================================================================================
1618 
1619 //*************************************************************************************************
1632 template< typename MT // Type of the dense matrix
1633  , bool SF // Symmetry flag
1634  , typename... CRAs > // Compile time row arguments
1635 inline Rows<MT,true,true,SF,CRAs...>&
1637 {
1640 
1641  if( rows() != columns() ) {
1642  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1643  }
1644 
1645  const ResultType tmp( trans( *this ) );
1646 
1647  if( IsRestricted_v<MT> ) {
1648  for( size_t i=0UL; i<rows(); ++i ) {
1649  if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
1650  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1651  }
1652  }
1653  }
1654 
1655  decltype(auto) left( derestrict( *this ) );
1656 
1657  smpAssign( left, tmp );
1658 
1659  return *this;
1660 }
1662 //*************************************************************************************************
1663 
1664 
1665 //*************************************************************************************************
1678 template< typename MT // Type of the dense matrix
1679  , bool SF // Symmetry flag
1680  , typename... CRAs > // Compile time row arguments
1681 inline Rows<MT,true,true,SF,CRAs...>&
1682  Rows<MT,true,true,SF,CRAs...>::ctranspose()
1683 {
1686 
1687  if( rows() != columns() ) {
1688  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1689  }
1690 
1691  const ResultType tmp( ctrans( *this ) );
1692 
1693  if( IsRestricted_v<MT> ) {
1694  for( size_t i=0UL; i<rows(); ++i ) {
1695  if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
1696  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1697  }
1698  }
1699  }
1700 
1701  decltype(auto) left( derestrict( *this ) );
1702 
1703  smpAssign( left, tmp );
1704 
1705  return *this;
1706 }
1708 //*************************************************************************************************
1709 
1710 
1711 //*************************************************************************************************
1724 template< typename MT // Type of the dense matrix
1725  , bool SF // Symmetry flag
1726  , typename... CRAs > // Compile time row arguments
1727 template< typename Other > // Data type of the scalar value
1728 inline Rows<MT,true,true,SF,CRAs...>&
1729  Rows<MT,true,true,SF,CRAs...>::scale( const Other& scalar )
1730 {
1734 
1735  for( size_t i=0UL; i<rows(); ++i )
1736  {
1737  const size_t index ( idx(i) );
1738  const size_t jbegin( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index+1UL : index ) : 0UL );
1739  const size_t jend ( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index : index+1UL ) : columns() );
1740 
1741  for( size_t j=jbegin; j<jend; ++j ) {
1742  matrix_(index,j) *= scalar;
1743  }
1744  }
1745 
1746  return *this;
1747 }
1749 //*************************************************************************************************
1750 
1751 
1752 
1753 
1754 //=================================================================================================
1755 //
1756 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1757 //
1758 //=================================================================================================
1759 
1760 //*************************************************************************************************
1771 template< typename MT // Type of the dense matrix
1772  , bool SF // Symmetry flag
1773  , typename... CRAs > // Compile time row arguments
1774 template< typename Other > // Data type of the foreign expression
1775 inline bool Rows<MT,true,true,SF,CRAs...>::canAlias( const Other* alias ) const noexcept
1776 {
1777  return matrix_.isAliased( alias );
1778 }
1780 //*************************************************************************************************
1781 
1782 
1783 //*************************************************************************************************
1795 template< typename MT // Type of the dense matrix
1796  , bool SF // Symmetry flag
1797  , typename... CRAs > // Compile time row arguments
1798 template< typename MT2 // Data type of the foreign dense row selection
1799  , bool SO2 // Storage order of the foreign dense row selection
1800  , bool SF2 // Symmetry flag of the foreign dense row selection
1801  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
1802 inline bool
1803  Rows<MT,true,true,SF,CRAs...>::canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
1804 {
1805  return matrix_.isAliased( &alias->matrix_ );
1806 }
1808 //*************************************************************************************************
1809 
1810 
1811 //*************************************************************************************************
1822 template< typename MT // Type of the dense matrix
1823  , bool SF // Symmetry flag
1824  , typename... CRAs > // Compile time row arguments
1825 template< typename Other > // Data type of the foreign expression
1826 inline bool Rows<MT,true,true,SF,CRAs...>::isAliased( const Other* alias ) const noexcept
1827 {
1828  return matrix_.isAliased( alias );
1829 }
1831 //*************************************************************************************************
1832 
1833 
1834 //*************************************************************************************************
1846 template< typename MT // Type of the dense matrix
1847  , bool SF // Symmetry flag
1848  , typename... CRAs > // Compile time row arguments
1849 template< typename MT2 // Data type of the foreign dense row selection
1850  , bool SO2 // Storage order of the foreign dense row selection
1851  , bool SF2 // Symmetry flag of the foreign dense row selection
1852  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
1853 inline bool
1854  Rows<MT,true,true,SF,CRAs...>::isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
1855 {
1856  return matrix_.isAliased( &alias->matrix_ );
1857 }
1859 //*************************************************************************************************
1860 
1861 
1862 //*************************************************************************************************
1872 template< typename MT // Type of the dense matrix
1873  , bool SF // Symmetry flag
1874  , typename... CRAs > // Compile time row arguments
1875 inline bool Rows<MT,true,true,SF,CRAs...>::isAligned() const noexcept
1876 {
1877  return matrix_.isAligned();
1878 }
1880 //*************************************************************************************************
1881 
1882 
1883 //*************************************************************************************************
1894 template< typename MT // Type of the dense matrix
1895  , bool SF // Symmetry flag
1896  , typename... CRAs > // Compile time row arguments
1897 inline bool Rows<MT,true,true,SF,CRAs...>::canSMPAssign() const noexcept
1898 {
1899  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
1900 }
1902 //*************************************************************************************************
1903 
1904 
1905 //*************************************************************************************************
1920 template< typename MT // Type of the dense matrix
1921  , bool SF // Symmetry flag
1922  , typename... CRAs > // Compile time row arguments
1923 BLAZE_ALWAYS_INLINE typename Rows<MT,true,true,SF,CRAs...>::SIMDType
1924  Rows<MT,true,true,SF,CRAs...>::load( size_t i, size_t j ) const noexcept
1925 {
1926  return matrix_.load( idx(i), j );
1927 }
1929 //*************************************************************************************************
1930 
1931 
1932 //*************************************************************************************************
1947 template< typename MT // Type of the dense matrix
1948  , bool SF // Symmetry flag
1949  , typename... CRAs > // Compile time row arguments
1950 BLAZE_ALWAYS_INLINE typename Rows<MT,true,true,SF,CRAs...>::SIMDType
1951  Rows<MT,true,true,SF,CRAs...>::loada( size_t i, size_t j ) const noexcept
1952 {
1953  return matrix_.loada( idx(i), j );
1954 }
1956 //*************************************************************************************************
1957 
1958 
1959 //*************************************************************************************************
1974 template< typename MT // Type of the dense matrix
1975  , bool SF // Symmetry flag
1976  , typename... CRAs > // Compile time row arguments
1977 BLAZE_ALWAYS_INLINE typename Rows<MT,true,true,SF,CRAs...>::SIMDType
1978  Rows<MT,true,true,SF,CRAs...>::loadu( size_t i, size_t j ) const noexcept
1979 {
1980  return matrix_.loadu( idx(i), j );
1981 }
1983 //*************************************************************************************************
1984 
1985 
1986 //*************************************************************************************************
2002 template< typename MT // Type of the dense matrix
2003  , bool SF // Symmetry flag
2004  , typename... CRAs > // Compile time row arguments
2006  Rows<MT,true,true,SF,CRAs...>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2007 {
2008  matrix_.store( idx(i), j, value );
2009 }
2011 //*************************************************************************************************
2012 
2013 
2014 //*************************************************************************************************
2030 template< typename MT // Type of the dense matrix
2031  , bool SF // Symmetry flag
2032  , typename... CRAs > // Compile time row arguments
2034  Rows<MT,true,true,SF,CRAs...>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2035 {
2036  matrix_.storea( idx(i), j, value );
2037 }
2039 //*************************************************************************************************
2040 
2041 
2042 //*************************************************************************************************
2058 template< typename MT // Type of the dense matrix
2059  , bool SF // Symmetry flag
2060  , typename... CRAs > // Compile time row arguments
2062  Rows<MT,true,true,SF,CRAs...>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2063 {
2064  matrix_.storeu( idx(i), j, value );
2065 }
2067 //*************************************************************************************************
2068 
2069 
2070 //*************************************************************************************************
2086 template< typename MT // Type of the dense matrix
2087  , bool SF // Symmetry flag
2088  , typename... CRAs > // Compile time row arguments
2090  Rows<MT,true,true,SF,CRAs...>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2091 {
2092  matrix_.stream( idx(i), j, value );
2093 }
2095 //*************************************************************************************************
2096 
2097 
2098 //*************************************************************************************************
2110 template< typename MT // Type of the dense matrix
2111  , bool SF // Symmetry flag
2112  , typename... CRAs > // Compile time row arguments
2113 template< typename MT2 > // Type of the right-hand side dense matrix
2114 inline auto Rows<MT,true,true,SF,CRAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2115  -> DisableIf_t< VectorizedAssign_v<MT2> >
2116 {
2119 
2120  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2121  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2122 
2123  const size_t jpos( columns() & size_t(-2) );
2124  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
2125 
2126  for( size_t i=0UL; i<rows(); ++i ) {
2127  const size_t index( idx(i) );
2128  for( size_t j=0UL; j<jpos; j+=2UL ) {
2129  matrix_(index,j ) = (~rhs)(i,j );
2130  matrix_(index,j+1UL) = (~rhs)(i,j+1UL);
2131  }
2132  if( jpos < columns() ) {
2133  matrix_(index,jpos) = (~rhs)(i,jpos);
2134  }
2135  }
2136 }
2138 //*************************************************************************************************
2139 
2140 
2141 //*************************************************************************************************
2153 template< typename MT // Type of the dense matrix
2154  , bool SF // Symmetry flag
2155  , typename... CRAs > // Compile time row arguments
2156 template< typename MT2 > // Type of the right-hand side dense matrix
2157 inline auto Rows<MT,true,true,SF,CRAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2158  -> EnableIf_t< VectorizedAssign_v<MT2> >
2159 {
2162 
2164 
2165  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2166  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2167 
2168  const size_t jpos( columns() & size_t(-SIMDSIZE) );
2169  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2170 
2171  if( useStreaming &&
2172  rows()*columns() > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2173  !(~rhs).isAliased( &matrix_ ) )
2174  {
2175  for( size_t i=0UL; i<rows(); ++i )
2176  {
2177  size_t j( 0UL );
2178  Iterator left( begin(i) );
2179  ConstIterator_t<MT2> right( (~rhs).begin(i) );
2180 
2181  for( ; j<jpos; j+=SIMDSIZE ) {
2182  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2183  }
2184  for( ; j<columns(); ++j ) {
2185  *left = *right;
2186  }
2187  }
2188  }
2189  else
2190  {
2191  for( size_t i=0UL; i<rows(); ++i )
2192  {
2193  size_t j( 0UL );
2194  Iterator left( begin(i) );
2195  ConstIterator_t<MT2> right( (~rhs).begin(i) );
2196 
2197  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2198  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2199  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2200  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2201  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2202  }
2203  for( ; j<jpos; j+=SIMDSIZE ) {
2204  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2205  }
2206  for( ; j<columns(); ++j ) {
2207  *left = *right; ++left; ++right;
2208  }
2209  }
2210  }
2211 }
2213 //*************************************************************************************************
2214 
2215 
2216 //*************************************************************************************************
2228 template< typename MT // Type of the dense matrix
2229  , bool SF // Symmetry flag
2230  , typename... CRAs > // Compile time row arguments
2231 template< typename MT2 > // Type of the right-hand side dense matrix
2232 inline void Rows<MT,true,true,SF,CRAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2233 {
2236 
2238 
2239  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2240  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2241 
2242  constexpr size_t block( BLOCK_SIZE );
2243 
2244  if( rows() < block && columns() < block )
2245  {
2246  const size_t jpos( (~rhs).columns() & size_t(-2) );
2247  for( size_t i=0UL; i<rows(); ++i ) {
2248  const size_t index( idx(i) );
2249  for( size_t j=0UL; j<jpos; j+=2UL ) {
2250  matrix_(index,j ) = (~rhs)(i,j );
2251  matrix_(index,j+1UL) = (~rhs)(i,j+1UL);
2252  }
2253  if( jpos < (~rhs).columns() ) {
2254  matrix_(index,jpos) = (~rhs)(i,jpos);
2255  }
2256  }
2257  }
2258  else
2259  {
2260  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2261  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2262  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2263  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2264  for( size_t i=ii; i<iend; ++i ) {
2265  const size_t index( idx(i) );
2266  for( size_t j=jj; j<jend; ++j ) {
2267  matrix_(index,j) = (~rhs)(i,j);
2268  }
2269  }
2270  }
2271  }
2272  }
2273 }
2275 //*************************************************************************************************
2276 
2277 
2278 //*************************************************************************************************
2290 template< typename MT // Type of the dense matrix
2291  , bool SF // Symmetry flag
2292  , typename... CRAs > // Compile time row arguments
2293 template< typename MT2 > // Type of the right-hand side sparse matrix
2294 inline void Rows<MT,true,true,SF,CRAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2295 {
2298 
2299  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2300  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2301 
2302  for( size_t i=0UL; i<rows(); ++i ) {
2303  const size_t index( idx(i) );
2304  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2305  matrix_(index,element->index()) = element->value();
2306  }
2307 }
2309 //*************************************************************************************************
2310 
2311 
2312 //*************************************************************************************************
2324 template< typename MT // Type of the dense matrix
2325  , bool SF // Symmetry flag
2326  , typename... CRAs > // Compile time row arguments
2327 template< typename MT2 > // Type of the right-hand side sparse matrix
2328 inline void Rows<MT,true,true,SF,CRAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2329 {
2332 
2334 
2335  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2336  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2337 
2338  for( size_t j=0UL; j<columns(); ++j ) {
2339  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2340  matrix_(idx(element->index()),j) = element->value();
2341  }
2342 }
2344 //*************************************************************************************************
2345 
2346 
2347 //*************************************************************************************************
2359 template< typename MT // Type of the dense matrix
2360  , bool SF // Symmetry flag
2361  , typename... CRAs > // Compile time row arguments
2362 template< typename MT2 > // Type of the right-hand side dense matrix
2363 inline auto Rows<MT,true,true,SF,CRAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2364  -> DisableIf_t< VectorizedAddAssign_v<MT2> >
2365 {
2368 
2369  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2370  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2371 
2372  const size_t jpos( columns() & size_t(-2) );
2373  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
2374 
2375  for( size_t i=0UL; i<rows(); ++i )
2376  {
2377  const size_t index( idx(i) );
2378  if( IsDiagonal_v<MT2> ) {
2379  matrix_(index,i) += (~rhs)(i,i);
2380  }
2381  else {
2382  for( size_t j=0UL; j<jpos; j+=2UL ) {
2383  matrix_(index,j ) += (~rhs)(i,j );
2384  matrix_(index,j+1UL) += (~rhs)(i,j+1UL);
2385  }
2386  if( jpos < columns() ) {
2387  matrix_(index,jpos) += (~rhs)(i,jpos);
2388  }
2389  }
2390  }
2391 }
2393 //*************************************************************************************************
2394 
2395 
2396 //*************************************************************************************************
2408 template< typename MT // Type of the dense matrix
2409  , bool SF // Symmetry flag
2410  , typename... CRAs > // Compile time row arguments
2411 template< typename MT2 > // Type of the right-hand side dense matrix
2412 inline auto Rows<MT,true,true,SF,CRAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2413  -> EnableIf_t< VectorizedAddAssign_v<MT2> >
2414 {
2417 
2419 
2420  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2421  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2422 
2423  for( size_t i=0UL; i<rows(); ++i )
2424  {
2425  const size_t jbegin( ( IsUpper_v<MT2> )
2426  ?( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2427  :( 0UL ) );
2428  const size_t jend ( ( IsLower_v<MT2> )
2429  ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
2430  :( columns() ) );
2431  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2432 
2433  const size_t jpos( jend & size_t(-SIMDSIZE) );
2434  BLAZE_INTERNAL_ASSERT( ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2435 
2436  size_t j( jbegin );
2437  Iterator left( begin(i) + jbegin );
2438  ConstIterator_t<MT2> right( (~rhs).begin(i) + jbegin );
2439 
2440  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2441  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2442  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2443  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2444  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2445  }
2446  for( ; j<jpos; j+=SIMDSIZE ) {
2447  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2448  }
2449  for( ; j<jend; ++j ) {
2450  *left += *right; ++left; ++right;
2451  }
2452  }
2453 }
2455 //*************************************************************************************************
2456 
2457 
2458 //*************************************************************************************************
2470 template< typename MT // Type of the dense matrix
2471  , bool SF // Symmetry flag
2472  , typename... CRAs > // Compile time row arguments
2473 template< typename MT2 > // Type of the right-hand side dense matrix
2474 inline void Rows<MT,true,true,SF,CRAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2475 {
2478 
2480 
2481  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2482  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2483 
2484  constexpr size_t block( BLOCK_SIZE );
2485 
2486  if( rows() < block && columns() < block )
2487  {
2488  const size_t jpos( (~rhs).columns() & size_t(-2) );
2489  for( size_t i=0UL; i<rows(); ++i ) {
2490  const size_t index( idx(i) );
2491  for( size_t j=0UL; j<jpos; j+=2UL ) {
2492  matrix_(index,j ) += (~rhs)(i,j );
2493  matrix_(index,j+1UL) += (~rhs)(i,j+1UL);
2494  }
2495  if( jpos < (~rhs).columns() ) {
2496  matrix_(index,jpos) += (~rhs)(i,jpos);
2497  }
2498  }
2499  }
2500  else
2501  {
2502  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2503  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2504  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2505  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2506  for( size_t i=ii; i<iend; ++i ) {
2507  const size_t index( idx(i) );
2508  for( size_t j=jj; j<jend; ++j ) {
2509  matrix_(index,j) += (~rhs)(i,j);
2510  }
2511  }
2512  }
2513  }
2514  }
2515 }
2517 //*************************************************************************************************
2518 
2519 
2520 //*************************************************************************************************
2532 template< typename MT // Type of the dense matrix
2533  , bool SF // Symmetry flag
2534  , typename... CRAs > // Compile time row arguments
2535 template< typename MT2 > // Type of the right-hand side sparse matrix
2536 inline void Rows<MT,true,true,SF,CRAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
2537 {
2540 
2541  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2542  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2543 
2544  for( size_t i=0UL; i<rows(); ++i ) {
2545  const size_t index( idx(i) );
2546  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2547  matrix_(index,element->index()) += element->value();
2548  }
2549 }
2551 //*************************************************************************************************
2552 
2553 
2554 //*************************************************************************************************
2566 template< typename MT // Type of the dense matrix
2567  , bool SF // Symmetry flag
2568  , typename... CRAs > // Compile time row arguments
2569 template< typename MT2 > // Type of the right-hand side sparse matrix
2570 inline void Rows<MT,true,true,SF,CRAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
2571 {
2574 
2576 
2577  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2578  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2579 
2580  for( size_t j=0UL; j<columns(); ++j ) {
2581  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2582  matrix_(idx(element->index()),j) += element->value();
2583  }
2584 }
2586 //*************************************************************************************************
2587 
2588 
2589 //*************************************************************************************************
2601 template< typename MT // Type of the dense matrix
2602  , bool SF // Symmetry flag
2603  , typename... CRAs > // Compile time row arguments
2604 template< typename MT2 > // Type of the right-hand side dense matrix
2605 inline auto Rows<MT,true,true,SF,CRAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2606  -> DisableIf_t< VectorizedSubAssign_v<MT2> >
2607 {
2610 
2611  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2612  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2613 
2614  const size_t jpos( columns() & size_t(-2) );
2615  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
2616 
2617  for( size_t i=0UL; i<rows(); ++i )
2618  {
2619  const size_t index( idx(i) );
2620 
2621  if( IsDiagonal_v<MT2> ) {
2622  matrix_(index,i) -= (~rhs)(i,i);
2623  }
2624  else {
2625  for( size_t j=0UL; j<jpos; j+=2UL ) {
2626  matrix_(index,j ) -= (~rhs)(i,j );
2627  matrix_(index,j+1UL) -= (~rhs)(i,j+1UL);
2628  }
2629  if( jpos < columns() ) {
2630  matrix_(index,jpos) -= (~rhs)(i,jpos);
2631  }
2632  }
2633  }
2634 }
2636 //*************************************************************************************************
2637 
2638 
2639 //*************************************************************************************************
2651 template< typename MT // Type of the dense matrix
2652  , bool SF // Symmetry flag
2653  , typename... CRAs > // Compile time row arguments
2654 template< typename MT2 > // Type of the right-hand side dense matrix
2655 inline auto Rows<MT,true,true,SF,CRAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2656  -> EnableIf_t< VectorizedSubAssign_v<MT2> >
2657 {
2660 
2662 
2663  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2664  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2665 
2666  for( size_t i=0UL; i<rows(); ++i )
2667  {
2668  const size_t jbegin( ( IsUpper_v<MT2> )
2669  ?( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2670  :( 0UL ) );
2671  const size_t jend ( ( IsLower_v<MT2> )
2672  ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
2673  :( columns() ) );
2674  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2675 
2676  const size_t jpos( jend & size_t(-SIMDSIZE) );
2677  BLAZE_INTERNAL_ASSERT( ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2678 
2679  size_t j( jbegin );
2680  Iterator left( begin(i) + jbegin );
2681  ConstIterator_t<MT2> right( (~rhs).begin(i) + jbegin );
2682 
2683  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2684  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2685  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2686  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2687  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2688  }
2689  for( ; j<jpos; j+=SIMDSIZE ) {
2690  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2691  }
2692  for( ; j<jend; ++j ) {
2693  *left -= *right; ++left; ++right;
2694  }
2695  }
2696 }
2698 //*************************************************************************************************
2699 
2700 
2701 //*************************************************************************************************
2713 template< typename MT // Type of the dense matrix
2714  , bool SF // Symmetry flag
2715  , typename... CRAs > // Compile time row arguments
2716 template< typename MT2 > // Type of the right-hand side dense matrix
2717 inline void Rows<MT,true,true,SF,CRAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2718 {
2721 
2723 
2724  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2725  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2726 
2727  constexpr size_t block( BLOCK_SIZE );
2728 
2729  if( rows() < block && columns() < block )
2730  {
2731  const size_t jpos( (~rhs).columns() & size_t(-2) );
2732  for( size_t i=0UL; i<rows(); ++i ) {
2733  const size_t index( idx(i) );
2734  for( size_t j=0UL; j<jpos; j+=2UL ) {
2735  matrix_(index,j ) -= (~rhs)(i,j );
2736  matrix_(index,j+1UL) -= (~rhs)(i,j+1UL);
2737  }
2738  if( jpos < (~rhs).columns() ) {
2739  matrix_(index,jpos) -= (~rhs)(i,jpos);
2740  }
2741  }
2742  }
2743  else
2744  {
2745  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2746  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2747  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2748  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2749  for( size_t i=ii; i<iend; ++i ) {
2750  const size_t index( idx(i) );
2751  for( size_t j=jj; j<jend; ++j ) {
2752  matrix_(index,j) -= (~rhs)(i,j);
2753  }
2754  }
2755  }
2756  }
2757  }
2758 }
2760 //*************************************************************************************************
2761 
2762 
2763 //*************************************************************************************************
2775 template< typename MT // Type of the dense matrix
2776  , bool SF // Symmetry flag
2777  , typename... CRAs > // Compile time row arguments
2778 template< typename MT2 > // Type of the right-hand side sparse matrix
2779 inline void Rows<MT,true,true,SF,CRAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
2780 {
2783 
2784  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2785  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2786 
2787  for( size_t i=0UL; i<rows(); ++i ) {
2788  const size_t index( idx(i) );
2789  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2790  matrix_(index,element->index()) -= element->value();
2791  }
2792 }
2794 //*************************************************************************************************
2795 
2796 
2797 //*************************************************************************************************
2809 template< typename MT // Type of the dense matrix
2810  , bool SF // Symmetry flag
2811  , typename... CRAs > // Compile time row arguments
2812 template< typename MT2 > // Type of the right-hand side sparse matrix
2813 inline void Rows<MT,true,true,SF,CRAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
2814 {
2817 
2819 
2820  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2821  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2822 
2823  for( size_t j=0UL; j<columns(); ++j ) {
2824  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2825  matrix_(idx(element->index()),j) -= element->value();
2826  }
2827 }
2829 //*************************************************************************************************
2830 
2831 
2832 //*************************************************************************************************
2844 template< typename MT // Type of the dense matrix
2845  , bool SF // Symmetry flag
2846  , typename... CRAs > // Compile time row arguments
2847 template< typename MT2 > // Type of the right-hand side dense matrix
2848 inline auto Rows<MT,true,true,SF,CRAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2849  -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
2850 {
2853 
2854  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2855  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2856 
2857  const size_t jpos( columns() & size_t(-2) );
2858  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
2859 
2860  for( size_t i=0UL; i<rows(); ++i ) {
2861  const size_t index( idx(i) );
2862  for( size_t j=0UL; j<jpos; j+=2UL ) {
2863  matrix_(index,j ) *= (~rhs)(i,j );
2864  matrix_(index,j+1UL) *= (~rhs)(i,j+1UL);
2865  }
2866  if( jpos < columns() ) {
2867  matrix_(index,jpos) *= (~rhs)(i,jpos);
2868  }
2869  }
2870 }
2872 //*************************************************************************************************
2873 
2874 
2875 //*************************************************************************************************
2887 template< typename MT // Type of the dense matrix
2888  , bool SF // Symmetry flag
2889  , typename... CRAs > // Compile time row arguments
2890 template< typename MT2 > // Type of the right-hand side dense matrix
2891 inline auto Rows<MT,true,true,SF,CRAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2892  -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
2893 {
2896 
2898 
2899  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2900  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2901 
2902  for( size_t i=0UL; i<rows(); ++i )
2903  {
2904  const size_t jpos( columns() & size_t(-SIMDSIZE) );
2905  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2906 
2907  size_t j( 0UL );
2908  Iterator left( begin(i) );
2909  ConstIterator_t<MT2> right( (~rhs).begin(i) );
2910 
2911  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2912  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2913  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2914  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2915  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2916  }
2917  for( ; j<jpos; j+=SIMDSIZE ) {
2918  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2919  }
2920  for( ; j<columns(); ++j ) {
2921  *left *= *right; ++left; ++right;
2922  }
2923  }
2924 }
2926 //*************************************************************************************************
2927 
2928 
2929 //*************************************************************************************************
2941 template< typename MT // Type of the dense matrix
2942  , bool SF // Symmetry flag
2943  , typename... CRAs > // Compile time row arguments
2944 template< typename MT2 > // Type of the right-hand side dense matrix
2945 inline void Rows<MT,true,true,SF,CRAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2946 {
2949 
2951 
2952  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2953  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2954 
2955  constexpr size_t block( BLOCK_SIZE );
2956 
2957  if( rows() < block && columns() < block )
2958  {
2959  const size_t jpos( (~rhs).columns() & size_t(-2) );
2960  for( size_t i=0UL; i<rows(); ++i ) {
2961  const size_t index( idx(i) );
2962  for( size_t j=0UL; j<jpos; j+=2UL ) {
2963  matrix_(index,j ) *= (~rhs)(i,j );
2964  matrix_(index,j+1UL) *= (~rhs)(i,j+1UL);
2965  }
2966  if( jpos < (~rhs).columns() ) {
2967  matrix_(index,jpos) *= (~rhs)(i,jpos);
2968  }
2969  }
2970  }
2971  else
2972  {
2973  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2974  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2975  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2976  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2977  for( size_t i=ii; i<iend; ++i ) {
2978  const size_t index( idx(i) );
2979  for( size_t j=jj; j<jend; ++j ) {
2980  matrix_(index,j) *= (~rhs)(i,j);
2981  }
2982  }
2983  }
2984  }
2985  }
2986 }
2988 //*************************************************************************************************
2989 
2990 
2991 //*************************************************************************************************
3003 template< typename MT // Type of the dense matrix
3004  , bool SF // Symmetry flag
3005  , typename... CRAs > // Compile time row arguments
3006 template< typename MT2 > // Type of the right-hand side sparse matrix
3007 inline void Rows<MT,true,true,SF,CRAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
3008 {
3011 
3012  using blaze::reset;
3013 
3014  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3015  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3016 
3017  for( size_t i=0UL; i<rows(); ++i )
3018  {
3019  const size_t index( idx(i) );
3020  size_t j( 0UL );
3021 
3022  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
3023  for( ; j<element->index(); ++j )
3024  reset( matrix_(index,j) );
3025  matrix_(index,j) *= element->value();
3026  ++j;
3027  }
3028 
3029  for( ; j<columns(); ++j ) {
3030  reset( matrix_(index,j) );
3031  }
3032  }
3033 }
3035 //*************************************************************************************************
3036 
3037 
3038 //*************************************************************************************************
3050 template< typename MT // Type of the dense matrix
3051  , bool SF // Symmetry flag
3052  , typename... CRAs > // Compile time row arguments
3053 template< typename MT2 > // Type of the right-hand side sparse matrix
3054 inline void Rows<MT,true,true,SF,CRAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
3055 {
3058 
3059  using blaze::reset;
3060 
3062 
3063  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3064  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3065 
3066  for( size_t j=0UL; j<columns(); ++j )
3067  {
3068  size_t i( 0UL );
3069 
3070  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
3071  for( ; i<element->index(); ++i )
3072  reset( matrix_(idx(i),j) );
3073  matrix_(idx(i),j) *= element->value();
3074  ++i;
3075  }
3076 
3077  for( ; i<rows(); ++i ) {
3078  reset( matrix_(idx(i),j) );
3079  }
3080  }
3081 }
3083 //*************************************************************************************************
3084 
3085 
3086 
3087 
3088 
3089 
3090 
3091 
3092 //=================================================================================================
3093 //
3094 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR DENSE MATRICES
3095 //
3096 //=================================================================================================
3097 
3098 //*************************************************************************************************
3106 template< typename MT // Type of the dense matrix
3107  , typename... CRAs > // Compile time row arguments
3108 class Rows<MT,false,true,false,CRAs...>
3109  : public View< DenseMatrix< Rows<MT,false,true,false,CRAs...>, false > >
3110  , private RowsData<CRAs...>
3111 {
3112  private:
3113  //**Type definitions****************************************************************************
3114  using DataType = RowsData<CRAs...>;
3115  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
3116  //**********************************************************************************************
3117 
3118  //**Compile time flags**************************************************************************
3119  using DataType::N;
3120  //**********************************************************************************************
3121 
3122  //**********************************************************************************************
3124  template< typename MT1, typename MT2 >
3125  static constexpr bool EnforceEvaluation_v =
3126  ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
3127  //**********************************************************************************************
3128 
3129  public:
3130  //**Type definitions****************************************************************************
3132  using This = Rows<MT,false,true,false,CRAs...>;
3133 
3134  using BaseType = DenseMatrix<This,false>;
3135  using ViewedType = MT;
3136  using ResultType = RowsTrait_t<MT,N>;
3137  using OppositeType = OppositeType_t<ResultType>;
3138  using TransposeType = TransposeType_t<ResultType>;
3139  using ElementType = ElementType_t<MT>;
3140  using ReturnType = ReturnType_t<MT>;
3141  using CompositeType = const Rows&;
3142 
3144  using ConstReference = ConstReference_t<MT>;
3145 
3147  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
3148 
3150  using ConstPointer = ConstPointer_t<MT>;
3151 
3153  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
3154  //**********************************************************************************************
3155 
3156  //**RowsIterator class definition***************************************************************
3159  template< typename MatrixType // Type of the dense matrix
3160  , typename IteratorType > // Type of the dense matrix iterator
3161  class RowsIterator
3162  {
3163  public:
3164  //**Type definitions*************************************************************************
3166  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
3167 
3169  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
3170 
3172  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
3173 
3175  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
3176 
3178  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
3179 
3180  // STL iterator requirements
3181  using iterator_category = IteratorCategory;
3182  using value_type = ValueType;
3183  using pointer = PointerType;
3184  using reference = ReferenceType;
3185  using difference_type = DifferenceType;
3186  //*******************************************************************************************
3187 
3188  //**Constructor******************************************************************************
3191  inline RowsIterator() noexcept
3192  : matrix_( nullptr ) // The dense matrix containing the row
3193  , row_ ( 0UL ) // The current row index
3194  , column_( 0UL ) // The current column index
3195  , pos_ ( ) // Iterator to the current dense element
3196  {}
3197  //*******************************************************************************************
3198 
3199  //**Constructor******************************************************************************
3206  inline RowsIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
3207  : matrix_( &matrix ) // The dense matrix containing the selected row
3208  , row_ ( row ) // The current row index
3209  , column_( column ) // The current column index
3210  , pos_ ( ) // Iterator to the current dense element
3211  {
3212  if( column_ != matrix_->columns() )
3213  pos_ = matrix_->begin( column_ ) + row_;
3214  }
3215  //*******************************************************************************************
3216 
3217  //**Constructor******************************************************************************
3222  template< typename MatrixType2, typename IteratorType2 >
3223  inline RowsIterator( const RowsIterator<MatrixType2,IteratorType2>& it ) noexcept
3224  : matrix_( it.matrix_ ) // The dense matrix containing the seleted row
3225  , row_ ( it.row_ ) // The current row index
3226  , column_( it.column_ ) // The current column index
3227  , pos_ ( it.pos_ ) // Iterator to the current dense element
3228  {}
3229  //*******************************************************************************************
3230 
3231  //**Addition assignment operator*************************************************************
3237  inline RowsIterator& operator+=( size_t inc ) noexcept {
3238  using blaze::reset;
3239  column_ += inc;
3240  if( column_ != matrix_->columns() )
3241  pos_ = matrix_->begin( column_ ) + row_;
3242  else reset( pos_ );
3243  return *this;
3244  }
3245  //*******************************************************************************************
3246 
3247  //**Subtraction assignment operator**********************************************************
3253  inline RowsIterator& operator-=( size_t dec ) noexcept {
3254  using blaze::reset;
3255  column_ -= dec;
3256  if( column_ != matrix_->columns() )
3257  pos_ = matrix_->begin( column_ ) + row_;
3258  else reset( pos_ );
3259  return *this;
3260  }
3261  //*******************************************************************************************
3262 
3263  //**Prefix increment operator****************************************************************
3268  inline RowsIterator& operator++() noexcept {
3269  using blaze::reset;
3270  ++column_;
3271  if( column_ != matrix_->columns() )
3272  pos_ = matrix_->begin( column_ ) + row_;
3273  else reset( pos_ );
3274  return *this;
3275  }
3276  //*******************************************************************************************
3277 
3278  //**Postfix increment operator***************************************************************
3283  inline const RowsIterator operator++( int ) noexcept {
3284  const RowsIterator tmp( *this );
3285  ++(*this);
3286  return tmp;
3287  }
3288  //*******************************************************************************************
3289 
3290  //**Prefix decrement operator****************************************************************
3295  inline RowsIterator& operator--() noexcept {
3296  using blaze::reset;
3297  --column_;
3298  if( column_ != matrix_->columns() )
3299  pos_ = matrix_->begin( column_ ) + row_;
3300  else reset( pos_ );
3301  return *this;
3302  }
3303  //*******************************************************************************************
3304 
3305  //**Postfix decrement operator***************************************************************
3310  inline const RowsIterator operator--( int ) noexcept {
3311  const RowsIterator tmp( *this );
3312  --(*this);
3313  return tmp;
3314  }
3315  //*******************************************************************************************
3316 
3317  //**Subscript operator***********************************************************************
3323  inline ReferenceType operator[]( size_t index ) const {
3324  BLAZE_USER_ASSERT( column_+index < matrix_->columns(), "Invalid access index detected" );
3325  const IteratorType pos( matrix_->begin( column_+index ) + row_ );
3326  return *pos;
3327  }
3328  //*******************************************************************************************
3329 
3330  //**Element access operator******************************************************************
3335  inline ReferenceType operator*() const {
3336  return *pos_;
3337  }
3338  //*******************************************************************************************
3339 
3340  //**Element access operator******************************************************************
3345  inline PointerType operator->() const {
3346  return pos_;
3347  }
3348  //*******************************************************************************************
3349 
3350  //**Equality operator************************************************************************
3356  template< typename MatrixType2, typename IteratorType2 >
3357  inline bool operator==( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3358  return column_ == rhs.column_;
3359  }
3360  //*******************************************************************************************
3361 
3362  //**Inequality operator**********************************************************************
3368  template< typename MatrixType2, typename IteratorType2 >
3369  inline bool operator!=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3370  return !( *this == rhs );
3371  }
3372  //*******************************************************************************************
3373 
3374  //**Less-than operator***********************************************************************
3380  template< typename MatrixType2, typename IteratorType2 >
3381  inline bool operator<( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3382  return column_ < rhs.column_;
3383  }
3384  //*******************************************************************************************
3385 
3386  //**Greater-than operator********************************************************************
3392  template< typename MatrixType2, typename IteratorType2 >
3393  inline bool operator>( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3394  return column_ > rhs.column_;
3395  }
3396  //*******************************************************************************************
3397 
3398  //**Less-or-equal-than operator**************************************************************
3404  template< typename MatrixType2, typename IteratorType2 >
3405  inline bool operator<=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3406  return column_ <= rhs.column_;
3407  }
3408  //*******************************************************************************************
3409 
3410  //**Greater-or-equal-than operator***********************************************************
3416  template< typename MatrixType2, typename IteratorType2 >
3417  inline bool operator>=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3418  return column_ >= rhs.column_;
3419  }
3420  //*******************************************************************************************
3421 
3422  //**Subtraction operator*********************************************************************
3428  inline DifferenceType operator-( const RowsIterator& rhs ) const noexcept {
3429  return column_ - rhs.column_;
3430  }
3431  //*******************************************************************************************
3432 
3433  //**Addition operator************************************************************************
3440  friend inline const RowsIterator operator+( const RowsIterator& it, size_t inc ) noexcept {
3441  return RowsIterator( *it.matrix_, it.row_, it.column_+inc );
3442  }
3443  //*******************************************************************************************
3444 
3445  //**Addition operator************************************************************************
3452  friend inline const RowsIterator operator+( size_t inc, const RowsIterator& it ) noexcept {
3453  return RowsIterator( *it.matrix_, it.row_, it.column_+inc );
3454  }
3455  //*******************************************************************************************
3456 
3457  //**Subtraction operator*********************************************************************
3464  friend inline const RowsIterator operator-( const RowsIterator& it, size_t dec ) noexcept {
3465  return RowsIterator( *it.matrix_, it.row_, it.column_-dec );
3466  }
3467  //*******************************************************************************************
3468 
3469  private:
3470  //**Member variables*************************************************************************
3471  MatrixType* matrix_;
3472  size_t row_;
3473  size_t column_;
3474  IteratorType pos_;
3475  //*******************************************************************************************
3476 
3477  //**Friend declarations**********************************************************************
3478  template< typename MatrixType2, typename IteratorType2 > friend class RowsIterator;
3479  //*******************************************************************************************
3480  };
3481  //**********************************************************************************************
3482 
3483  //**Type definitions****************************************************************************
3485  using ConstIterator = RowsIterator< const MT, ConstIterator_t<MT> >;
3486 
3488  using Iterator = If_t< IsConst_v<MT>, ConstIterator, RowsIterator< MT, Iterator_t<MT> > >;
3489  //**********************************************************************************************
3490 
3491  //**Compilation flags***************************************************************************
3493  static constexpr bool simdEnabled = false;
3494 
3496  static constexpr bool smpAssignable = MT::smpAssignable;
3497 
3499  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
3500  //**********************************************************************************************
3501 
3502  //**Constructors********************************************************************************
3505  template< typename... RRAs >
3506  explicit inline Rows( MT& matrix, RRAs... args );
3507 
3508  Rows( const Rows& ) = default;
3509  Rows( Rows&& ) = default;
3511  //**********************************************************************************************
3512 
3513  //**Destructor**********************************************************************************
3516  ~Rows() = default;
3518  //**********************************************************************************************
3519 
3520  //**Data access functions***********************************************************************
3523  inline Reference operator()( size_t i, size_t j );
3524  inline ConstReference operator()( size_t i, size_t j ) const;
3525  inline Reference at( size_t i, size_t j );
3526  inline ConstReference at( size_t i, size_t j ) const;
3527  inline Pointer data () noexcept;
3528  inline ConstPointer data () const noexcept;
3529  inline Pointer data ( size_t i ) noexcept;
3530  inline ConstPointer data ( size_t i ) const noexcept;
3531  inline Iterator begin ( size_t i );
3532  inline ConstIterator begin ( size_t i ) const;
3533  inline ConstIterator cbegin( size_t i ) const;
3534  inline Iterator end ( size_t i );
3535  inline ConstIterator end ( size_t i ) const;
3536  inline ConstIterator cend ( size_t i ) const;
3538  //**********************************************************************************************
3539 
3540  //**Assignment operators************************************************************************
3543  inline Rows& operator=( const ElementType& rhs );
3544  inline Rows& operator=( initializer_list< initializer_list<ElementType> > list );
3545  inline Rows& operator=( const Rows& rhs );
3546 
3547  template< typename MT2, bool SO2 >
3548  inline Rows& operator=( const Matrix<MT2,SO2>& rhs );
3549 
3550  template< typename MT2, bool SO2 >
3551  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3552  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3553 
3554  template< typename MT2, bool SO2 >
3555  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3556  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3557 
3558  template< typename MT2, bool SO2 >
3559  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3560  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3561 
3562  template< typename MT2, bool SO2 >
3563  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3564  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3565 
3566  template< typename MT2, bool SO2 >
3567  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3568  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3569 
3570  template< typename MT2, bool SO2 >
3571  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3572  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3574  //**********************************************************************************************
3575 
3576  //**Utility functions***************************************************************************
3579  using DataType::idx;
3580  using DataType::idces;
3581  using DataType::rows;
3582 
3583  inline MT& operand() noexcept;
3584  inline const MT& operand() const noexcept;
3585 
3586  inline size_t columns() const noexcept;
3587  inline size_t spacing() const noexcept;
3588  inline size_t capacity() const noexcept;
3589  inline size_t capacity( size_t i ) const noexcept;
3590  inline size_t nonZeros() const;
3591  inline size_t nonZeros( size_t i ) const;
3592  inline void reset();
3593  inline void reset( size_t i );
3595  //**********************************************************************************************
3596 
3597  //**Numeric functions***************************************************************************
3600  inline Rows& transpose();
3601  inline Rows& ctranspose();
3602 
3603  template< typename Other > inline Rows& scale( const Other& scalar );
3605  //**********************************************************************************************
3606 
3607  //**Expression template evaluation functions****************************************************
3610  template< typename Other >
3611  inline bool canAlias( const Other* alias ) const noexcept;
3612 
3613  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
3614  inline bool canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
3615 
3616  template< typename Other >
3617  inline bool isAliased( const Other* alias ) const noexcept;
3618 
3619  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
3620  inline bool isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
3621 
3622  inline bool isAligned () const noexcept;
3623  inline bool canSMPAssign() const noexcept;
3624 
3625  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3626  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
3627  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3628  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3629 
3630  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3631  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
3632  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3633  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3634 
3635  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3636  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
3637  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3638  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3639 
3640  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
3641  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
3642  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
3643  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
3645  //**********************************************************************************************
3646 
3647  private:
3648  //**Member variables****************************************************************************
3651  Operand matrix_;
3652 
3653  //**********************************************************************************************
3654 
3655  //**Friend declarations*************************************************************************
3656  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CRAs2 > friend class Rows;
3657  //**********************************************************************************************
3658 
3659  //**Compile time checks*************************************************************************
3669  //**********************************************************************************************
3670 };
3672 //*************************************************************************************************
3673 
3674 
3675 
3676 
3677 //=================================================================================================
3678 //
3679 // CONSTRUCTORS
3680 //
3681 //=================================================================================================
3682 
3683 //*************************************************************************************************
3696 template< typename MT // Type of the dense matrix
3697  , typename... CRAs > // Compile time row arguments
3698 template< typename... RRAs > // Runtime row arguments
3699 inline Rows<MT,false,true,false,CRAs...>::Rows( MT& matrix, RRAs... args )
3700  : DataType( args... ) // Base class initialization
3701  , matrix_ ( matrix ) // The matrix containing the rows
3702 {
3703  if( !Contains_v< TypeList<RRAs...>, Unchecked > ) {
3704  for( size_t i=0UL; i<rows(); ++i ) {
3705  if( matrix_.rows() <= idx(i) ) {
3706  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
3707  }
3708  }
3709  }
3710 }
3712 //*************************************************************************************************
3713 
3714 
3715 
3716 
3717 //=================================================================================================
3718 //
3719 // DATA ACCESS FUNCTIONS
3720 //
3721 //=================================================================================================
3722 
3723 //*************************************************************************************************
3734 template< typename MT // Type of the dense matrix
3735  , typename... CRAs > // Compile time row arguments
3736 inline typename Rows<MT,false,true,false,CRAs...>::Reference
3737  Rows<MT,false,true,false,CRAs...>::operator()( size_t i, size_t j )
3738 {
3739  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3740  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3741 
3742  return matrix_(idx(i),j);
3743 }
3745 //*************************************************************************************************
3746 
3747 
3748 //*************************************************************************************************
3759 template< typename MT // Type of the dense matrix
3760  , typename... CRAs > // Compile time row arguments
3761 inline typename Rows<MT,false,true,false,CRAs...>::ConstReference
3762  Rows<MT,false,true,false,CRAs...>::operator()( size_t i, size_t j ) const
3763 {
3764  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3765  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3766 
3767  return const_cast<const MT&>( matrix_ )(idx(i),j);
3768 }
3770 //*************************************************************************************************
3771 
3772 
3773 //*************************************************************************************************
3785 template< typename MT // Type of the dense matrix
3786  , typename... CRAs > // Compile time row arguments
3787 inline typename Rows<MT,false,true,false,CRAs...>::Reference
3788  Rows<MT,false,true,false,CRAs...>::at( size_t i, size_t j )
3789 {
3790  if( i >= rows() ) {
3791  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3792  }
3793  if( j >= columns() ) {
3794  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3795  }
3796  return (*this)(i,j);
3797 }
3799 //*************************************************************************************************
3800 
3801 
3802 //*************************************************************************************************
3814 template< typename MT // Type of the dense matrix
3815  , typename... CRAs > // Compile time row arguments
3816 inline typename Rows<MT,false,true,false,CRAs...>::ConstReference
3817  Rows<MT,false,true,false,CRAs...>::at( size_t i, size_t j ) const
3818 {
3819  if( i >= rows() ) {
3820  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3821  }
3822  if( j >= columns() ) {
3823  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3824  }
3825  return (*this)(i,j);
3826 }
3828 //*************************************************************************************************
3829 
3830 
3831 //*************************************************************************************************
3841 template< typename MT // Type of the dense matrix
3842  , typename... CRAs > // Compile time row arguments
3843 inline typename Rows<MT,false,true,false,CRAs...>::Pointer
3845 {
3846  return matrix_.data() + idx(0UL);
3847 }
3849 //*************************************************************************************************
3850 
3851 
3852 //*************************************************************************************************
3862 template< typename MT // Type of the dense matrix
3863  , typename... CRAs > // Compile time row arguments
3864 inline typename Rows<MT,false,true,false,CRAs...>::ConstPointer
3866 {
3867  return matrix_.data() + idx(0UL);
3868 }
3870 //*************************************************************************************************
3871 
3872 
3873 //*************************************************************************************************
3882 template< typename MT // Type of the dense matrix
3883  , typename... CRAs > // Compile time row arguments
3884 inline typename Rows<MT,false,true,false,CRAs...>::Pointer
3885  Rows<MT,false,true,false,CRAs...>::data( size_t i ) noexcept
3886 {
3887  return matrix_.data() + idx(i);
3888 }
3890 //*************************************************************************************************
3891 
3892 
3893 //*************************************************************************************************
3902 template< typename MT // Type of the dense matrix
3903  , typename... CRAs > // Compile time row arguments
3904 inline typename Rows<MT,false,true,false,CRAs...>::ConstPointer
3905  Rows<MT,false,true,false,CRAs...>::data( size_t i ) const noexcept
3906 {
3907  return matrix_.data() + idx(i);
3908 }
3910 //*************************************************************************************************
3911 
3912 
3913 //*************************************************************************************************
3922 template< typename MT // Type of the dense matrix
3923  , typename... CRAs > // Compile time row arguments
3924 inline typename Rows<MT,false,true,false,CRAs...>::Iterator
3926 {
3927  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3928  return Iterator( matrix_, idx(i), 0UL );
3929 }
3931 //*************************************************************************************************
3932 
3933 
3934 //*************************************************************************************************
3943 template< typename MT // Type of the dense matrix
3944  , typename... CRAs > // Compile time row arguments
3945 inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
3947 {
3948  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3949  return ConstIterator( matrix_, idx(i), 0UL );
3950 }
3952 //*************************************************************************************************
3953 
3954 
3955 //*************************************************************************************************
3964 template< typename MT // Type of the dense matrix
3965  , typename... CRAs > // Compile time row arguments
3966 inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
3968 {
3969  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3970  return ConstIterator( matrix_, idx(i), 0UL );
3971 }
3973 //*************************************************************************************************
3974 
3975 
3976 //*************************************************************************************************
3985 template< typename MT // Type of the dense matrix
3986  , typename... CRAs > // Compile time row arguments
3987 inline typename Rows<MT,false,true,false,CRAs...>::Iterator
3989 {
3990  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3991  return Iterator( matrix_, idx(i), columns() );
3992 }
3994 //*************************************************************************************************
3995 
3996 
3997 //*************************************************************************************************
4006 template< typename MT // Type of the dense matrix
4007  , typename... CRAs > // Compile time row arguments
4008 inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
4009  Rows<MT,false,true,false,CRAs...>::end( size_t i ) const
4010 {
4011  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4012  return ConstIterator( matrix_, idx(i), columns() );
4013 }
4015 //*************************************************************************************************
4016 
4017 
4018 //*************************************************************************************************
4027 template< typename MT // Type of the dense matrix
4028  , typename... CRAs > // Compile time row arguments
4029 inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
4030  Rows<MT,false,true,false,CRAs...>::cend( size_t i ) const
4031 {
4032  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4033  return ConstIterator( matrix_, idx(i), columns() );
4034 }
4036 //*************************************************************************************************
4037 
4038 
4039 
4040 
4041 //=================================================================================================
4042 //
4043 // ASSIGNMENT OPERATORS
4044 //
4045 //=================================================================================================
4046 
4047 //*************************************************************************************************
4058 template< typename MT // Type of the dense matrix
4059  , typename... CRAs > // Compile time row arguments
4060 inline Rows<MT,false,true,false,CRAs...>&
4061  Rows<MT,false,true,false,CRAs...>::operator=( const ElementType& rhs )
4062 {
4063  for( size_t i=0UL; i<rows(); ++i ) {
4064  row( matrix_, idx(i), unchecked ) = rhs;
4065  }
4066 
4067  return *this;
4068 }
4070 //*************************************************************************************************
4071 
4072 
4073 //*************************************************************************************************
4089 template< typename MT // Type of the dense matrix
4090  , typename... CRAs > // Compile time row arguments
4091 inline Rows<MT,false,true,false,CRAs...>&
4092  Rows<MT,false,true,false,CRAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
4093 {
4096 
4097  if( list.size() != rows() ) {
4098  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row selection" );
4099  }
4100 
4101  if( IsRestricted_v<MT> ) {
4102  size_t i( 0UL );
4103  for( const auto& rowList : list ) {
4104  const InitializerVector<ElementType> tmp( rowList, columns() );
4105  if( !tryAssign( row( matrix_, idx(i), unchecked ), tmp, 0UL ) ){
4106  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4107  }
4108  ++i;
4109  }
4110  }
4111 
4112  decltype(auto) left( derestrict( *this ) );
4113  size_t i( 0UL );
4114 
4115  for( const auto& rowList : list ) {
4116  std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
4117  ++i;
4118  }
4119 
4120  return *this;
4121 }
4123 //*************************************************************************************************
4124 
4125 
4126 //*************************************************************************************************
4141 template< typename MT // Type of the dense matrix
4142  , typename... CRAs > // Compile time row arguments
4143 inline Rows<MT,false,true,false,CRAs...>&
4144  Rows<MT,false,true,false,CRAs...>::operator=( const Rows& rhs )
4145 {
4148 
4151 
4152  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
4153  return *this;
4154 
4155  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
4156  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4157  }
4158 
4159  if( IsRestricted_v<MT> ) {
4160  for( size_t i=0UL; i<rows(); ++i ) {
4161  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( rhs, i, unchecked ), 0UL ) ) {
4162  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4163  }
4164  }
4165  }
4166 
4167  decltype(auto) left( derestrict( *this ) );
4168 
4169  if( rhs.canAlias( &matrix_ ) ) {
4170  const ResultType tmp( rhs );
4171  smpAssign( left, tmp );
4172  }
4173  else {
4174  smpAssign( left, rhs );
4175  }
4176 
4177  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4178 
4179  return *this;
4180 }
4182 //*************************************************************************************************
4183 
4184 
4185 //*************************************************************************************************
4200 template< typename MT // Type of the dense matrix
4201  , typename... CRAs > // Compile time row arguments
4202 template< typename MT2 // Type of the right-hand side matrix
4203  , bool SO2 > // Storage order of the right-hand side matrix
4204 inline Rows<MT,false,true,false,CRAs...>&
4205  Rows<MT,false,true,false,CRAs...>::operator=( const Matrix<MT2,SO2>& rhs )
4206 {
4209 
4210  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4211 
4212  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4213  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4214  }
4215 
4216  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
4217  Right right( ~rhs );
4218 
4219  if( IsRestricted_v<MT> ) {
4220  for( size_t i=0UL; i<rows(); ++i ) {
4221  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( right, i, unchecked ), 0UL ) ) {
4222  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4223  }
4224  }
4225  }
4226 
4227  decltype(auto) left( derestrict( *this ) );
4228 
4229  if( IsSparseMatrix_v<MT2> ) {
4230  reset();
4231  }
4232 
4233  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
4234  const ResultType_t<MT2> tmp( right );
4235  smpAssign( left, tmp );
4236  }
4237  else {
4238  smpAssign( left, right );
4239  }
4240 
4241  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4242 
4243  return *this;
4244 }
4246 //*************************************************************************************************
4247 
4248 
4249 //*************************************************************************************************
4263 template< typename MT // Type of the dense matrix
4264  , typename... CRAs > // Compile time row arguments
4265 template< typename MT2 // Type of the right-hand side matrix
4266  , bool SO2 > // Storage order of the right-hand side matrix
4267 inline auto Rows<MT,false,true,false,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4268  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4269 {
4272 
4275  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4276 
4277  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4278 
4281 
4282  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4283  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4284  }
4285 
4286  if( IsRestricted_v<MT> ) {
4287  for( size_t i=0UL; i<rows(); ++i ) {
4288  if( !tryAddAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
4289  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4290  }
4291  }
4292  }
4293 
4294  decltype(auto) left( derestrict( *this ) );
4295 
4296  if( (~rhs).canAlias( &matrix_ ) ) {
4297  const AddType tmp( *this + (~rhs) );
4298  smpAssign( left, tmp );
4299  }
4300  else {
4301  smpAddAssign( left, ~rhs );
4302  }
4303 
4304  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4305 
4306  return *this;
4307 }
4309 //*************************************************************************************************
4310 
4311 
4312 //*************************************************************************************************
4326 template< typename MT // Type of the dense matrix
4327  , typename... CRAs > // Compile time row arguments
4328 template< typename MT2 // Type of the right-hand side matrix
4329  , bool SO2 > // Storage order of the right-hand side matrix
4330 inline auto Rows<MT,false,true,false,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4331  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4332 {
4335 
4338  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4339 
4340  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4341 
4344 
4345  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4346  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4347  }
4348 
4349  const AddType tmp( *this + (~rhs) );
4350 
4351  if( IsRestricted_v<MT> ) {
4352  for( size_t i=0UL; i<rows(); ++i ) {
4353  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
4354  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4355  }
4356  }
4357  }
4358 
4359  decltype(auto) left( derestrict( *this ) );
4360 
4361  smpAssign( left, tmp );
4362 
4363  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4364 
4365  return *this;
4366 }
4368 //*************************************************************************************************
4369 
4370 
4371 //*************************************************************************************************
4385 template< typename MT // Type of the dense matrix
4386  , typename... CRAs > // Compile time row arguments
4387 template< typename MT2 // Type of the right-hand side matrix
4388  , bool SO2 > // Storage order of the right-hand side matrix
4389 inline auto Rows<MT,false,true,false,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4390  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4391 {
4394 
4397  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4398 
4399  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4400 
4403 
4404  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4405  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4406  }
4407 
4408  if( IsRestricted_v<MT> ) {
4409  for( size_t i=0UL; i<rows(); ++i ) {
4410  if( !trySubAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
4411  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4412  }
4413  }
4414  }
4415 
4416  decltype(auto) left( derestrict( *this ) );
4417 
4418  if( (~rhs).canAlias( &matrix_ ) ) {
4419  const SubType tmp( *this - (~rhs ) );
4420  smpAssign( left, tmp );
4421  }
4422  else {
4423  smpSubAssign( left, ~rhs );
4424  }
4425 
4426  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4427 
4428  return *this;
4429 }
4431 //*************************************************************************************************
4432 
4433 
4434 //*************************************************************************************************
4448 template< typename MT // Type of the dense matrix
4449  , typename... CRAs > // Compile time row arguments
4450 template< typename MT2 // Type of the right-hand side matrix
4451  , bool SO2 > // Storage order of the right-hand side matrix
4452 inline auto Rows<MT,false,true,false,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4453  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4454 {
4457 
4460  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4461 
4462  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4463 
4466 
4467  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4468  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4469  }
4470 
4471  const SubType tmp( *this - (~rhs) );
4472 
4473  if( IsRestricted_v<MT> ) {
4474  for( size_t i=0UL; i<rows(); ++i ) {
4475  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
4476  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4477  }
4478  }
4479  }
4480 
4481  decltype(auto) left( derestrict( *this ) );
4482 
4483  smpAssign( left, tmp );
4484 
4485  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4486 
4487  return *this;
4488 }
4490 //*************************************************************************************************
4491 
4492 
4493 //*************************************************************************************************
4507 template< typename MT // Type of the dense matrix
4508  , typename... CRAs > // Compile time row arguments
4509 template< typename MT2 // Type of the right-hand side matrix
4510  , bool SO2 > // Storage order of the right-hand side matrix
4511 inline auto Rows<MT,false,true,false,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4512  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4513 {
4516 
4519  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4520 
4521  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4522 
4524 
4525  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4526  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4527  }
4528 
4529  if( IsRestricted_v<MT> ) {
4530  for( size_t i=0UL; i<rows(); ++i ) {
4531  if( !tryMultAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
4532  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4533  }
4534  }
4535  }
4536 
4537  decltype(auto) left( derestrict( *this ) );
4538 
4539  if( (~rhs).canAlias( &matrix_ ) ) {
4540  const SchurType tmp( *this % (~rhs) );
4541  if( IsSparseMatrix_v<SchurType> )
4542  reset();
4543  smpAssign( left, tmp );
4544  }
4545  else {
4546  smpSchurAssign( left, ~rhs );
4547  }
4548 
4549  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4550 
4551  return *this;
4552 }
4554 //*************************************************************************************************
4555 
4556 
4557 //*************************************************************************************************
4571 template< typename MT // Type of the dense matrix
4572  , typename... CRAs > // Compile time row arguments
4573 template< typename MT2 // Type of the right-hand side matrix
4574  , bool SO2 > // Storage order of the right-hand side matrix
4575 inline auto Rows<MT,false,true,false,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4576  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4577 {
4580 
4583  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4584 
4585  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4586 
4588 
4589  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4590  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4591  }
4592 
4593  const SchurType tmp( *this % (~rhs) );
4594 
4595  if( IsRestricted_v<MT> ) {
4596  for( size_t i=0UL; i<rows(); ++i ) {
4597  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
4598  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4599  }
4600  }
4601  }
4602 
4603  decltype(auto) left( derestrict( *this ) );
4604 
4605  if( IsSparseMatrix_v<SchurType> ) {
4606  reset();
4607  }
4608 
4609  smpAssign( left, tmp );
4610 
4611  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4612 
4613  return *this;
4614 }
4616 //*************************************************************************************************
4617 
4618 
4619 
4620 
4621 //=================================================================================================
4622 //
4623 // UTILITY FUNCTIONS
4624 //
4625 //=================================================================================================
4626 
4627 //*************************************************************************************************
4633 template< typename MT // Type of the dense matrix
4634  , typename... CRAs > // Compile time row arguments
4635 inline MT& Rows<MT,false,true,false,CRAs...>::operand() noexcept
4636 {
4637  return matrix_;
4638 }
4640 //*************************************************************************************************
4641 
4642 
4643 //*************************************************************************************************
4649 template< typename MT // Type of the dense matrix
4650  , typename... CRAs > // Compile time row arguments
4651 inline const MT& Rows<MT,false,true,false,CRAs...>::operand() const noexcept
4652 {
4653  return matrix_;
4654 }
4656 //*************************************************************************************************
4657 
4658 
4659 //*************************************************************************************************
4665 template< typename MT // Type of the dense matrix
4666  , typename... CRAs > // Compile time row arguments
4667 inline size_t Rows<MT,false,true,false,CRAs...>::columns() const noexcept
4668 {
4669  return matrix_.columns();
4670 }
4672 //*************************************************************************************************
4673 
4674 
4675 //*************************************************************************************************
4684 template< typename MT // Type of the dense matrix
4685  , typename... CRAs > // Compile time row arguments
4686 inline size_t Rows<MT,false,true,false,CRAs...>::spacing() const noexcept
4687 {
4688  return matrix_.columns();
4689 }
4691 //*************************************************************************************************
4692 
4693 
4694 //*************************************************************************************************
4700 template< typename MT // Type of the dense matrix
4701  , typename... CRAs > // Compile time row arguments
4702 inline size_t Rows<MT,false,true,false,CRAs...>::capacity() const noexcept
4703 {
4704  return rows() * columns();
4705 }
4707 //*************************************************************************************************
4708 
4709 
4710 //*************************************************************************************************
4719 template< typename MT // Type of the dense matrix
4720  , typename... CRAs > // Compile time row arguments
4721 inline size_t Rows<MT,false,true,false,CRAs...>::capacity( size_t i ) const noexcept
4722 {
4723  MAYBE_UNUSED( i );
4724 
4725  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4726 
4727  return columns();
4728 }
4730 //*************************************************************************************************
4731 
4732 
4733 //*************************************************************************************************
4739 template< typename MT // Type of the dense matrix
4740  , typename... CRAs > // Compile time row arguments
4741 inline size_t Rows<MT,false,true,false,CRAs...>::nonZeros() const
4742 {
4743  size_t nonzeros( 0UL );
4744 
4745  for( size_t i=0UL; i<rows(); ++i ) {
4746  nonzeros += nonZeros( i );
4747  }
4748 
4749  return nonzeros;
4750 }
4752 //*************************************************************************************************
4753 
4754 
4755 //*************************************************************************************************
4764 template< typename MT // Type of the dense matrix
4765  , typename... CRAs > // Compile time row arguments
4766 inline size_t Rows<MT,false,true,false,CRAs...>::nonZeros( size_t i ) const
4767 {
4768  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4769 
4770  size_t nonzeros( 0UL );
4771 
4772  const size_t index( idx(i) );
4773  for( size_t j=0UL; j<columns(); ++j ) {
4774  if( !isDefault( matrix_( index, j ) ) )
4775  ++nonzeros;
4776  }
4777 
4778  return nonzeros;
4779 }
4781 //*************************************************************************************************
4782 
4783 
4784 //*************************************************************************************************
4790 template< typename MT // Type of the dense matrix
4791  , typename... CRAs > // Compile time row arguments
4793 {
4794  for( size_t i=0UL; i<rows(); ++i ) {
4795  reset( i );
4796  }
4797 }
4799 //*************************************************************************************************
4800 
4801 
4802 //*************************************************************************************************
4811 template< typename MT // Type of the dense matrix
4812  , typename... CRAs > // Compile time row arguments
4813 inline void Rows<MT,false,true,false,CRAs...>::reset( size_t i )
4814 {
4815  using blaze::reset;
4816 
4817  const size_t index( idx(i) );
4818  for( size_t j=0UL; j<columns(); ++j ) {
4819  reset( matrix_( index, j ) );
4820  }
4821 }
4823 //*************************************************************************************************
4824 
4825 
4826 
4827 
4828 //=================================================================================================
4829 //
4830 // NUMERIC FUNCTIONS
4831 //
4832 //=================================================================================================
4833 
4834 //*************************************************************************************************
4847 template< typename MT // Type of the dense matrix
4848  , typename... CRAs > // Compile time row arguments
4849 inline Rows<MT,false,true,false,CRAs...>&
4851 {
4854 
4855  if( rows() != columns() ) {
4856  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4857  }
4858 
4859  const ResultType tmp( trans( *this ) );
4860 
4861  if( IsRestricted_v<MT> ) {
4862  for( size_t i=0UL; i<rows(); ++i ) {
4863  if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
4864  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4865  }
4866  }
4867  }
4868 
4869  decltype(auto) left( derestrict( *this ) );
4870 
4871  smpAssign( left, tmp );
4872 
4873  return *this;
4874 }
4876 //*************************************************************************************************
4877 
4878 
4879 //*************************************************************************************************
4892 template< typename MT // Type of the dense matrix
4893  , typename... CRAs > // Compile time row arguments
4894 inline Rows<MT,false,true,false,CRAs...>&
4895  Rows<MT,false,true,false,CRAs...>::ctranspose()
4896 {
4899 
4900  if( rows() != columns() ) {
4901  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4902  }
4903 
4904  const ResultType tmp( ctrans( *this ) );
4905 
4906  if( IsRestricted_v<MT> ) {
4907  for( size_t i=0UL; i<rows(); ++i ) {
4908  if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
4909  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4910  }
4911  }
4912  }
4913 
4914  decltype(auto) left( derestrict( *this ) );
4915 
4916  smpAssign( left, tmp );
4917 
4918  return *this;
4919 }
4921 //*************************************************************************************************
4922 
4923 
4924 //*************************************************************************************************
4937 template< typename MT // Type of the dense matrix
4938  , typename... CRAs > // Compile time row arguments
4939 template< typename Other > // Data type of the scalar value
4940 inline Rows<MT,false,true,false,CRAs...>&
4941  Rows<MT,false,true,false,CRAs...>::scale( const Other& scalar )
4942 {
4946 
4947  for( size_t i=0UL; i<rows(); ++i )
4948  {
4949  const size_t index ( idx(i) );
4950  const size_t jbegin( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index+1UL : index ) : 0UL );
4951  const size_t jend ( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index : index+1UL ) : columns() );
4952 
4953  for( size_t j=jbegin; j<jend; ++j ) {
4954  matrix_(index,j) *= scalar;
4955  }
4956  }
4957 
4958  return *this;
4959 }
4961 //*************************************************************************************************
4962 
4963 
4964 
4965 
4966 //=================================================================================================
4967 //
4968 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4969 //
4970 //=================================================================================================
4971 
4972 //*************************************************************************************************
4983 template< typename MT // Type of the dense matrix
4984  , typename... CRAs > // Compile time row arguments
4985 template< typename Other > // Data type of the foreign expression
4986 inline bool Rows<MT,false,true,false,CRAs...>::canAlias( const Other* alias ) const noexcept
4987 {
4988  return matrix_.isAliased( alias );
4989 }
4991 //*************************************************************************************************
4992 
4993 
4994 //*************************************************************************************************
5006 template< typename MT // Type of the dense matrix
5007  , typename... CRAs > // Compile time row arguments
5008 template< typename MT2 // Data type of the foreign dense row selection
5009  , bool SO2 // Storage order of the foreign dense row selection
5010  , bool SF2 // Symmetry flag of the foreign dense row selection
5011  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
5012 inline bool
5013  Rows<MT,false,true,false,CRAs...>::canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
5014 {
5015  return matrix_.isAliased( &alias->matrix_ );
5016 }
5018 //*************************************************************************************************
5019 
5020 
5021 //*************************************************************************************************
5032 template< typename MT // Type of the dense matrix
5033  , typename... CRAs > // Compile time row arguments
5034 template< typename Other > // Data type of the foreign expression
5035 inline bool Rows<MT,false,true,false,CRAs...>::isAliased( const Other* alias ) const noexcept
5036 {
5037  return matrix_.isAliased( alias );
5038 }
5040 //*************************************************************************************************
5041 
5042 
5043 //*************************************************************************************************
5055 template< typename MT // Type of the dense matrix
5056  , typename... CRAs > // Compile time row arguments
5057 template< typename MT2 // Data type of the foreign dense row selection
5058  , bool SO2 // Storage order of the foreign dense row selection
5059  , bool SF2 // Symmetry flag of the foreign dense row selection
5060  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
5061 inline bool
5062  Rows<MT,false,true,false,CRAs...>::isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
5063 {
5064  return matrix_.isAliased( &alias->matrix_ );
5065 }
5067 //*************************************************************************************************
5068 
5069 
5070 //*************************************************************************************************
5080 template< typename MT // Type of the dense matrix
5081  , typename... CRAs > // Compile time row arguments
5082 inline bool Rows<MT,false,true,false,CRAs...>::isAligned() const noexcept
5083 {
5084  return false;
5085 }
5087 //*************************************************************************************************
5088 
5089 
5090 //*************************************************************************************************
5101 template< typename MT // Type of the dense matrix
5102  , typename... CRAs > // Compile time row arguments
5103 inline bool Rows<MT,false,true,false,CRAs...>::canSMPAssign() const noexcept
5104 {
5105  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
5106 }
5108 //*************************************************************************************************
5109 
5110 
5111 //*************************************************************************************************
5123 template< typename MT // Type of the dense matrix
5124  , typename... CRAs > // Compile time row arguments
5125 template< typename MT2 > // Type of the right-hand side dense matrix
5126 inline void Rows<MT,false,true,false,CRAs...>::assign( const DenseMatrix<MT2,false>& rhs )
5127 {
5130 
5131  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5132  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5133 
5134  const size_t jpos( columns() & size_t(-2) );
5135  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
5136 
5137  for( size_t i=0UL; i<rows(); ++i ) {
5138  const size_t index( idx(i) );
5139  for( size_t j=0UL; j<jpos; j+=2UL ) {
5140  matrix_(index,j ) = (~rhs)(i,j );
5141  matrix_(index,j+1UL) = (~rhs)(i,j+1UL);
5142  }
5143  if( jpos < columns() ) {
5144  matrix_(index,jpos) = (~rhs)(i,jpos);
5145  }
5146  }
5147 }
5149 //*************************************************************************************************
5150 
5151 
5152 //*************************************************************************************************
5164 template< typename MT // Type of the dense matrix
5165  , typename... CRAs > // Compile time row arguments
5166 template< typename MT2 > // Type of the right-hand side dense matrix
5167 inline void Rows<MT,false,true,false,CRAs...>::assign( const DenseMatrix<MT2,true>& rhs )
5168 {
5171 
5173 
5174  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5175  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5176 
5177  constexpr size_t block( BLOCK_SIZE );
5178 
5179  if( rows() < block && columns() < block )
5180  {
5181  const size_t jpos( (~rhs).columns() & size_t(-2) );
5182  for( size_t i=0UL; i<rows(); ++i ) {
5183  const size_t index( idx(i) );
5184  for( size_t j=0UL; j<jpos; j+=2UL ) {
5185  matrix_(index,j ) = (~rhs)(i,j );
5186  matrix_(index,j+1UL) = (~rhs)(i,j+1UL);
5187  }
5188  if( jpos < (~rhs).columns() )
5189  matrix_(index,jpos) = (~rhs)(i,jpos);
5190  }
5191  }
5192  else
5193  {
5194  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5195  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5196  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5197  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5198  for( size_t i=ii; i<iend; ++i ) {
5199  const size_t index( idx(i) );
5200  for( size_t j=jj; j<jend; ++j ) {
5201  matrix_(index,j) = (~rhs)(i,j);
5202  }
5203  }
5204  }
5205  }
5206  }
5207 }
5209 //*************************************************************************************************
5210 
5211 
5212 //*************************************************************************************************
5224 template< typename MT // Type of the dense matrix
5225  , typename... CRAs > // Compile time row arguments
5226 template< typename MT2 > // Type of the right-hand side sparse matrix
5227 inline void Rows<MT,false,true,false,CRAs...>::assign( const SparseMatrix<MT2,false>& rhs )
5228 {
5231 
5232  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5233  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5234 
5235  for( size_t i=0UL; i<rows(); ++i ) {
5236  const size_t index( idx(i) );
5237  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5238  matrix_(index,element->index()) = element->value();
5239  }
5240 }
5242 //*************************************************************************************************
5243 
5244 
5245 //*************************************************************************************************
5257 template< typename MT // Type of the dense matrix
5258  , typename... CRAs > // Compile time row arguments
5259 template< typename MT2 > // Type of the right-hand side sparse matrix
5260 inline void Rows<MT,false,true,false,CRAs...>::assign( const SparseMatrix<MT2,true>& rhs )
5261 {
5264 
5266 
5267  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5268  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5269 
5270  for( size_t j=0UL; j<columns(); ++j ) {
5271  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5272  matrix_(idx(element->index()),j) = element->value();
5273  }
5274 }
5276 //*************************************************************************************************
5277 
5278 
5279 //*************************************************************************************************
5291 template< typename MT // Type of the dense matrix
5292  , typename... CRAs > // Compile time row arguments
5293 template< typename MT2 > // Type of the right-hand side dense matrix
5294 inline void Rows<MT,false,true,false,CRAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
5295 {
5298 
5299  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5300  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5301 
5302  const size_t jpos( columns() & size_t(-2) );
5303  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
5304 
5305  for( size_t i=0UL; i<rows(); ++i )
5306  {
5307  const size_t index( idx(i) );
5308  if( IsDiagonal_v<MT2> ) {
5309  matrix_(index,i) += (~rhs)(i,i);
5310  }
5311  else {
5312  for( size_t j=0UL; j<jpos; j+=2UL ) {
5313  matrix_(index,j ) += (~rhs)(i,j );
5314  matrix_(index,j+1UL) += (~rhs)(i,j+1UL);
5315  }
5316  if( jpos < columns() ) {
5317  matrix_(index,jpos) += (~rhs)(i,jpos);
5318  }
5319  }
5320  }
5321 }
5323 //*************************************************************************************************
5324 
5325 
5326 //*************************************************************************************************
5338 template< typename MT // Type of the dense matrix
5339  , typename... CRAs > // Compile time row arguments
5340 template< typename MT2 > // Type of the right-hand side dense matrix
5341 inline void Rows<MT,false,true,false,CRAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
5342 {
5345 
5347 
5348  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5349  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5350 
5351  constexpr size_t block( BLOCK_SIZE );
5352 
5353  if( rows() < block && columns() < block )
5354  {
5355  const size_t jpos( (~rhs).columns() & size_t(-2) );
5356  for( size_t i=0UL; i<rows(); ++i ) {
5357  const size_t index( idx(i) );
5358  for( size_t j=0UL; j<jpos; j+=2UL ) {
5359  matrix_(index,j ) += (~rhs)(i,j );
5360  matrix_(index,j+1UL) += (~rhs)(i,j+1UL);
5361  }
5362  if( jpos < (~rhs).columns() )
5363  matrix_(index,jpos) += (~rhs)(i,jpos);
5364  }
5365  }
5366  else
5367  {
5368  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5369  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5370  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5371  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5372  for( size_t i=ii; i<iend; ++i ) {
5373  const size_t index( idx(i) );
5374  for( size_t j=jj; j<jend; ++j ) {
5375  matrix_(index,j) += (~rhs)(i,j);
5376  }
5377  }
5378  }
5379  }
5380  }
5381 }
5383 //*************************************************************************************************
5384 
5385 
5386 //*************************************************************************************************
5398 template< typename MT // Type of the dense matrix
5399  , typename... CRAs > // Compile time row arguments
5400 template< typename MT2 > // Type of the right-hand side sparse matrix
5401 inline void Rows<MT,false,true,false,CRAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
5402 {
5405 
5406  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5407  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5408 
5409  for( size_t i=0UL; i<rows(); ++i ) {
5410  const size_t index( idx(i) );
5411  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5412  matrix_(index,element->index()) += element->value();
5413  }
5414 }
5416 //*************************************************************************************************
5417 
5418 
5419 //*************************************************************************************************
5431 template< typename MT // Type of the dense matrix
5432  , typename... CRAs > // Compile time row arguments
5433 template< typename MT2 > // Type of the right-hand side sparse matrix
5434 inline void Rows<MT,false,true,false,CRAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
5435 {
5438 
5440 
5441  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5442  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5443 
5444  for( size_t j=0UL; j<columns(); ++j ) {
5445  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5446  matrix_(idx(element->index()),j) += element->value();
5447  }
5448 }
5450 //*************************************************************************************************
5451 
5452 
5453 //*************************************************************************************************
5465 template< typename MT // Type of the dense matrix
5466  , typename... CRAs > // Compile time row arguments
5467 template< typename MT2 > // Type of the right-hand side dense matrix
5468 inline void Rows<MT,false,true,false,CRAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
5469 {
5472 
5473  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5474  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5475 
5476  const size_t jpos( columns() & size_t(-2) );
5477  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
5478 
5479  for( size_t i=0UL; i<rows(); ++i )
5480  {
5481  const size_t index( idx(i) );
5482 
5483  if( IsDiagonal_v<MT2> ) {
5484  matrix_(index,i) -= (~rhs)(i,i);
5485  }
5486  else {
5487  for( size_t j=0UL; j<jpos; j+=2UL ) {
5488  matrix_(index,j ) -= (~rhs)(i,j );
5489  matrix_(index,j+1UL) -= (~rhs)(i,j+1UL);
5490  }
5491  if( jpos < columns() ) {
5492  matrix_(index,jpos) -= (~rhs)(i,jpos);
5493  }
5494  }
5495  }
5496 }
5498 //*************************************************************************************************
5499 
5500 
5501 //*************************************************************************************************
5513 template< typename MT // Type of the dense matrix
5514  , typename... CRAs > // Compile time row arguments
5515 template< typename MT2 > // Type of the right-hand side dense matrix
5516 inline void Rows<MT,false,true,false,CRAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
5517 {
5520 
5522 
5523  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5524  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5525 
5526  constexpr size_t block( BLOCK_SIZE );
5527 
5528  if( rows() < block && columns() < block )
5529  {
5530  const size_t jpos( (~rhs).columns() & size_t(-2) );
5531  for( size_t i=0UL; i<rows(); ++i ) {
5532  const size_t index( idx(i) );
5533  for( size_t j=0UL; j<jpos; j+=2UL ) {
5534  matrix_(index,j ) -= (~rhs)(i,j );
5535  matrix_(index,j+1UL) -= (~rhs)(i,j+1UL);
5536  }
5537  if( jpos < (~rhs).columns() )
5538  matrix_(index,jpos) -= (~rhs)(i,jpos);
5539  }
5540  }
5541  else
5542  {
5543  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5544  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5545  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5546  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5547  for( size_t i=ii; i<iend; ++i ) {
5548  const size_t index( idx(i) );
5549  for( size_t j=jj; j<jend; ++j ) {
5550  matrix_(index,j) -= (~rhs)(i,j);
5551  }
5552  }
5553  }
5554  }
5555  }
5556 }
5558 //*************************************************************************************************
5559 
5560 
5561 //*************************************************************************************************
5573 template< typename MT // Type of the dense matrix
5574  , typename... CRAs > // Compile time row arguments
5575 template< typename MT2 > // Type of the right-hand side sparse matrix
5576 inline void Rows<MT,false,true,false,CRAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
5577 {
5580 
5581  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5582  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5583 
5584  for( size_t i=0UL; i<rows(); ++i ) {
5585  const size_t index( idx(i) );
5586  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5587  matrix_(index,element->index()) -= element->value();
5588  }
5589 }
5591 //*************************************************************************************************
5592 
5593 
5594 //*************************************************************************************************
5606 template< typename MT // Type of the dense matrix
5607  , typename... CRAs > // Compile time row arguments
5608 template< typename MT2 > // Type of the right-hand side sparse matrix
5609 inline void Rows<MT,false,true,false,CRAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
5610 {
5613 
5615 
5616  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5617  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5618 
5619  for( size_t j=0UL; j<columns(); ++j ) {
5620  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5621  matrix_(idx(element->index()),j) -= element->value();
5622  }
5623 }
5625 //*************************************************************************************************
5626 
5627 
5628 //*************************************************************************************************
5640 template< typename MT // Type of the dense matrix
5641  , typename... CRAs > // Compile time row arguments
5642 template< typename MT2 > // Type of the right-hand side dense matrix
5643 inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
5644 {
5647 
5648  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5649  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5650 
5651  const size_t jpos( columns() & size_t(-2) );
5652  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
5653 
5654  for( size_t i=0UL; i<rows(); ++i ) {
5655  const size_t index( idx(i) );
5656  for( size_t j=0UL; j<jpos; j+=2UL ) {
5657  matrix_(index,j ) *= (~rhs)(i,j );
5658  matrix_(index,j+1UL) *= (~rhs)(i,j+1UL);
5659  }
5660  if( jpos < columns() ) {
5661  matrix_(index,jpos) *= (~rhs)(i,jpos);
5662  }
5663  }
5664 }
5666 //*************************************************************************************************
5667 
5668 
5669 //*************************************************************************************************
5681 template< typename MT // Type of the dense matrix
5682  , typename... CRAs > // Compile time row arguments
5683 template< typename MT2 > // Type of the right-hand side dense matrix
5684 inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
5685 {
5688 
5690 
5691  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5692  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5693 
5694  constexpr size_t block( BLOCK_SIZE );
5695 
5696  if( rows() < block && columns() < block )
5697  {
5698  const size_t jpos( (~rhs).columns() & size_t(-2) );
5699  for( size_t i=0UL; i<rows(); ++i ) {
5700  const size_t index( idx(i) );
5701  for( size_t j=0UL; j<jpos; j+=2UL ) {
5702  matrix_(index,j ) *= (~rhs)(i,j );
5703  matrix_(index,j+1UL) *= (~rhs)(i,j+1UL);
5704  }
5705  if( jpos < (~rhs).columns() )
5706  matrix_(index,jpos) *= (~rhs)(i,jpos);
5707  }
5708  }
5709  else
5710  {
5711  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5712  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5713  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5714  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5715  for( size_t i=ii; i<iend; ++i ) {
5716  const size_t index( idx(i) );
5717  for( size_t j=jj; j<jend; ++j ) {
5718  matrix_(index,j) *= (~rhs)(i,j);
5719  }
5720  }
5721  }
5722  }
5723  }
5724 }
5726 //*************************************************************************************************
5727 
5728 
5729 //*************************************************************************************************
5741 template< typename MT // Type of the dense matrix
5742  , typename... CRAs > // Compile time row arguments
5743 template< typename MT2 > // Type of the right-hand side sparse matrix
5744 inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
5745 {
5746  using blaze::reset;
5747 
5750 
5751  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5752  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5753 
5754  for( size_t i=0UL; i<rows(); ++i )
5755  {
5756  const size_t index( idx(i) );
5757  size_t j( 0UL );
5758 
5759  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
5760  for( ; j<element->index(); ++j )
5761  reset( matrix_(index,j) );
5762  matrix_(index,j) *= element->value();
5763  ++j;
5764  }
5765 
5766  for( ; j<columns(); ++j ) {
5767  reset( matrix_(index,j) );
5768  }
5769  }
5770 }
5772 //*************************************************************************************************
5773 
5774 
5775 //*************************************************************************************************
5787 template< typename MT // Type of the dense matrix
5788  , typename... CRAs > // Compile time row arguments
5789 template< typename MT2 > // Type of the right-hand side sparse matrix
5790 inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
5791 {
5792  using blaze::reset;
5793 
5796 
5798 
5799  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5800  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5801 
5802  for( size_t j=0UL; j<columns(); ++j )
5803  {
5804  size_t i( 0UL );
5805 
5806  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
5807  for( ; i<element->index(); ++i )
5808  reset( matrix_(idx(i),j) );
5809  matrix_(idx(i),j) *= element->value();
5810  ++i;
5811  }
5812 
5813  for( ; i<rows(); ++i ) {
5814  reset( matrix_(idx(i),j) );
5815  }
5816  }
5817 }
5819 //*************************************************************************************************
5820 
5821 
5822 
5823 
5824 
5825 
5826 
5827 
5828 //=================================================================================================
5829 //
5830 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR DENSE MATRICES
5831 //
5832 //=================================================================================================
5833 
5834 //*************************************************************************************************
5842 template< typename MT // Type of the dense matrix
5843  , typename... CRAs > // Compile time row arguments
5844 class Rows<MT,false,true,true,CRAs...>
5845  : public View< DenseMatrix< Rows<MT,false,true,true,CRAs...>, false > >
5846  , private RowsData<CRAs...>
5847 {
5848  private:
5849  //**Type definitions****************************************************************************
5850  using DataType = RowsData<CRAs...>;
5851  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
5852  //**********************************************************************************************
5853 
5854  //**Compile time flags**************************************************************************
5855  using DataType::N;
5856  //**********************************************************************************************
5857 
5858  public:
5859  //**Type definitions****************************************************************************
5861  using This = Rows<MT,false,true,true,CRAs...>;
5862 
5863  using BaseType = DenseMatrix<This,false>;
5864  using ViewedType = MT;
5865  using ResultType = RowsTrait_t<MT,N>;
5866  using OppositeType = OppositeType_t<ResultType>;
5867  using TransposeType = TransposeType_t<ResultType>;
5868  using ElementType = ElementType_t<MT>;
5869  using SIMDType = SIMDTrait_t<ElementType>;
5870  using ReturnType = ReturnType_t<MT>;
5871  using CompositeType = const Rows&;
5872 
5874  using ConstReference = ConstReference_t<MT>;
5875 
5877  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
5878 
5880  using ConstPointer = ConstPointer_t<MT>;
5881 
5883  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
5884 
5886  using ConstIterator = ConstIterator_t<MT>;
5887 
5889  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
5890  //**********************************************************************************************
5891 
5892  //**Compilation flags***************************************************************************
5894  static constexpr bool simdEnabled = MT::simdEnabled;
5895 
5897  static constexpr bool smpAssignable = MT::smpAssignable;
5898 
5900  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
5901  //**********************************************************************************************
5902 
5903  //**Constructors********************************************************************************
5906  template< typename... RRAs >
5907  explicit inline Rows( MT& matrix, RRAs... args );
5908 
5909  Rows( const Rows& ) = default;
5910  Rows( Rows&& ) = default;
5912  //**********************************************************************************************
5913 
5914  //**Destructor**********************************************************************************
5917  ~Rows() = default;
5919  //**********************************************************************************************
5920 
5921  //**Data access functions***********************************************************************
5924  inline Reference operator()( size_t i, size_t j );
5925  inline ConstReference operator()( size_t i, size_t j ) const;
5926  inline Reference at( size_t i, size_t j );
5927  inline ConstReference at( size_t i, size_t j ) const;
5928  inline Pointer data () noexcept;
5929  inline ConstPointer data () const noexcept;
5930  inline Pointer data ( size_t i ) noexcept;
5931  inline ConstPointer data ( size_t i ) const noexcept;
5932  inline Iterator begin ( size_t i );
5933  inline ConstIterator begin ( size_t i ) const;
5934  inline ConstIterator cbegin( size_t i ) const;
5935  inline Iterator end ( size_t i );
5936  inline ConstIterator end ( size_t i ) const;
5937  inline ConstIterator cend ( size_t i ) const;
5939  //**********************************************************************************************
5940 
5941  //**Assignment operators************************************************************************
5944  inline Rows& operator=( const ElementType& rhs );
5945 
5946  Rows& operator=( const Rows& ) = delete;
5948  //**********************************************************************************************
5949 
5950  //**Utility functions***************************************************************************
5953  using DataType::idx;
5954  using DataType::idces;
5955  using DataType::rows;
5956 
5957  inline MT& operand() noexcept;
5958  inline const MT& operand() const noexcept;
5959 
5960  inline size_t columns() const noexcept;
5961  inline size_t spacing() const noexcept;
5962  inline size_t capacity() const noexcept;
5963  inline size_t capacity( size_t i ) const noexcept;
5964  inline size_t nonZeros() const;
5965  inline size_t nonZeros( size_t i ) const;
5966  inline void reset();
5967  inline void reset( size_t i );
5969  //**********************************************************************************************
5970 
5971  //**Expression template evaluation functions****************************************************
5974  template< typename Other >
5975  inline bool canAlias( const Other* alias ) const noexcept;
5976 
5977  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
5978  inline bool canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
5979 
5980  template< typename Other >
5981  inline bool isAliased( const Other* alias ) const noexcept;
5982 
5983  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
5984  inline bool isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
5985 
5986  inline bool isAligned () const noexcept;
5987  inline bool canSMPAssign() const noexcept;
5988 
5989  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
5990  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
5991  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
5993  //**********************************************************************************************
5994 
5995  private:
5996  //**Member variables****************************************************************************
5999  Operand matrix_;
6000 
6001  //**********************************************************************************************
6002 
6003  //**Friend declarations*************************************************************************
6004  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CRAs2 > friend class Rows;
6005  //**********************************************************************************************
6006 
6007  //**Compile time checks*************************************************************************
6017  //**********************************************************************************************
6018 };
6020 //*************************************************************************************************
6021 
6022 
6023 
6024 
6025 //=================================================================================================
6026 //
6027 // CONSTRUCTORS
6028 //
6029 //=================================================================================================
6030 
6031 //*************************************************************************************************
6044 template< typename MT // Type of the dense matrix
6045  , typename... CRAs > // Compile time row arguments
6046 template< typename... RRAs > // Runtime row arguments
6047 inline Rows<MT,false,true,true,CRAs...>::Rows( MT& matrix, RRAs... args )
6048  : DataType( args... ) // Base class initialization
6049  , matrix_ ( matrix ) // The matrix containing the rows
6050 {
6051  if( !Contains_v< TypeList<RRAs...>, Unchecked > ) {
6052  for( size_t i=0UL; i<rows(); ++i ) {
6053  if( matrix_.rows() <= idx(i) ) {
6054  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
6055  }
6056  }
6057  }
6058 }
6060 //*************************************************************************************************
6061 
6062 
6063 
6064 
6065 //=================================================================================================
6066 //
6067 // DATA ACCESS FUNCTIONS
6068 //
6069 //=================================================================================================
6070 
6071 //*************************************************************************************************
6082 template< typename MT // Type of the dense matrix
6083  , typename... CRAs > // Compile time row arguments
6084 inline typename Rows<MT,false,true,true,CRAs...>::Reference
6085  Rows<MT,false,true,true,CRAs...>::operator()( size_t i, size_t j )
6086 {
6087  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6088  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6089 
6090  return matrix_(j,idx(i));
6091 }
6093 //*************************************************************************************************
6094 
6095 
6096 //*************************************************************************************************
6107 template< typename MT // Type of the dense matrix
6108  , typename... CRAs > // Compile time row arguments
6109 inline typename Rows<MT,false,true,true,CRAs...>::ConstReference
6110  Rows<MT,false,true,true,CRAs...>::operator()( size_t i, size_t j ) const
6111 {
6112  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6113  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6114 
6115  return const_cast<const MT&>( matrix_ )(j,idx(i));
6116 }
6118 //*************************************************************************************************
6119 
6120 
6121 //*************************************************************************************************
6133 template< typename MT // Type of the dense matrix
6134  , typename... CRAs > // Compile time row arguments
6135 inline typename Rows<MT,false,true,true,CRAs...>::Reference
6136  Rows<MT,false,true,true,CRAs...>::at( size_t i, size_t j )
6137 {
6138  if( i >= rows() ) {
6139  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6140  }
6141  if( j >= columns() ) {
6142  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6143  }
6144  return (*this)(i,j);
6145 }
6147 //*************************************************************************************************
6148 
6149 
6150 //*************************************************************************************************
6162 template< typename MT // Type of the dense matrix
6163  , typename... CRAs > // Compile time row arguments
6164 inline typename Rows<MT,false,true,true,CRAs...>::ConstReference
6165  Rows<MT,false,true,true,CRAs...>::at( size_t i, size_t j ) const
6166 {
6167  if( i >= rows() ) {
6168  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6169  }
6170  if( j >= columns() ) {
6171  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6172  }
6173  return (*this)(i,j);
6174 }
6176 //*************************************************************************************************
6177 
6178 
6179 //*************************************************************************************************
6189 template< typename MT // Type of the dense matrix
6190  , typename... CRAs > // Compile time row arguments
6191 inline typename Rows<MT,false,true,true,CRAs...>::Pointer
6193 {
6194  return matrix_.data( idx(0UL) );
6195 }
6197 //*************************************************************************************************
6198 
6199 
6200 //*************************************************************************************************
6210 template< typename MT // Type of the dense matrix
6211  , typename... CRAs > // Compile time row arguments
6212 inline typename Rows<MT,false,true,true,CRAs...>::ConstPointer
6214 {
6215  return matrix_.data( idx(0UL) );
6216 }
6218 //*************************************************************************************************
6219 
6220 
6221 //*************************************************************************************************
6230 template< typename MT // Type of the dense matrix
6231  , typename... CRAs > // Compile time row arguments
6232 inline typename Rows<MT,false,true,true,CRAs...>::Pointer
6233  Rows<MT,false,true,true,CRAs...>::data( size_t i ) noexcept
6234 {
6235  return matrix_.data( idx(i) );
6236 }
6238 //*************************************************************************************************
6239 
6240 
6241 //*************************************************************************************************
6250 template< typename MT // Type of the dense matrix
6251  , typename... CRAs > // Compile time row arguments
6252 inline typename Rows<MT,false,true,true,CRAs...>::ConstPointer
6253  Rows<MT,false,true,true,CRAs...>::data( size_t i ) const noexcept
6254 {
6255  return matrix_.data( idx(i) );
6256 }
6258 //*************************************************************************************************
6259 
6260 
6261 //*************************************************************************************************
6270 template< typename MT // Type of the dense matrix
6271  , typename... CRAs > // Compile time row arguments
6272 inline typename Rows<MT,false,true,true,CRAs...>::Iterator
6274 {
6275  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6276  return matrix_.begin( idx(i) );
6277 }
6279 //*************************************************************************************************
6280 
6281 
6282 //*************************************************************************************************
6291 template< typename MT // Type of the dense matrix
6292  , typename... CRAs > // Compile time row arguments
6293 inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6294  Rows<MT,false,true,true,CRAs...>::begin( size_t i ) const
6295 {
6296  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6297  return matrix_.cbegin( idx(i) );
6298 }
6300 //*************************************************************************************************
6301 
6302 
6303 //*************************************************************************************************
6312 template< typename MT // Type of the dense matrix
6313  , typename... CRAs > // Compile time row arguments
6314 inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6316 {
6317  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6318  return matrix_.cbegin( idx(i) );
6319 }
6321 //*************************************************************************************************
6322 
6323 
6324 //*************************************************************************************************
6333 template< typename MT // Type of the dense matrix
6334  , typename... CRAs > // Compile time row arguments
6335 inline typename Rows<MT,false,true,true,CRAs...>::Iterator
6337 {
6338  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6339  return matrix_.end( idx(i) );
6340 }
6342 //*************************************************************************************************
6343 
6344 
6345 //*************************************************************************************************
6354 template< typename MT // Type of the dense matrix
6355  , typename... CRAs > // Compile time row arguments
6356 inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6357  Rows<MT,false,true,true,CRAs...>::end( size_t i ) const
6358 {
6359  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6360  return matrix_.cend( idx(i) );
6361 }
6363 //*************************************************************************************************
6364 
6365 
6366 //*************************************************************************************************
6375 template< typename MT // Type of the dense matrix
6376  , typename... CRAs > // Compile time row arguments
6377 inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6378  Rows<MT,false,true,true,CRAs...>::cend( size_t i ) const
6379 {
6380  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6381  return matrix_.cend( idx(i) );
6382 }
6384 //*************************************************************************************************
6385 
6386 
6387 
6388 
6389 //=================================================================================================
6390 //
6391 // ASSIGNMENT OPERATORS
6392 //
6393 //=================================================================================================
6394 
6395 //*************************************************************************************************
6406 template< typename MT // Type of the dense matrix
6407  , typename... CRAs > // Compile time row arguments
6408 inline Rows<MT,false,true,true,CRAs...>&
6409  Rows<MT,false,true,true,CRAs...>::operator=( const ElementType& rhs )
6410 {
6411  for( size_t i=0UL; i<rows(); ++i ) {
6412  column( matrix_, idx(i), unchecked ) = rhs;
6413  }
6414 
6415  return *this;
6416 }
6418 //*************************************************************************************************
6419 
6420 
6421 
6422 
6423 //=================================================================================================
6424 //
6425 // UTILITY FUNCTIONS
6426 //
6427 //=================================================================================================
6428 
6429 //*************************************************************************************************
6435 template< typename MT // Type of the dense matrix
6436  , typename... CRAs > // Compile time row arguments
6437 inline MT& Rows<MT,false,true,true,CRAs...>::operand() noexcept
6438 {
6439  return matrix_;
6440 }
6442 //*************************************************************************************************
6443 
6444 
6445 //*************************************************************************************************
6451 template< typename MT // Type of the dense matrix
6452  , typename... CRAs > // Compile time row arguments
6453 inline const MT& Rows<MT,false,true,true,CRAs...>::operand() const noexcept
6454 {
6455  return matrix_;
6456 }
6458 //*************************************************************************************************
6459 
6460 
6461 //*************************************************************************************************
6467 template< typename MT // Type of the dense matrix
6468  , typename... CRAs > // Compile time row arguments
6469 inline size_t Rows<MT,false,true,true,CRAs...>::columns() const noexcept
6470 {
6471  return matrix_.columns();
6472 }
6474 //*************************************************************************************************
6475 
6476 
6477 //*************************************************************************************************
6486 template< typename MT // Type of the dense matrix
6487  , typename... CRAs > // Compile time row arguments
6488 inline size_t Rows<MT,false,true,true,CRAs...>::spacing() const noexcept
6489 {
6490  return matrix_.spacing();
6491 }
6493 //*************************************************************************************************
6494 
6495 
6496 //*************************************************************************************************
6502 template< typename MT // Type of the dense matrix
6503  , typename... CRAs > // Compile time row arguments
6504 inline size_t Rows<MT,false,true,true,CRAs...>::capacity() const noexcept
6505 {
6506  return rows() * columns();
6507 }
6509 //*************************************************************************************************
6510 
6511 
6512 //*************************************************************************************************
6521 template< typename MT // Type of the dense matrix
6522  , typename... CRAs > // Compile time row arguments
6523 inline size_t Rows<MT,false,true,true,CRAs...>::capacity( size_t i ) const noexcept
6524 {
6525  MAYBE_UNUSED( i );
6526 
6527  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6528 
6529  return columns();
6530 }
6532 //*************************************************************************************************
6533 
6534 
6535 //*************************************************************************************************
6541 template< typename MT // Type of the dense matrix
6542  , typename... CRAs > // Compile time row arguments
6543 inline size_t Rows<MT,false,true,true,CRAs...>::nonZeros() const
6544 {
6545  size_t nonzeros( 0UL );
6546 
6547  for( size_t i=0UL; i<rows(); ++i ) {
6548  nonzeros += matrix_.nonZeros( idx(i) );
6549  }
6550 
6551  return nonzeros;
6552 }
6554 //*************************************************************************************************
6555 
6556 
6557 //*************************************************************************************************
6566 template< typename MT // Type of the dense matrix
6567  , typename... CRAs > // Compile time row arguments
6568 inline size_t Rows<MT,false,true,true,CRAs...>::nonZeros( size_t i ) const
6569 {
6570  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6571 
6572  return matrix_.nonZeros( idx(i) );
6573 }
6575 //*************************************************************************************************
6576 
6577 
6578 //*************************************************************************************************
6584 template< typename MT // Type of the dense matrix
6585  , typename... CRAs > // Compile time row arguments
6587 {
6588  for( size_t i=0UL; i<rows(); ++i ) {
6589  matrix_.reset( idx(i) );
6590  }
6591 }
6593 //*************************************************************************************************
6594 
6595 
6596 //*************************************************************************************************
6605 template< typename MT // Type of the dense matrix
6606  , typename... CRAs > // Compile time row arguments
6607 inline void Rows<MT,false,true,true,CRAs...>::reset( size_t i )
6608 {
6609  matrix_.reset( idx(i) );
6610 }
6612 //*************************************************************************************************
6613 
6614 
6615 
6616 
6617 //=================================================================================================
6618 //
6619 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6620 //
6621 //=================================================================================================
6622 
6623 //*************************************************************************************************
6634 template< typename MT // Type of the dense matrix
6635  , typename... CRAs > // Compile time row arguments
6636 template< typename Other > // Data type of the foreign expression
6637 inline bool Rows<MT,false,true,true,CRAs...>::canAlias( const Other* alias ) const noexcept
6638 {
6639  return matrix_.isAliased( alias );
6640 }
6642 //*************************************************************************************************
6643 
6644 
6645 //*************************************************************************************************
6657 template< typename MT // Type of the dense matrix
6658  , typename... CRAs > // Compile time row arguments
6659 template< typename MT2 // Data type of the foreign dense row selection
6660  , bool SO2 // Storage order of the foreign dense row selection
6661  , bool SF2 // Symmetry flag of the foreign dense row selection
6662  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
6663 inline bool
6664  Rows<MT,false,true,true,CRAs...>::canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
6665 {
6666  return matrix_.isAliased( &alias->matrix_ );
6667 }
6669 //*************************************************************************************************
6670 
6671 
6672 //*************************************************************************************************
6683 template< typename MT // Type of the dense matrix
6684  , typename... CRAs > // Compile time row arguments
6685 template< typename Other > // Data type of the foreign expression
6686 inline bool Rows<MT,false,true,true,CRAs...>::isAliased( const Other* alias ) const noexcept
6687 {
6688  return matrix_.isAliased( alias );
6689 }
6691 //*************************************************************************************************
6692 
6693 
6694 //*************************************************************************************************
6706 template< typename MT // Type of the dense matrix
6707  , typename... CRAs > // Compile time row arguments
6708 template< typename MT2 // Data type of the foreign dense row selection
6709  , bool SO2 // Storage order of the foreign dense row selection
6710  , bool SF2 // Symmetry flag of the foreign dense row selection
6711  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
6712 inline bool
6713  Rows<MT,false,true,true,CRAs...>::isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
6714 {
6715  return matrix_.isAliased( &alias->matrix_ );
6716 }
6718 //*************************************************************************************************
6719 
6720 
6721 //*************************************************************************************************
6731 template< typename MT // Type of the dense matrix
6732  , typename... CRAs > // Compile time row arguments
6733 inline bool Rows<MT,false,true,true,CRAs...>::isAligned() const noexcept
6734 {
6735  return matrix_.isAligned();
6736 }
6738 //*************************************************************************************************
6739 
6740 
6741 //*************************************************************************************************
6752 template< typename MT // Type of the dense matrix
6753  , typename... CRAs > // Compile time row arguments
6754 inline bool Rows<MT,false,true,true,CRAs...>::canSMPAssign() const noexcept
6755 {
6756  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
6757 }
6759 //*************************************************************************************************
6760 
6761 
6762 //*************************************************************************************************
6777 template< typename MT // Type of the dense matrix
6778  , typename... CRAs > // Compile time row arguments
6779 BLAZE_ALWAYS_INLINE typename Rows<MT,false,true,true,CRAs...>::SIMDType
6780  Rows<MT,false,true,true,CRAs...>::load( size_t i, size_t j ) const noexcept
6781 {
6782  return matrix_.load( j, idx(i) );
6783 }
6785 //*************************************************************************************************
6786 
6787 
6788 //*************************************************************************************************
6803 template< typename MT // Type of the dense matrix
6804  , typename... CRAs > // Compile time row arguments
6805 BLAZE_ALWAYS_INLINE typename Rows<MT,false,true,true,CRAs...>::SIMDType
6806  Rows<MT,false,true,true,CRAs...>::loada( size_t i, size_t j ) const noexcept
6807 {
6808  return matrix_.loada( j, idx(i) );
6809 }
6811 //*************************************************************************************************
6812 
6813 
6814 //*************************************************************************************************
6829 template< typename MT // Type of the dense matrix
6830  , typename... CRAs > // Compile time row arguments
6831 BLAZE_ALWAYS_INLINE typename Rows<MT,false,true,true,CRAs...>::SIMDType
6832  Rows<MT,false,true,true,CRAs...>::loadu( size_t i, size_t j ) const noexcept
6833 {
6834  return matrix_.loadu( j, idx(i) );
6835 }
6837 //*************************************************************************************************
6838 
6839 } // namespace blaze
6840 
6841 #endif
Constraint on the data type.
#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
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
Header file for kernel specific block sizes.
Header file for the Schur product trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ROWS_TYPE(T)
Constraint on the data type.In case the given data type T is a row selection type (i....
Definition: Rows.h:81
#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 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
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:170
Header file for the View base class.
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i....
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type,...
Definition: DenseMatrix.h:61
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:332
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
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
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
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e....
Definition: Submatrix.h:81
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
#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
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a symmetric matrix type,...
Definition: Symmetric.h:60
Header file for the reset shim.
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:187
Constraints on the storage order of matrix types.
#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
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
Header file for the RequiresEvaluation type trait.
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
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
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
Constraint on the data type.
Constraint on the data type.
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:253
Constraint on the data type.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
Header file for the DisableIf class template.
Header file for the IsStrictlyUpper type trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1361
Header file for the If class template.
Header file for the implementation of a vector representation of an initializer list.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
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
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:187
#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
Header file for the HasSIMDAdd type trait.
Header file for the DenseMatrix base class.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:370
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:446
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
Header file for all SIMD functionality.
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
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type,...
Definition: Vectorizable.h:61
Header file for the exception macros of the math module.
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.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Constraint on the data type.
Header file for the IsSIMDCombinable type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type,...
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
Header file for run time assertion macros.
Header file for the addition trait.
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
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
Header file for the cache size of the target architecture.
#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
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
Constraints on the storage order of matrix types.
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:408
Header file for the HasMutableDataAccess type trait.
#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 IsReference type trait.
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
constexpr const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:718
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
Header file for the rows trait.
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:74
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
Constraint on the data type.
Header file for the implementation of the RowsData class template.
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:188
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type,...
Definition: Hermitian.h:79
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
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
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.The IsDiagonal_v variable template provides...
Definition: IsDiagonal.h:148
Header file for the implementation of the Rows base template.
Header file for the IsRestricted type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#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
constexpr bool IsSparseMatrix_v
Auxiliary variable template for the IsSparseMatrix type trait.The IsSparseMatrix_v variable template ...
Definition: IsSparseMatrix.h:138
Header file for the IsExpression type trait class.
Constraint on the data type.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825