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>
94 #include <blaze/util/DisableIf.h>
95 #include <blaze/util/EnableIf.h>
96 #include <blaze/util/mpl/If.h>
97 #include <blaze/util/TypeList.h>
98 #include <blaze/util/Types.h>
101 #include <blaze/util/Unused.h>
102 
103 
104 namespace blaze {
105 
106 //=================================================================================================
107 //
108 // CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR DENSE MATRICES
109 //
110 //=================================================================================================
111 
112 //*************************************************************************************************
120 template< typename MT // Type of the dense matrix
121  , bool SF // Symmetry flag
122  , typename... CRAs > // Compile time row arguments
123 class Rows<MT,true,true,SF,CRAs...>
124  : public View< DenseMatrix< Rows<MT,true,true,SF,CRAs...>, false > >
125  , private RowsData<CRAs...>
126 {
127  private:
128  //**Type definitions****************************************************************************
129  using DataType = RowsData<CRAs...>;
130  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
131  //**********************************************************************************************
132 
133  //**Compile time flags**************************************************************************
134  using DataType::N;
135  //**********************************************************************************************
136 
137  //**********************************************************************************************
139  template< typename MT1, typename MT2 >
140  static constexpr bool EnforceEvaluation_v =
141  ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
142  //**********************************************************************************************
143 
144  public:
145  //**Type definitions****************************************************************************
147  using This = Rows<MT,true,true,SF,CRAs...>;
148 
149  using BaseType = DenseMatrix<This,false>;
150  using ViewedType = MT;
151  using ResultType = RowsTrait_t<MT,N>;
152  using OppositeType = OppositeType_t<ResultType>;
153  using TransposeType = TransposeType_t<ResultType>;
154  using ElementType = ElementType_t<MT>;
155  using SIMDType = SIMDTrait_t<ElementType>;
156  using ReturnType = ReturnType_t<MT>;
157  using CompositeType = const Rows&;
158 
160  using ConstReference = ConstReference_t<MT>;
161 
163  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
164 
166  using ConstPointer = ConstPointer_t<MT>;
167 
169  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
170 
172  using ConstIterator = ConstIterator_t<MT>;
173 
175  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
176  //**********************************************************************************************
177 
178  //**Compilation flags***************************************************************************
180  static constexpr bool simdEnabled = MT::simdEnabled;
181 
183  static constexpr bool smpAssignable = MT::smpAssignable;
184  //**********************************************************************************************
185 
186  //**Constructors********************************************************************************
189  template< typename... RRAs >
190  explicit inline Rows( MT& matrix, RRAs... args );
191 
192  Rows( const Rows& ) = default;
193  Rows( Rows&& ) = default;
195  //**********************************************************************************************
196 
197  //**Destructor**********************************************************************************
200  ~Rows() = default;
202  //**********************************************************************************************
203 
204  //**Data access functions***********************************************************************
207  inline Reference operator()( size_t i, size_t j );
208  inline ConstReference operator()( size_t i, size_t j ) const;
209  inline Reference at( size_t i, size_t j );
210  inline ConstReference at( size_t i, size_t j ) const;
211  inline Pointer data () noexcept;
212  inline ConstPointer data () const noexcept;
213  inline Pointer data ( size_t i ) noexcept;
214  inline ConstPointer data ( size_t i ) const noexcept;
215  inline Iterator begin ( size_t i );
216  inline ConstIterator begin ( size_t i ) const;
217  inline ConstIterator cbegin( size_t i ) const;
218  inline Iterator end ( size_t i );
219  inline ConstIterator end ( size_t i ) const;
220  inline ConstIterator cend ( size_t i ) const;
222  //**********************************************************************************************
223 
224  //**Assignment operators************************************************************************
227  inline Rows& operator=( const ElementType& rhs );
228  inline Rows& operator=( initializer_list< initializer_list<ElementType> > list );
229  inline Rows& operator=( const Rows& rhs );
230 
231  template< typename MT2, bool SO2 >
232  inline Rows& operator=( const Matrix<MT2,SO2>& rhs );
233 
234  template< typename MT2, bool SO2 >
235  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
236  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
237 
238  template< typename MT2, bool SO2 >
239  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
240  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
241 
242  template< typename MT2, bool SO2 >
243  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
244  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
245 
246  template< typename MT2, bool SO2 >
247  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
248  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
249 
250  template< typename MT2, bool SO2 >
251  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
252  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
253 
254  template< typename MT2, bool SO2 >
255  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
256  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
258  //**********************************************************************************************
259 
260  //**Utility functions***************************************************************************
263  using DataType::idx;
264  using DataType::idces;
265  using DataType::rows;
266 
267  inline MT& operand() noexcept;
268  inline const MT& operand() const noexcept;
269 
270  inline size_t columns() const noexcept;
271  inline size_t spacing() const noexcept;
272  inline size_t capacity() const noexcept;
273  inline size_t capacity( size_t i ) const noexcept;
274  inline size_t nonZeros() const;
275  inline size_t nonZeros( size_t i ) const;
276  inline void reset();
277  inline void reset( size_t i );
279  //**********************************************************************************************
280 
281  //**Numeric functions***************************************************************************
284  inline Rows& transpose();
285  inline Rows& ctranspose();
286 
287  template< typename Other > inline Rows& scale( const Other& scalar );
289  //**********************************************************************************************
290 
291  private:
292  //**********************************************************************************************
294  template< typename MT2 >
295  static constexpr bool VectorizedAssign_v =
296  ( useOptimizedKernels &&
297  simdEnabled && MT2::simdEnabled &&
299  //**********************************************************************************************
300 
301  //**********************************************************************************************
303  template< typename MT2 >
304  static constexpr bool VectorizedAddAssign_v =
305  ( useOptimizedKernels &&
306  simdEnabled && MT2::simdEnabled &&
309  !IsDiagonal_v<MT2> );
310  //**********************************************************************************************
311 
312  //**********************************************************************************************
314  template< typename MT2 >
315  static constexpr bool VectorizedSubAssign_v =
316  ( useOptimizedKernels &&
317  simdEnabled && MT2::simdEnabled &&
320  !IsDiagonal_v<MT2> );
321  //**********************************************************************************************
322 
323  //**********************************************************************************************
325  template< typename MT2 >
326  static constexpr bool VectorizedSchurAssign_v =
327  ( useOptimizedKernels &&
328  simdEnabled && MT2::simdEnabled &&
331  //**********************************************************************************************
332 
333  //**SIMD properties*****************************************************************************
335  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
336  //**********************************************************************************************
337 
338  public:
339  //**Expression template evaluation functions****************************************************
342  template< typename Other >
343  inline bool canAlias( const Other* alias ) const noexcept;
344 
345  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
346  inline bool canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
347 
348  template< typename Other >
349  inline bool isAliased( const Other* alias ) const noexcept;
350 
351  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
352  inline bool isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
353 
354  inline bool isAligned () const noexcept;
355  inline bool canSMPAssign() const noexcept;
356 
357  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
358  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
359  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
360 
361  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
362  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
363  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
364  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
365 
366  template< typename MT2 >
367  inline auto assign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT2> >;
368 
369  template< typename MT2 >
370  inline auto assign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT2> >;
371 
372  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
373 
374  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
375  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
376 
377  template< typename MT2 >
378  inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT2> >;
379 
380  template< typename MT2 >
381  inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT2> >;
382 
383  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
384  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
385  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
386 
387  template< typename MT2 >
388  inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT2> >;
389 
390  template< typename MT2 >
391  inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT2> >;
392 
393  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
394  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
395  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
396 
397  template< typename MT2 >
398  inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT2> >;
399 
400  template< typename MT2 >
401  inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT2> >;
402 
403  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
404  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
405  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
407  //**********************************************************************************************
408 
409  private:
410  //**Member variables****************************************************************************
413  Operand matrix_;
414 
415  //**********************************************************************************************
416 
417  //**Friend declarations*************************************************************************
418  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CRAs2 > friend class Rows;
419  //**********************************************************************************************
420 
421  //**Compile time checks*************************************************************************
430  //**********************************************************************************************
431 };
433 //*************************************************************************************************
434 
435 
436 
437 
438 //=================================================================================================
439 //
440 // CONSTRUCTORS
441 //
442 //=================================================================================================
443 
444 //*************************************************************************************************
457 template< typename MT // Type of the dense matrix
458  , bool SF // Symmetry flag
459  , typename... CRAs > // Compile time row arguments
460 template< typename... RRAs > // Runtime row arguments
461 inline Rows<MT,true,true,SF,CRAs...>::Rows( MT& matrix, RRAs... args )
462  : DataType( args... ) // Base class initialization
463  , matrix_ ( matrix ) // The matrix containing the rows
464 {
465  if( !Contains_v< TypeList<RRAs...>, Unchecked > ) {
466  for( size_t i=0UL; i<rows(); ++i ) {
467  if( matrix_.rows() <= idx(i) ) {
468  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
469  }
470  }
471  }
472 }
474 //*************************************************************************************************
475 
476 
477 
478 
479 //=================================================================================================
480 //
481 // DATA ACCESS FUNCTIONS
482 //
483 //=================================================================================================
484 
485 //*************************************************************************************************
496 template< typename MT // Type of the dense matrix
497  , bool SF // Symmetry flag
498  , typename... CRAs > // Compile time row arguments
499 inline typename Rows<MT,true,true,SF,CRAs...>::Reference
500  Rows<MT,true,true,SF,CRAs...>::operator()( size_t i, size_t j )
501 {
502  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
503  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
504 
505  return matrix_(idx(i),j);
506 }
508 //*************************************************************************************************
509 
510 
511 //*************************************************************************************************
522 template< typename MT // Type of the dense matrix
523  , bool SF // Symmetry flag
524  , typename... CRAs > // Compile time row arguments
525 inline typename Rows<MT,true,true,SF,CRAs...>::ConstReference
526  Rows<MT,true,true,SF,CRAs...>::operator()( size_t i, size_t j ) const
527 {
528  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
529  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
530 
531  return const_cast<const MT&>( matrix_ )(idx(i),j);
532 }
534 //*************************************************************************************************
535 
536 
537 //*************************************************************************************************
549 template< typename MT // Type of the dense matrix
550  , bool SF // Symmetry flag
551  , typename... CRAs > // Compile time row arguments
552 inline typename Rows<MT,true,true,SF,CRAs...>::Reference
553  Rows<MT,true,true,SF,CRAs...>::at( size_t i, size_t j )
554 {
555  if( i >= rows() ) {
556  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
557  }
558  if( j >= columns() ) {
559  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
560  }
561  return (*this)(i,j);
562 }
564 //*************************************************************************************************
565 
566 
567 //*************************************************************************************************
579 template< typename MT // Type of the dense matrix
580  , bool SF // Symmetry flag
581  , typename... CRAs > // Compile time row arguments
582 inline typename Rows<MT,true,true,SF,CRAs...>::ConstReference
583  Rows<MT,true,true,SF,CRAs...>::at( size_t i, size_t j ) const
584 {
585  if( i >= rows() ) {
586  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
587  }
588  if( j >= columns() ) {
589  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
590  }
591  return (*this)(i,j);
592 }
594 //*************************************************************************************************
595 
596 
597 //*************************************************************************************************
607 template< typename MT // Type of the dense matrix
608  , bool SF // Symmetry flag
609  , typename... CRAs > // Compile time row arguments
610 inline typename Rows<MT,true,true,SF,CRAs...>::Pointer
612 {
613  return matrix_.data( idx(0UL) );
614 }
616 //*************************************************************************************************
617 
618 
619 //*************************************************************************************************
629 template< typename MT // Type of the dense matrix
630  , bool SF // Symmetry flag
631  , typename... CRAs > // Compile time row arguments
632 inline typename Rows<MT,true,true,SF,CRAs...>::ConstPointer
633  Rows<MT,true,true,SF,CRAs...>::data() const noexcept
634 {
635  return matrix_.data( idx(0UL) );
636 }
638 //*************************************************************************************************
639 
640 
641 //*************************************************************************************************
650 template< typename MT // Type of the dense matrix
651  , bool SF // Symmetry flag
652  , typename... CRAs > // Compile time row arguments
653 inline typename Rows<MT,true,true,SF,CRAs...>::Pointer
654  Rows<MT,true,true,SF,CRAs...>::data( size_t i ) noexcept
655 {
656  return matrix_.data( idx(i) );
657 }
659 //*************************************************************************************************
660 
661 
662 //*************************************************************************************************
671 template< typename MT // Type of the dense matrix
672  , bool SF // Symmetry flag
673  , typename... CRAs > // Compile time row arguments
674 inline typename Rows<MT,true,true,SF,CRAs...>::ConstPointer
675  Rows<MT,true,true,SF,CRAs...>::data( size_t i ) const noexcept
676 {
677  return matrix_.data( idx(i) );
678 }
680 //*************************************************************************************************
681 
682 
683 //*************************************************************************************************
692 template< typename MT // Type of the dense matrix
693  , bool SF // Symmetry flag
694  , typename... CRAs > // Compile time row arguments
695 inline typename Rows<MT,true,true,SF,CRAs...>::Iterator
697 {
698  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
699  return matrix_.begin( idx(i) );
700 }
702 //*************************************************************************************************
703 
704 
705 //*************************************************************************************************
714 template< typename MT // Type of the dense matrix
715  , bool SF // Symmetry flag
716  , typename... CRAs > // Compile time row arguments
717 inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
718  Rows<MT,true,true,SF,CRAs...>::begin( size_t i ) const
719 {
720  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
721  return matrix_.cbegin( idx(i) );
722 }
724 //*************************************************************************************************
725 
726 
727 //*************************************************************************************************
736 template< typename MT // Type of the dense matrix
737  , bool SF // Symmetry flag
738  , typename... CRAs > // Compile time row arguments
739 inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
740  Rows<MT,true,true,SF,CRAs...>::cbegin( size_t i ) const
741 {
742  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
743  return matrix_.cbegin( idx(i) );
744 }
746 //*************************************************************************************************
747 
748 
749 //*************************************************************************************************
758 template< typename MT // Type of the dense matrix
759  , bool SF // Symmetry flag
760  , typename... CRAs > // Compile time row arguments
761 inline typename Rows<MT,true,true,SF,CRAs...>::Iterator
763 {
764  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
765  return matrix_.end( idx(i) );
766 }
768 //*************************************************************************************************
769 
770 
771 //*************************************************************************************************
780 template< typename MT // Type of the dense matrix
781  , bool SF // Symmetry flag
782  , typename... CRAs > // Compile time row arguments
783 inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
784  Rows<MT,true,true,SF,CRAs...>::end( size_t i ) const
785 {
786  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
787  return matrix_.cend( idx(i) );
788 }
790 //*************************************************************************************************
791 
792 
793 //*************************************************************************************************
802 template< typename MT // Type of the dense matrix
803  , bool SF // Symmetry flag
804  , typename... CRAs > // Compile time row arguments
805 inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
806  Rows<MT,true,true,SF,CRAs...>::cend( size_t i ) const
807 {
808  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
809  return matrix_.cend( idx(i) );
810 }
812 //*************************************************************************************************
813 
814 
815 
816 
817 //=================================================================================================
818 //
819 // ASSIGNMENT OPERATORS
820 //
821 //=================================================================================================
822 
823 //*************************************************************************************************
834 template< typename MT // Type of the dense matrix
835  , bool SF // Symmetry flag
836  , typename... CRAs > // Compile time row arguments
837 inline Rows<MT,true,true,SF,CRAs...>&
838  Rows<MT,true,true,SF,CRAs...>::operator=( const ElementType& rhs )
839 {
840  for( size_t i=0UL; i<rows(); ++i ) {
841  row( matrix_, idx(i), unchecked ) = rhs;
842  }
843 
844  return *this;
845 }
847 //*************************************************************************************************
848 
849 
850 //*************************************************************************************************
866 template< typename MT // Type of the dense matrix
867  , bool SF // Symmetry flag
868  , typename... CRAs > // Compile time row arguments
869 inline Rows<MT,true,true,SF,CRAs...>&
870  Rows<MT,true,true,SF,CRAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
871 {
874 
875  if( list.size() != rows() ) {
876  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row selection" );
877  }
878 
879  if( IsRestricted_v<MT> ) {
880  size_t i( 0UL );
881  for( const auto& rowList : list ) {
882  const InitializerVector<ElementType> tmp( rowList, columns() );
883  if( !tryAssign( row( matrix_, idx(i), unchecked ), tmp, 0UL ) ){
884  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
885  }
886  ++i;
887  }
888  }
889 
890  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
891  size_t i( 0UL );
892 
893  for( const auto& rowList : list ) {
894  std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
895  ++i;
896  }
897 
898  return *this;
899 }
901 //*************************************************************************************************
902 
903 
904 //*************************************************************************************************
919 template< typename MT // Type of the dense matrix
920  , bool SF // Symmetry flag
921  , typename... CRAs > // Compile time row arguments
922 inline Rows<MT,true,true,SF,CRAs...>&
923  Rows<MT,true,true,SF,CRAs...>::operator=( const Rows& rhs )
924 {
927 
930 
931  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
932  return *this;
933 
934  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
935  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
936  }
937 
938  if( IsRestricted_v<MT> ) {
939  for( size_t i=0UL; i<rows(); ++i ) {
940  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( rhs, i, unchecked ), 0UL ) ) {
941  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
942  }
943  }
944  }
945 
946  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
947 
948  if( rhs.canAlias( &matrix_ ) ) {
949  const ResultType tmp( rhs );
950  smpAssign( left, tmp );
951  }
952  else {
953  smpAssign( left, rhs );
954  }
955 
956  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
957 
958  return *this;
959 }
961 //*************************************************************************************************
962 
963 
964 //*************************************************************************************************
979 template< typename MT // Type of the dense matrix
980  , bool SF // Symmetry flag
981  , typename... CRAs > // Compile time row arguments
982 template< typename MT2 // Type of the right-hand side matrix
983  , bool SO2 > // Storage order of the right-hand side matrix
984 inline Rows<MT,true,true,SF,CRAs...>&
985  Rows<MT,true,true,SF,CRAs...>::operator=( const Matrix<MT2,SO2>& rhs )
986 {
989 
991 
992  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
993  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
994  }
995 
996  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
997  Right right( ~rhs );
998 
999  if( IsRestricted_v<MT> ) {
1000  for( size_t i=0UL; i<rows(); ++i ) {
1001  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( right, i, unchecked ), 0UL ) ) {
1002  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1003  }
1004  }
1005  }
1006 
1007  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1008 
1009  if( IsSparseMatrix_v<MT2> ) {
1010  reset();
1011  }
1012 
1013  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
1014  const ResultType_t<MT2> tmp( right );
1015  smpAssign( left, tmp );
1016  }
1017  else {
1018  smpAssign( left, right );
1019  }
1020 
1021  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1022 
1023  return *this;
1024 }
1026 //*************************************************************************************************
1027 
1028 
1029 //*************************************************************************************************
1043 template< typename MT // Type of the dense matrix
1044  , bool SF // Symmetry flag
1045  , typename... CRAs > // Compile time row arguments
1046 template< typename MT2 // Type of the right-hand side matrix
1047  , bool SO2 > // Storage order of the right-hand side matrix
1048 inline auto Rows<MT,true,true,SF,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1049  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1050 {
1053 
1056  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1057 
1058  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1059 
1062 
1063  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1064  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1065  }
1066 
1067  if( IsRestricted_v<MT> ) {
1068  for( size_t i=0UL; i<rows(); ++i ) {
1069  if( !tryAddAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
1070  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1071  }
1072  }
1073  }
1074 
1075  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1076 
1077  if( (~rhs).canAlias( &matrix_ ) ) {
1078  const AddType tmp( *this + (~rhs) );
1079  smpAssign( left, tmp );
1080  }
1081  else {
1082  smpAddAssign( left, ~rhs );
1083  }
1084 
1085  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1086 
1087  return *this;
1088 }
1090 //*************************************************************************************************
1091 
1092 
1093 //*************************************************************************************************
1107 template< typename MT // Type of the dense matrix
1108  , bool SF // Symmetry flag
1109  , typename... CRAs > // Compile time row arguments
1110 template< typename MT2 // Type of the right-hand side matrix
1111  , bool SO2 > // Storage order of the right-hand side matrix
1112 inline auto Rows<MT,true,true,SF,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1113  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1114 {
1117 
1120  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1121 
1122  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1123 
1126 
1127  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1128  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1129  }
1130 
1131  const AddType tmp( *this + (~rhs) );
1132 
1133  if( IsRestricted_v<MT> ) {
1134  for( size_t i=0UL; i<rows(); ++i ) {
1135  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
1136  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1137  }
1138  }
1139  }
1140 
1141  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1142 
1143  smpAssign( left, tmp );
1144 
1145  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1146 
1147  return *this;
1148 }
1150 //*************************************************************************************************
1151 
1152 
1153 //*************************************************************************************************
1167 template< typename MT // Type of the dense matrix
1168  , bool SF // Symmetry flag
1169  , typename... CRAs > // Compile time row arguments
1170 template< typename MT2 // Type of the right-hand side matrix
1171  , bool SO2 > // Storage order of the right-hand side matrix
1172 inline auto Rows<MT,true,true,SF,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1173  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1174 {
1177 
1180  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1181 
1182  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1183 
1186 
1187  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1188  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1189  }
1190 
1191  if( IsRestricted_v<MT> ) {
1192  for( size_t i=0UL; i<rows(); ++i ) {
1193  if( !trySubAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
1194  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1195  }
1196  }
1197  }
1198 
1199  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1200 
1201  if( (~rhs).canAlias( &matrix_ ) ) {
1202  const SubType tmp( *this - (~rhs ) );
1203  smpAssign( left, tmp );
1204  }
1205  else {
1206  smpSubAssign( left, ~rhs );
1207  }
1208 
1209  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1210 
1211  return *this;
1212 }
1214 //*************************************************************************************************
1215 
1216 
1217 //*************************************************************************************************
1231 template< typename MT // Type of the dense matrix
1232  , bool SF // Symmetry flag
1233  , typename... CRAs > // Compile time row arguments
1234 template< typename MT2 // Type of the right-hand side matrix
1235  , bool SO2 > // Storage order of the right-hand side matrix
1236 inline auto Rows<MT,true,true,SF,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1237  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1238 {
1241 
1244  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1245 
1246  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1247 
1250 
1251  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1252  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1253  }
1254 
1255  const SubType tmp( *this - (~rhs) );
1256 
1257  if( IsRestricted_v<MT> ) {
1258  for( size_t i=0UL; i<rows(); ++i ) {
1259  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
1260  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1261  }
1262  }
1263  }
1264 
1265  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1266 
1267  smpAssign( left, tmp );
1268 
1269  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1270 
1271  return *this;
1272 }
1274 //*************************************************************************************************
1275 
1276 
1277 //*************************************************************************************************
1291 template< typename MT // Type of the dense matrix
1292  , bool SF // Symmetry flag
1293  , typename... CRAs > // Compile time row arguments
1294 template< typename MT2 // Type of the right-hand side matrix
1295  , bool SO2 > // Storage order of the right-hand side matrix
1296 inline auto Rows<MT,true,true,SF,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1297  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1298 {
1301 
1304  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1305 
1306  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1307 
1309 
1310  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1311  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1312  }
1313 
1314  if( IsRestricted_v<MT> ) {
1315  for( size_t i=0UL; i<rows(); ++i ) {
1316  if( !tryMultAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
1317  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1318  }
1319  }
1320  }
1321 
1322  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1323 
1324  if( (~rhs).canAlias( &matrix_ ) ) {
1325  const SchurType tmp( *this % (~rhs) );
1326  if( IsSparseMatrix_v<SchurType> )
1327  reset();
1328  smpAssign( left, tmp );
1329  }
1330  else {
1331  smpSchurAssign( left, ~rhs );
1332  }
1333 
1334  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1335 
1336  return *this;
1337 }
1339 //*************************************************************************************************
1340 
1341 
1342 //*************************************************************************************************
1356 template< typename MT // Type of the dense matrix
1357  , bool SF // Symmetry flag
1358  , typename... CRAs > // Compile time row arguments
1359 template< typename MT2 // Type of the right-hand side matrix
1360  , bool SO2 > // Storage order of the right-hand side matrix
1361 inline auto Rows<MT,true,true,SF,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1362  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1363 {
1366 
1369  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1370 
1371  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1372 
1374 
1375  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1376  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1377  }
1378 
1379  const SchurType tmp( *this % (~rhs) );
1380 
1381  if( IsRestricted_v<MT> ) {
1382  for( size_t i=0UL; i<rows(); ++i ) {
1383  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
1384  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1385  }
1386  }
1387  }
1388 
1389  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1390 
1391  if( IsSparseMatrix_v<SchurType> ) {
1392  reset();
1393  }
1394 
1395  smpAssign( left, tmp );
1396 
1397  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1398 
1399  return *this;
1400 }
1402 //*************************************************************************************************
1403 
1404 
1405 
1406 
1407 //=================================================================================================
1408 //
1409 // UTILITY FUNCTIONS
1410 //
1411 //=================================================================================================
1412 
1413 //*************************************************************************************************
1419 template< typename MT // Type of the dense matrix
1420  , bool SF // Symmetry flag
1421  , typename... CRAs > // Compile time row arguments
1422 inline MT& Rows<MT,true,true,SF,CRAs...>::operand() noexcept
1423 {
1424  return matrix_;
1425 }
1427 //*************************************************************************************************
1428 
1429 
1430 //*************************************************************************************************
1436 template< typename MT // Type of the dense matrix
1437  , bool SF // Symmetry flag
1438  , typename... CRAs > // Compile time row arguments
1439 inline const MT& Rows<MT,true,true,SF,CRAs...>::operand() const noexcept
1440 {
1441  return matrix_;
1442 }
1444 //*************************************************************************************************
1445 
1446 
1447 //*************************************************************************************************
1453 template< typename MT // Type of the dense matrix
1454  , bool SF // Symmetry flag
1455  , typename... CRAs > // Compile time row arguments
1456 inline size_t Rows<MT,true,true,SF,CRAs...>::columns() const noexcept
1457 {
1458  return matrix_.columns();
1459 }
1461 //*************************************************************************************************
1462 
1463 
1464 //*************************************************************************************************
1473 template< typename MT // Type of the dense matrix
1474  , bool SF // Symmetry flag
1475  , typename... CRAs > // Compile time row arguments
1476 inline size_t Rows<MT,true,true,SF,CRAs...>::spacing() const noexcept
1477 {
1478  return matrix_.spacing();
1479 }
1481 //*************************************************************************************************
1482 
1483 
1484 //*************************************************************************************************
1490 template< typename MT // Type of the dense matrix
1491  , bool SF // Symmetry flag
1492  , typename... CRAs > // Compile time row arguments
1493 inline size_t Rows<MT,true,true,SF,CRAs...>::capacity() const noexcept
1494 {
1495  return rows() * columns();
1496 }
1498 //*************************************************************************************************
1499 
1500 
1501 //*************************************************************************************************
1510 template< typename MT // Type of the dense matrix
1511  , bool SF // Symmetry flag
1512  , typename... CRAs > // Compile time row arguments
1513 inline size_t Rows<MT,true,true,SF,CRAs...>::capacity( size_t i ) const noexcept
1514 {
1515  UNUSED_PARAMETER( i );
1516 
1517  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1518 
1519  return columns();
1520 }
1522 //*************************************************************************************************
1523 
1524 
1525 //*************************************************************************************************
1531 template< typename MT // Type of the dense matrix
1532  , bool SF // Symmetry flag
1533  , typename... CRAs > // Compile time row arguments
1534 inline size_t Rows<MT,true,true,SF,CRAs...>::nonZeros() const
1535 {
1536  size_t nonzeros( 0UL );
1537 
1538  for( size_t i=0UL; i<rows(); ++i ) {
1539  nonzeros += matrix_.nonZeros( idx(i) );
1540  }
1541 
1542  return nonzeros;
1543 }
1545 //*************************************************************************************************
1546 
1547 
1548 //*************************************************************************************************
1557 template< typename MT // Type of the dense matrix
1558  , bool SF // Symmetry flag
1559  , typename... CRAs > // Compile time row arguments
1560 inline size_t Rows<MT,true,true,SF,CRAs...>::nonZeros( size_t i ) const
1561 {
1562  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1563 
1564  return matrix_.nonZeros( idx(i) );
1565 }
1567 //*************************************************************************************************
1568 
1569 
1570 //*************************************************************************************************
1576 template< typename MT // Type of the dense matrix
1577  , bool SF // Symmetry flag
1578  , typename... CRAs > // Compile time row arguments
1580 {
1581  for( size_t i=0UL; i<rows(); ++i ) {
1582  matrix_.reset( idx(i) );
1583  }
1584 }
1586 //*************************************************************************************************
1587 
1588 
1589 //*************************************************************************************************
1598 template< typename MT // Type of the dense matrix
1599  , bool SF // Symmetry flag
1600  , typename... CRAs > // Compile time row arguments
1601 inline void Rows<MT,true,true,SF,CRAs...>::reset( size_t i )
1602 {
1603  matrix_.reset( idx(i) );
1604 }
1606 //*************************************************************************************************
1607 
1608 
1609 
1610 
1611 //=================================================================================================
1612 //
1613 // NUMERIC FUNCTIONS
1614 //
1615 //=================================================================================================
1616 
1617 //*************************************************************************************************
1630 template< typename MT // Type of the dense matrix
1631  , bool SF // Symmetry flag
1632  , typename... CRAs > // Compile time row arguments
1633 inline Rows<MT,true,true,SF,CRAs...>&
1635 {
1638 
1639  if( rows() != columns() ) {
1640  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1641  }
1642 
1643  const ResultType tmp( trans( *this ) );
1644 
1645  if( IsRestricted_v<MT> ) {
1646  for( size_t i=0UL; i<rows(); ++i ) {
1647  if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
1648  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1649  }
1650  }
1651  }
1652 
1653  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1654 
1655  smpAssign( left, tmp );
1656 
1657  return *this;
1658 }
1660 //*************************************************************************************************
1661 
1662 
1663 //*************************************************************************************************
1676 template< typename MT // Type of the dense matrix
1677  , bool SF // Symmetry flag
1678  , typename... CRAs > // Compile time row arguments
1679 inline Rows<MT,true,true,SF,CRAs...>&
1681 {
1684 
1685  if( rows() != columns() ) {
1686  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1687  }
1688 
1689  const ResultType tmp( ctrans( *this ) );
1690 
1691  if( IsRestricted_v<MT> ) {
1692  for( size_t i=0UL; i<rows(); ++i ) {
1693  if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
1694  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1695  }
1696  }
1697  }
1698 
1699  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1700 
1701  smpAssign( left, tmp );
1702 
1703  return *this;
1704 }
1706 //*************************************************************************************************
1707 
1708 
1709 //*************************************************************************************************
1722 template< typename MT // Type of the dense matrix
1723  , bool SF // Symmetry flag
1724  , typename... CRAs > // Compile time row arguments
1725 template< typename Other > // Data type of the scalar value
1726 inline Rows<MT,true,true,SF,CRAs...>&
1727  Rows<MT,true,true,SF,CRAs...>::scale( const Other& scalar )
1728 {
1732 
1733  for( size_t i=0UL; i<rows(); ++i )
1734  {
1735  const size_t index ( idx(i) );
1736  const size_t jbegin( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index+1UL : index ) : 0UL );
1737  const size_t jend ( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index : index+1UL ) : columns() );
1738 
1739  for( size_t j=jbegin; j<jend; ++j ) {
1740  matrix_(index,j) *= scalar;
1741  }
1742  }
1743 
1744  return *this;
1745 }
1747 //*************************************************************************************************
1748 
1749 
1750 
1751 
1752 //=================================================================================================
1753 //
1754 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1755 //
1756 //=================================================================================================
1757 
1758 //*************************************************************************************************
1769 template< typename MT // Type of the dense matrix
1770  , bool SF // Symmetry flag
1771  , typename... CRAs > // Compile time row arguments
1772 template< typename Other > // Data type of the foreign expression
1773 inline bool Rows<MT,true,true,SF,CRAs...>::canAlias( const Other* alias ) const noexcept
1774 {
1775  return matrix_.isAliased( alias );
1776 }
1778 //*************************************************************************************************
1779 
1780 
1781 //*************************************************************************************************
1793 template< typename MT // Type of the dense matrix
1794  , bool SF // Symmetry flag
1795  , typename... CRAs > // Compile time row arguments
1796 template< typename MT2 // Data type of the foreign dense row selection
1797  , bool SO2 // Storage order of the foreign dense row selection
1798  , bool SF2 // Symmetry flag of the foreign dense row selection
1799  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
1800 inline bool
1801  Rows<MT,true,true,SF,CRAs...>::canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
1802 {
1803  return matrix_.isAliased( &alias->matrix_ );
1804 }
1806 //*************************************************************************************************
1807 
1808 
1809 //*************************************************************************************************
1820 template< typename MT // Type of the dense matrix
1821  , bool SF // Symmetry flag
1822  , typename... CRAs > // Compile time row arguments
1823 template< typename Other > // Data type of the foreign expression
1824 inline bool Rows<MT,true,true,SF,CRAs...>::isAliased( const Other* alias ) const noexcept
1825 {
1826  return matrix_.isAliased( alias );
1827 }
1829 //*************************************************************************************************
1830 
1831 
1832 //*************************************************************************************************
1844 template< typename MT // Type of the dense matrix
1845  , bool SF // Symmetry flag
1846  , typename... CRAs > // Compile time row arguments
1847 template< typename MT2 // Data type of the foreign dense row selection
1848  , bool SO2 // Storage order of the foreign dense row selection
1849  , bool SF2 // Symmetry flag of the foreign dense row selection
1850  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
1851 inline bool
1852  Rows<MT,true,true,SF,CRAs...>::isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
1853 {
1854  return matrix_.isAliased( &alias->matrix_ );
1855 }
1857 //*************************************************************************************************
1858 
1859 
1860 //*************************************************************************************************
1870 template< typename MT // Type of the dense matrix
1871  , bool SF // Symmetry flag
1872  , typename... CRAs > // Compile time row arguments
1873 inline bool Rows<MT,true,true,SF,CRAs...>::isAligned() const noexcept
1874 {
1875  return matrix_.isAligned();
1876 }
1878 //*************************************************************************************************
1879 
1880 
1881 //*************************************************************************************************
1892 template< typename MT // Type of the dense matrix
1893  , bool SF // Symmetry flag
1894  , typename... CRAs > // Compile time row arguments
1895 inline bool Rows<MT,true,true,SF,CRAs...>::canSMPAssign() const noexcept
1896 {
1897  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
1898 }
1900 //*************************************************************************************************
1901 
1902 
1903 //*************************************************************************************************
1918 template< typename MT // Type of the dense matrix
1919  , bool SF // Symmetry flag
1920  , typename... CRAs > // Compile time row arguments
1921 BLAZE_ALWAYS_INLINE typename Rows<MT,true,true,SF,CRAs...>::SIMDType
1922  Rows<MT,true,true,SF,CRAs...>::load( size_t i, size_t j ) const noexcept
1923 {
1924  return matrix_.load( idx(i), j );
1925 }
1927 //*************************************************************************************************
1928 
1929 
1930 //*************************************************************************************************
1945 template< typename MT // Type of the dense matrix
1946  , bool SF // Symmetry flag
1947  , typename... CRAs > // Compile time row arguments
1948 BLAZE_ALWAYS_INLINE typename Rows<MT,true,true,SF,CRAs...>::SIMDType
1949  Rows<MT,true,true,SF,CRAs...>::loada( size_t i, size_t j ) const noexcept
1950 {
1951  return matrix_.loada( idx(i), j );
1952 }
1954 //*************************************************************************************************
1955 
1956 
1957 //*************************************************************************************************
1972 template< typename MT // Type of the dense matrix
1973  , bool SF // Symmetry flag
1974  , typename... CRAs > // Compile time row arguments
1975 BLAZE_ALWAYS_INLINE typename Rows<MT,true,true,SF,CRAs...>::SIMDType
1976  Rows<MT,true,true,SF,CRAs...>::loadu( size_t i, size_t j ) const noexcept
1977 {
1978  return matrix_.loadu( idx(i), j );
1979 }
1981 //*************************************************************************************************
1982 
1983 
1984 //*************************************************************************************************
2000 template< typename MT // Type of the dense matrix
2001  , bool SF // Symmetry flag
2002  , typename... CRAs > // Compile time row arguments
2004  Rows<MT,true,true,SF,CRAs...>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2005 {
2006  matrix_.store( idx(i), j, value );
2007 }
2009 //*************************************************************************************************
2010 
2011 
2012 //*************************************************************************************************
2028 template< typename MT // Type of the dense matrix
2029  , bool SF // Symmetry flag
2030  , typename... CRAs > // Compile time row arguments
2032  Rows<MT,true,true,SF,CRAs...>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2033 {
2034  matrix_.storea( idx(i), j, value );
2035 }
2037 //*************************************************************************************************
2038 
2039 
2040 //*************************************************************************************************
2056 template< typename MT // Type of the dense matrix
2057  , bool SF // Symmetry flag
2058  , typename... CRAs > // Compile time row arguments
2060  Rows<MT,true,true,SF,CRAs...>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2061 {
2062  matrix_.storeu( idx(i), j, value );
2063 }
2065 //*************************************************************************************************
2066 
2067 
2068 //*************************************************************************************************
2084 template< typename MT // Type of the dense matrix
2085  , bool SF // Symmetry flag
2086  , typename... CRAs > // Compile time row arguments
2088  Rows<MT,true,true,SF,CRAs...>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2089 {
2090  matrix_.stream( idx(i), j, value );
2091 }
2093 //*************************************************************************************************
2094 
2095 
2096 //*************************************************************************************************
2108 template< typename MT // Type of the dense matrix
2109  , bool SF // Symmetry flag
2110  , typename... CRAs > // Compile time row arguments
2111 template< typename MT2 > // Type of the right-hand side dense matrix
2112 inline auto Rows<MT,true,true,SF,CRAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2113  -> DisableIf_t< VectorizedAssign_v<MT2> >
2114 {
2117 
2118  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2119  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2120 
2121  const size_t jpos( columns() & size_t(-2) );
2122  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
2123 
2124  for( size_t i=0UL; i<rows(); ++i ) {
2125  const size_t index( idx(i) );
2126  for( size_t j=0UL; j<jpos; j+=2UL ) {
2127  matrix_(index,j ) = (~rhs)(i,j );
2128  matrix_(index,j+1UL) = (~rhs)(i,j+1UL);
2129  }
2130  if( jpos < columns() ) {
2131  matrix_(index,jpos) = (~rhs)(i,jpos);
2132  }
2133  }
2134 }
2136 //*************************************************************************************************
2137 
2138 
2139 //*************************************************************************************************
2151 template< typename MT // Type of the dense matrix
2152  , bool SF // Symmetry flag
2153  , typename... CRAs > // Compile time row arguments
2154 template< typename MT2 > // Type of the right-hand side dense matrix
2155 inline auto Rows<MT,true,true,SF,CRAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2156  -> EnableIf_t< VectorizedAssign_v<MT2> >
2157 {
2160 
2162 
2163  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2164  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2165 
2166  const size_t jpos( columns() & size_t(-SIMDSIZE) );
2167  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2168 
2169  if( useStreaming &&
2170  rows()*columns() > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2171  !(~rhs).isAliased( &matrix_ ) )
2172  {
2173  for( size_t i=0UL; i<rows(); ++i )
2174  {
2175  size_t j( 0UL );
2176  Iterator left( begin(i) );
2177  ConstIterator_t<MT2> right( (~rhs).begin(i) );
2178 
2179  for( ; j<jpos; j+=SIMDSIZE ) {
2180  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2181  }
2182  for( ; j<columns(); ++j ) {
2183  *left = *right;
2184  }
2185  }
2186  }
2187  else
2188  {
2189  for( size_t i=0UL; i<rows(); ++i )
2190  {
2191  size_t j( 0UL );
2192  Iterator left( begin(i) );
2193  ConstIterator_t<MT2> right( (~rhs).begin(i) );
2194 
2195  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2196  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2197  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2198  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2199  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2200  }
2201  for( ; j<jpos; j+=SIMDSIZE ) {
2202  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2203  }
2204  for( ; j<columns(); ++j ) {
2205  *left = *right; ++left; ++right;
2206  }
2207  }
2208  }
2209 }
2211 //*************************************************************************************************
2212 
2213 
2214 //*************************************************************************************************
2226 template< typename MT // Type of the dense matrix
2227  , bool SF // Symmetry flag
2228  , typename... CRAs > // Compile time row arguments
2229 template< typename MT2 > // Type of the right-hand side dense matrix
2230 inline void Rows<MT,true,true,SF,CRAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2231 {
2234 
2236 
2237  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2238  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2239 
2240  constexpr size_t block( BLOCK_SIZE );
2241 
2242  if( rows() < block && columns() < block )
2243  {
2244  const size_t jpos( (~rhs).columns() & size_t(-2) );
2245  for( size_t i=0UL; i<rows(); ++i ) {
2246  const size_t index( idx(i) );
2247  for( size_t j=0UL; j<jpos; j+=2UL ) {
2248  matrix_(index,j ) = (~rhs)(i,j );
2249  matrix_(index,j+1UL) = (~rhs)(i,j+1UL);
2250  }
2251  if( jpos < (~rhs).columns() ) {
2252  matrix_(index,jpos) = (~rhs)(i,jpos);
2253  }
2254  }
2255  }
2256  else
2257  {
2258  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2259  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2260  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2261  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2262  for( size_t i=ii; i<iend; ++i ) {
2263  const size_t index( idx(i) );
2264  for( size_t j=jj; j<jend; ++j ) {
2265  matrix_(index,j) = (~rhs)(i,j);
2266  }
2267  }
2268  }
2269  }
2270  }
2271 }
2273 //*************************************************************************************************
2274 
2275 
2276 //*************************************************************************************************
2288 template< typename MT // Type of the dense matrix
2289  , bool SF // Symmetry flag
2290  , typename... CRAs > // Compile time row arguments
2291 template< typename MT2 > // Type of the right-hand side sparse matrix
2292 inline void Rows<MT,true,true,SF,CRAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2293 {
2296 
2297  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2298  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2299 
2300  for( size_t i=0UL; i<rows(); ++i ) {
2301  const size_t index( idx(i) );
2302  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2303  matrix_(index,element->index()) = element->value();
2304  }
2305 }
2307 //*************************************************************************************************
2308 
2309 
2310 //*************************************************************************************************
2322 template< typename MT // Type of the dense matrix
2323  , bool SF // Symmetry flag
2324  , typename... CRAs > // Compile time row arguments
2325 template< typename MT2 > // Type of the right-hand side sparse matrix
2326 inline void Rows<MT,true,true,SF,CRAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2327 {
2330 
2332 
2333  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2334  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2335 
2336  for( size_t j=0UL; j<columns(); ++j ) {
2337  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2338  matrix_(idx(element->index()),j) = element->value();
2339  }
2340 }
2342 //*************************************************************************************************
2343 
2344 
2345 //*************************************************************************************************
2357 template< typename MT // Type of the dense matrix
2358  , bool SF // Symmetry flag
2359  , typename... CRAs > // Compile time row arguments
2360 template< typename MT2 > // Type of the right-hand side dense matrix
2361 inline auto Rows<MT,true,true,SF,CRAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2362  -> DisableIf_t< VectorizedAddAssign_v<MT2> >
2363 {
2366 
2367  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2368  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2369 
2370  const size_t jpos( columns() & size_t(-2) );
2371  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
2372 
2373  for( size_t i=0UL; i<rows(); ++i )
2374  {
2375  const size_t index( idx(i) );
2376  if( IsDiagonal_v<MT2> ) {
2377  matrix_(index,i) += (~rhs)(i,i);
2378  }
2379  else {
2380  for( size_t j=0UL; j<jpos; j+=2UL ) {
2381  matrix_(index,j ) += (~rhs)(i,j );
2382  matrix_(index,j+1UL) += (~rhs)(i,j+1UL);
2383  }
2384  if( jpos < columns() ) {
2385  matrix_(index,jpos) += (~rhs)(i,jpos);
2386  }
2387  }
2388  }
2389 }
2391 //*************************************************************************************************
2392 
2393 
2394 //*************************************************************************************************
2406 template< typename MT // Type of the dense matrix
2407  , bool SF // Symmetry flag
2408  , typename... CRAs > // Compile time row arguments
2409 template< typename MT2 > // Type of the right-hand side dense matrix
2410 inline auto Rows<MT,true,true,SF,CRAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2411  -> EnableIf_t< VectorizedAddAssign_v<MT2> >
2412 {
2415 
2417 
2418  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2419  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2420 
2421  for( size_t i=0UL; i<rows(); ++i )
2422  {
2423  const size_t jbegin( ( IsUpper_v<MT2> )
2424  ?( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2425  :( 0UL ) );
2426  const size_t jend ( ( IsLower_v<MT2> )
2427  ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
2428  :( columns() ) );
2429  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2430 
2431  const size_t jpos( jend & size_t(-SIMDSIZE) );
2432  BLAZE_INTERNAL_ASSERT( ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2433 
2434  size_t j( jbegin );
2435  Iterator left( begin(i) + jbegin );
2436  ConstIterator_t<MT2> right( (~rhs).begin(i) + jbegin );
2437 
2438  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2439  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2440  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2441  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2442  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2443  }
2444  for( ; j<jpos; j+=SIMDSIZE ) {
2445  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2446  }
2447  for( ; j<jend; ++j ) {
2448  *left += *right; ++left; ++right;
2449  }
2450  }
2451 }
2453 //*************************************************************************************************
2454 
2455 
2456 //*************************************************************************************************
2468 template< typename MT // Type of the dense matrix
2469  , bool SF // Symmetry flag
2470  , typename... CRAs > // Compile time row arguments
2471 template< typename MT2 > // Type of the right-hand side dense matrix
2472 inline void Rows<MT,true,true,SF,CRAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2473 {
2476 
2478 
2479  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2480  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2481 
2482  constexpr size_t block( BLOCK_SIZE );
2483 
2484  if( rows() < block && columns() < block )
2485  {
2486  const size_t jpos( (~rhs).columns() & size_t(-2) );
2487  for( size_t i=0UL; i<rows(); ++i ) {
2488  const size_t index( idx(i) );
2489  for( size_t j=0UL; j<jpos; j+=2UL ) {
2490  matrix_(index,j ) += (~rhs)(i,j );
2491  matrix_(index,j+1UL) += (~rhs)(i,j+1UL);
2492  }
2493  if( jpos < (~rhs).columns() ) {
2494  matrix_(index,jpos) += (~rhs)(i,jpos);
2495  }
2496  }
2497  }
2498  else
2499  {
2500  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2501  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2502  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2503  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2504  for( size_t i=ii; i<iend; ++i ) {
2505  const size_t index( idx(i) );
2506  for( size_t j=jj; j<jend; ++j ) {
2507  matrix_(index,j) += (~rhs)(i,j);
2508  }
2509  }
2510  }
2511  }
2512  }
2513 }
2515 //*************************************************************************************************
2516 
2517 
2518 //*************************************************************************************************
2530 template< typename MT // Type of the dense matrix
2531  , bool SF // Symmetry flag
2532  , typename... CRAs > // Compile time row arguments
2533 template< typename MT2 > // Type of the right-hand side sparse matrix
2534 inline void Rows<MT,true,true,SF,CRAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
2535 {
2538 
2539  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2540  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2541 
2542  for( size_t i=0UL; i<rows(); ++i ) {
2543  const size_t index( idx(i) );
2544  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2545  matrix_(index,element->index()) += element->value();
2546  }
2547 }
2549 //*************************************************************************************************
2550 
2551 
2552 //*************************************************************************************************
2564 template< typename MT // Type of the dense matrix
2565  , bool SF // Symmetry flag
2566  , typename... CRAs > // Compile time row arguments
2567 template< typename MT2 > // Type of the right-hand side sparse matrix
2568 inline void Rows<MT,true,true,SF,CRAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
2569 {
2572 
2574 
2575  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2576  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2577 
2578  for( size_t j=0UL; j<columns(); ++j ) {
2579  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2580  matrix_(idx(element->index()),j) += element->value();
2581  }
2582 }
2584 //*************************************************************************************************
2585 
2586 
2587 //*************************************************************************************************
2599 template< typename MT // Type of the dense matrix
2600  , bool SF // Symmetry flag
2601  , typename... CRAs > // Compile time row arguments
2602 template< typename MT2 > // Type of the right-hand side dense matrix
2603 inline auto Rows<MT,true,true,SF,CRAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2604  -> DisableIf_t< VectorizedSubAssign_v<MT2> >
2605 {
2608 
2609  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2610  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2611 
2612  const size_t jpos( columns() & size_t(-2) );
2613  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
2614 
2615  for( size_t i=0UL; i<rows(); ++i )
2616  {
2617  const size_t index( idx(i) );
2618 
2619  if( IsDiagonal_v<MT2> ) {
2620  matrix_(index,i) -= (~rhs)(i,i);
2621  }
2622  else {
2623  for( size_t j=0UL; j<jpos; j+=2UL ) {
2624  matrix_(index,j ) -= (~rhs)(i,j );
2625  matrix_(index,j+1UL) -= (~rhs)(i,j+1UL);
2626  }
2627  if( jpos < columns() ) {
2628  matrix_(index,jpos) -= (~rhs)(i,jpos);
2629  }
2630  }
2631  }
2632 }
2634 //*************************************************************************************************
2635 
2636 
2637 //*************************************************************************************************
2649 template< typename MT // Type of the dense matrix
2650  , bool SF // Symmetry flag
2651  , typename... CRAs > // Compile time row arguments
2652 template< typename MT2 > // Type of the right-hand side dense matrix
2653 inline auto Rows<MT,true,true,SF,CRAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2654  -> EnableIf_t< VectorizedSubAssign_v<MT2> >
2655 {
2658 
2660 
2661  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2662  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2663 
2664  for( size_t i=0UL; i<rows(); ++i )
2665  {
2666  const size_t jbegin( ( IsUpper_v<MT2> )
2667  ?( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ) & size_t(-SIMDSIZE) )
2668  :( 0UL ) );
2669  const size_t jend ( ( IsLower_v<MT2> )
2670  ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
2671  :( columns() ) );
2672  BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2673 
2674  const size_t jpos( jend & size_t(-SIMDSIZE) );
2675  BLAZE_INTERNAL_ASSERT( ( jend - ( jend % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2676 
2677  size_t j( jbegin );
2678  Iterator left( begin(i) + jbegin );
2679  ConstIterator_t<MT2> right( (~rhs).begin(i) + jbegin );
2680 
2681  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2682  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2683  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2684  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2685  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2686  }
2687  for( ; j<jpos; j+=SIMDSIZE ) {
2688  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2689  }
2690  for( ; j<jend; ++j ) {
2691  *left -= *right; ++left; ++right;
2692  }
2693  }
2694 }
2696 //*************************************************************************************************
2697 
2698 
2699 //*************************************************************************************************
2711 template< typename MT // Type of the dense matrix
2712  , bool SF // Symmetry flag
2713  , typename... CRAs > // Compile time row arguments
2714 template< typename MT2 > // Type of the right-hand side dense matrix
2715 inline void Rows<MT,true,true,SF,CRAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2716 {
2719 
2721 
2722  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2723  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2724 
2725  constexpr size_t block( BLOCK_SIZE );
2726 
2727  if( rows() < block && columns() < block )
2728  {
2729  const size_t jpos( (~rhs).columns() & size_t(-2) );
2730  for( size_t i=0UL; i<rows(); ++i ) {
2731  const size_t index( idx(i) );
2732  for( size_t j=0UL; j<jpos; j+=2UL ) {
2733  matrix_(index,j ) -= (~rhs)(i,j );
2734  matrix_(index,j+1UL) -= (~rhs)(i,j+1UL);
2735  }
2736  if( jpos < (~rhs).columns() ) {
2737  matrix_(index,jpos) -= (~rhs)(i,jpos);
2738  }
2739  }
2740  }
2741  else
2742  {
2743  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2744  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2745  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2746  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2747  for( size_t i=ii; i<iend; ++i ) {
2748  const size_t index( idx(i) );
2749  for( size_t j=jj; j<jend; ++j ) {
2750  matrix_(index,j) -= (~rhs)(i,j);
2751  }
2752  }
2753  }
2754  }
2755  }
2756 }
2758 //*************************************************************************************************
2759 
2760 
2761 //*************************************************************************************************
2773 template< typename MT // Type of the dense matrix
2774  , bool SF // Symmetry flag
2775  , typename... CRAs > // Compile time row arguments
2776 template< typename MT2 > // Type of the right-hand side sparse matrix
2777 inline void Rows<MT,true,true,SF,CRAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
2778 {
2781 
2782  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2783  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2784 
2785  for( size_t i=0UL; i<rows(); ++i ) {
2786  const size_t index( idx(i) );
2787  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2788  matrix_(index,element->index()) -= element->value();
2789  }
2790 }
2792 //*************************************************************************************************
2793 
2794 
2795 //*************************************************************************************************
2807 template< typename MT // Type of the dense matrix
2808  , bool SF // Symmetry flag
2809  , typename... CRAs > // Compile time row arguments
2810 template< typename MT2 > // Type of the right-hand side sparse matrix
2811 inline void Rows<MT,true,true,SF,CRAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
2812 {
2815 
2817 
2818  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2819  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2820 
2821  for( size_t j=0UL; j<columns(); ++j ) {
2822  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2823  matrix_(idx(element->index()),j) -= element->value();
2824  }
2825 }
2827 //*************************************************************************************************
2828 
2829 
2830 //*************************************************************************************************
2842 template< typename MT // Type of the dense matrix
2843  , bool SF // Symmetry flag
2844  , typename... CRAs > // Compile time row arguments
2845 template< typename MT2 > // Type of the right-hand side dense matrix
2846 inline auto Rows<MT,true,true,SF,CRAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2847  -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
2848 {
2851 
2852  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2853  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2854 
2855  const size_t jpos( columns() & size_t(-2) );
2856  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
2857 
2858  for( size_t i=0UL; i<rows(); ++i ) {
2859  const size_t index( idx(i) );
2860  for( size_t j=0UL; j<jpos; j+=2UL ) {
2861  matrix_(index,j ) *= (~rhs)(i,j );
2862  matrix_(index,j+1UL) *= (~rhs)(i,j+1UL);
2863  }
2864  if( jpos < columns() ) {
2865  matrix_(index,jpos) *= (~rhs)(i,jpos);
2866  }
2867  }
2868 }
2870 //*************************************************************************************************
2871 
2872 
2873 //*************************************************************************************************
2885 template< typename MT // Type of the dense matrix
2886  , bool SF // Symmetry flag
2887  , typename... CRAs > // Compile time row arguments
2888 template< typename MT2 > // Type of the right-hand side dense matrix
2889 inline auto Rows<MT,true,true,SF,CRAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2890  -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
2891 {
2894 
2896 
2897  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2898  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2899 
2900  for( size_t i=0UL; i<rows(); ++i )
2901  {
2902  const size_t jpos( columns() & size_t(-SIMDSIZE) );
2903  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
2904 
2905  size_t j( 0UL );
2906  Iterator left( begin(i) );
2907  ConstIterator_t<MT2> right( (~rhs).begin(i) );
2908 
2909  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2910  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2911  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2912  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2913  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2914  }
2915  for( ; j<jpos; j+=SIMDSIZE ) {
2916  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2917  }
2918  for( ; j<columns(); ++j ) {
2919  *left *= *right; ++left; ++right;
2920  }
2921  }
2922 }
2924 //*************************************************************************************************
2925 
2926 
2927 //*************************************************************************************************
2939 template< typename MT // Type of the dense matrix
2940  , bool SF // Symmetry flag
2941  , typename... CRAs > // Compile time row arguments
2942 template< typename MT2 > // Type of the right-hand side dense matrix
2943 inline void Rows<MT,true,true,SF,CRAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2944 {
2947 
2949 
2950  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2951  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2952 
2953  constexpr size_t block( BLOCK_SIZE );
2954 
2955  if( rows() < block && columns() < block )
2956  {
2957  const size_t jpos( (~rhs).columns() & size_t(-2) );
2958  for( size_t i=0UL; i<rows(); ++i ) {
2959  const size_t index( idx(i) );
2960  for( size_t j=0UL; j<jpos; j+=2UL ) {
2961  matrix_(index,j ) *= (~rhs)(i,j );
2962  matrix_(index,j+1UL) *= (~rhs)(i,j+1UL);
2963  }
2964  if( jpos < (~rhs).columns() ) {
2965  matrix_(index,jpos) *= (~rhs)(i,jpos);
2966  }
2967  }
2968  }
2969  else
2970  {
2971  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2972  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2973  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2974  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2975  for( size_t i=ii; i<iend; ++i ) {
2976  const size_t index( idx(i) );
2977  for( size_t j=jj; j<jend; ++j ) {
2978  matrix_(index,j) *= (~rhs)(i,j);
2979  }
2980  }
2981  }
2982  }
2983  }
2984 }
2986 //*************************************************************************************************
2987 
2988 
2989 //*************************************************************************************************
3001 template< typename MT // Type of the dense matrix
3002  , bool SF // Symmetry flag
3003  , typename... CRAs > // Compile time row arguments
3004 template< typename MT2 > // Type of the right-hand side sparse matrix
3005 inline void Rows<MT,true,true,SF,CRAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
3006 {
3009 
3010  using blaze::reset;
3011 
3012  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3013  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3014 
3015  for( size_t i=0UL; i<rows(); ++i )
3016  {
3017  const size_t index( idx(i) );
3018  size_t j( 0UL );
3019 
3020  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
3021  for( ; j<element->index(); ++j )
3022  reset( matrix_(index,j) );
3023  matrix_(index,j) *= element->value();
3024  ++j;
3025  }
3026 
3027  for( ; j<columns(); ++j ) {
3028  reset( matrix_(index,j) );
3029  }
3030  }
3031 }
3033 //*************************************************************************************************
3034 
3035 
3036 //*************************************************************************************************
3048 template< typename MT // Type of the dense matrix
3049  , bool SF // Symmetry flag
3050  , typename... CRAs > // Compile time row arguments
3051 template< typename MT2 > // Type of the right-hand side sparse matrix
3052 inline void Rows<MT,true,true,SF,CRAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
3053 {
3056 
3057  using blaze::reset;
3058 
3060 
3061  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3062  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3063 
3064  for( size_t j=0UL; j<columns(); ++j )
3065  {
3066  size_t i( 0UL );
3067 
3068  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
3069  for( ; i<element->index(); ++i )
3070  reset( matrix_(idx(i),j) );
3071  matrix_(idx(i),j) *= element->value();
3072  ++i;
3073  }
3074 
3075  for( ; i<rows(); ++i ) {
3076  reset( matrix_(idx(i),j) );
3077  }
3078  }
3079 }
3081 //*************************************************************************************************
3082 
3083 
3084 
3085 
3086 
3087 
3088 
3089 
3090 //=================================================================================================
3091 //
3092 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR DENSE MATRICES
3093 //
3094 //=================================================================================================
3095 
3096 //*************************************************************************************************
3104 template< typename MT // Type of the dense matrix
3105  , typename... CRAs > // Compile time row arguments
3106 class Rows<MT,false,true,false,CRAs...>
3107  : public View< DenseMatrix< Rows<MT,false,true,false,CRAs...>, false > >
3108  , private RowsData<CRAs...>
3109 {
3110  private:
3111  //**Type definitions****************************************************************************
3112  using DataType = RowsData<CRAs...>;
3113  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
3114  //**********************************************************************************************
3115 
3116  //**Compile time flags**************************************************************************
3117  using DataType::N;
3118  //**********************************************************************************************
3119 
3120  //**********************************************************************************************
3122  template< typename MT1, typename MT2 >
3123  static constexpr bool EnforceEvaluation_v =
3124  ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
3125  //**********************************************************************************************
3126 
3127  public:
3128  //**Type definitions****************************************************************************
3130  using This = Rows<MT,false,true,false,CRAs...>;
3131 
3132  using BaseType = DenseMatrix<This,false>;
3133  using ViewedType = MT;
3134  using ResultType = RowsTrait_t<MT,N>;
3135  using OppositeType = OppositeType_t<ResultType>;
3136  using TransposeType = TransposeType_t<ResultType>;
3137  using ElementType = ElementType_t<MT>;
3138  using ReturnType = ReturnType_t<MT>;
3139  using CompositeType = const Rows&;
3140 
3142  using ConstReference = ConstReference_t<MT>;
3143 
3145  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
3146 
3148  using ConstPointer = ConstPointer_t<MT>;
3149 
3151  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
3152  //**********************************************************************************************
3153 
3154  //**RowsIterator class definition***************************************************************
3157  template< typename MatrixType // Type of the dense matrix
3158  , typename IteratorType > // Type of the dense matrix iterator
3159  class RowsIterator
3160  {
3161  public:
3162  //**Type definitions*************************************************************************
3164  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
3165 
3167  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
3168 
3170  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
3171 
3173  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
3174 
3176  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
3177 
3178  // STL iterator requirements
3179  using iterator_category = IteratorCategory;
3180  using value_type = ValueType;
3181  using pointer = PointerType;
3182  using reference = ReferenceType;
3183  using difference_type = DifferenceType;
3184  //*******************************************************************************************
3185 
3186  //**Constructor******************************************************************************
3189  inline RowsIterator() noexcept
3190  : matrix_( nullptr ) // The dense matrix containing the row
3191  , row_ ( 0UL ) // The current row index
3192  , column_( 0UL ) // The current column index
3193  , pos_ ( ) // Iterator to the current dense element
3194  {}
3195  //*******************************************************************************************
3196 
3197  //**Constructor******************************************************************************
3204  inline RowsIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
3205  : matrix_( &matrix ) // The dense matrix containing the selected row
3206  , row_ ( row ) // The current row index
3207  , column_( column ) // The current column index
3208  , pos_ ( ) // Iterator to the current dense element
3209  {
3210  if( column_ != matrix_->columns() )
3211  pos_ = matrix_->begin( column_ ) + row_;
3212  }
3213  //*******************************************************************************************
3214 
3215  //**Constructor******************************************************************************
3220  template< typename MatrixType2, typename IteratorType2 >
3221  inline RowsIterator( const RowsIterator<MatrixType2,IteratorType2>& it ) noexcept
3222  : matrix_( it.matrix_ ) // The dense matrix containing the seleted row
3223  , row_ ( it.row_ ) // The current row index
3224  , column_( it.column_ ) // The current column index
3225  , pos_ ( it.pos_ ) // Iterator to the current dense element
3226  {}
3227  //*******************************************************************************************
3228 
3229  //**Addition assignment operator*************************************************************
3235  inline RowsIterator& operator+=( size_t inc ) noexcept {
3236  using blaze::reset;
3237  column_ += inc;
3238  if( column_ != matrix_->columns() )
3239  pos_ = matrix_->begin( column_ ) + row_;
3240  else reset( pos_ );
3241  return *this;
3242  }
3243  //*******************************************************************************************
3244 
3245  //**Subtraction assignment operator**********************************************************
3251  inline RowsIterator& operator-=( size_t dec ) noexcept {
3252  using blaze::reset;
3253  column_ -= dec;
3254  if( column_ != matrix_->columns() )
3255  pos_ = matrix_->begin( column_ ) + row_;
3256  else reset( pos_ );
3257  return *this;
3258  }
3259  //*******************************************************************************************
3260 
3261  //**Prefix increment operator****************************************************************
3266  inline RowsIterator& operator++() noexcept {
3267  using blaze::reset;
3268  ++column_;
3269  if( column_ != matrix_->columns() )
3270  pos_ = matrix_->begin( column_ ) + row_;
3271  else reset( pos_ );
3272  return *this;
3273  }
3274  //*******************************************************************************************
3275 
3276  //**Postfix increment operator***************************************************************
3281  inline const RowsIterator operator++( int ) noexcept {
3282  const RowsIterator tmp( *this );
3283  ++(*this);
3284  return tmp;
3285  }
3286  //*******************************************************************************************
3287 
3288  //**Prefix decrement operator****************************************************************
3293  inline RowsIterator& operator--() noexcept {
3294  using blaze::reset;
3295  --column_;
3296  if( column_ != matrix_->columns() )
3297  pos_ = matrix_->begin( column_ ) + row_;
3298  else reset( pos_ );
3299  return *this;
3300  }
3301  //*******************************************************************************************
3302 
3303  //**Postfix decrement operator***************************************************************
3308  inline const RowsIterator operator--( int ) noexcept {
3309  const RowsIterator tmp( *this );
3310  --(*this);
3311  return tmp;
3312  }
3313  //*******************************************************************************************
3314 
3315  //**Subscript operator***********************************************************************
3321  inline ReferenceType operator[]( size_t index ) const {
3322  BLAZE_USER_ASSERT( column_+index < matrix_->columns(), "Invalid access index detected" );
3323  const IteratorType pos( matrix_->begin( column_+index ) + row_ );
3324  return *pos;
3325  }
3326  //*******************************************************************************************
3327 
3328  //**Element access operator******************************************************************
3333  inline ReferenceType operator*() const {
3334  return *pos_;
3335  }
3336  //*******************************************************************************************
3337 
3338  //**Element access operator******************************************************************
3343  inline PointerType operator->() const {
3344  return pos_;
3345  }
3346  //*******************************************************************************************
3347 
3348  //**Equality operator************************************************************************
3354  template< typename MatrixType2, typename IteratorType2 >
3355  inline bool operator==( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3356  return column_ == rhs.column_;
3357  }
3358  //*******************************************************************************************
3359 
3360  //**Inequality operator**********************************************************************
3366  template< typename MatrixType2, typename IteratorType2 >
3367  inline bool operator!=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3368  return !( *this == rhs );
3369  }
3370  //*******************************************************************************************
3371 
3372  //**Less-than operator***********************************************************************
3378  template< typename MatrixType2, typename IteratorType2 >
3379  inline bool operator<( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3380  return column_ < rhs.column_;
3381  }
3382  //*******************************************************************************************
3383 
3384  //**Greater-than operator********************************************************************
3390  template< typename MatrixType2, typename IteratorType2 >
3391  inline bool operator>( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3392  return column_ > rhs.column_;
3393  }
3394  //*******************************************************************************************
3395 
3396  //**Less-or-equal-than operator**************************************************************
3402  template< typename MatrixType2, typename IteratorType2 >
3403  inline bool operator<=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3404  return column_ <= rhs.column_;
3405  }
3406  //*******************************************************************************************
3407 
3408  //**Greater-or-equal-than operator***********************************************************
3414  template< typename MatrixType2, typename IteratorType2 >
3415  inline bool operator>=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3416  return column_ >= rhs.column_;
3417  }
3418  //*******************************************************************************************
3419 
3420  //**Subtraction operator*********************************************************************
3426  inline DifferenceType operator-( const RowsIterator& rhs ) const noexcept {
3427  return column_ - rhs.column_;
3428  }
3429  //*******************************************************************************************
3430 
3431  //**Addition operator************************************************************************
3438  friend inline const RowsIterator operator+( const RowsIterator& it, size_t inc ) noexcept {
3439  return RowsIterator( *it.matrix_, it.row_, it.column_+inc );
3440  }
3441  //*******************************************************************************************
3442 
3443  //**Addition operator************************************************************************
3450  friend inline const RowsIterator operator+( size_t inc, const RowsIterator& it ) noexcept {
3451  return RowsIterator( *it.matrix_, it.row_, it.column_+inc );
3452  }
3453  //*******************************************************************************************
3454 
3455  //**Subtraction operator*********************************************************************
3462  friend inline const RowsIterator operator-( const RowsIterator& it, size_t dec ) noexcept {
3463  return RowsIterator( *it.matrix_, it.row_, it.column_-dec );
3464  }
3465  //*******************************************************************************************
3466 
3467  private:
3468  //**Member variables*************************************************************************
3469  MatrixType* matrix_;
3470  size_t row_;
3471  size_t column_;
3472  IteratorType pos_;
3473  //*******************************************************************************************
3474 
3475  //**Friend declarations**********************************************************************
3476  template< typename MatrixType2, typename IteratorType2 > friend class RowsIterator;
3477  //*******************************************************************************************
3478  };
3479  //**********************************************************************************************
3480 
3481  //**Type definitions****************************************************************************
3483  using ConstIterator = RowsIterator< const MT, ConstIterator_t<MT> >;
3484 
3486  using Iterator = If_t< IsConst_v<MT>, ConstIterator, RowsIterator< MT, Iterator_t<MT> > >;
3487  //**********************************************************************************************
3488 
3489  //**Compilation flags***************************************************************************
3491  static constexpr bool simdEnabled = false;
3492 
3494  static constexpr bool smpAssignable = MT::smpAssignable;
3495  //**********************************************************************************************
3496 
3497  //**Constructors********************************************************************************
3500  template< typename... RRAs >
3501  explicit inline Rows( MT& matrix, RRAs... args );
3502 
3503  Rows( const Rows& ) = default;
3504  Rows( Rows&& ) = default;
3506  //**********************************************************************************************
3507 
3508  //**Destructor**********************************************************************************
3511  ~Rows() = default;
3513  //**********************************************************************************************
3514 
3515  //**Data access functions***********************************************************************
3518  inline Reference operator()( size_t i, size_t j );
3519  inline ConstReference operator()( size_t i, size_t j ) const;
3520  inline Reference at( size_t i, size_t j );
3521  inline ConstReference at( size_t i, size_t j ) const;
3522  inline Pointer data () noexcept;
3523  inline ConstPointer data () const noexcept;
3524  inline Pointer data ( size_t i ) noexcept;
3525  inline ConstPointer data ( size_t i ) const noexcept;
3526  inline Iterator begin ( size_t i );
3527  inline ConstIterator begin ( size_t i ) const;
3528  inline ConstIterator cbegin( size_t i ) const;
3529  inline Iterator end ( size_t i );
3530  inline ConstIterator end ( size_t i ) const;
3531  inline ConstIterator cend ( size_t i ) const;
3533  //**********************************************************************************************
3534 
3535  //**Assignment operators************************************************************************
3538  inline Rows& operator=( const ElementType& rhs );
3539  inline Rows& operator=( initializer_list< initializer_list<ElementType> > list );
3540  inline Rows& operator=( const Rows& rhs );
3541 
3542  template< typename MT2, bool SO2 >
3543  inline Rows& operator=( const Matrix<MT2,SO2>& rhs );
3544 
3545  template< typename MT2, bool SO2 >
3546  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3547  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3548 
3549  template< typename MT2, bool SO2 >
3550  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3551  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3552 
3553  template< typename MT2, bool SO2 >
3554  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3555  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3556 
3557  template< typename MT2, bool SO2 >
3558  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3559  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3560 
3561  template< typename MT2, bool SO2 >
3562  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3563  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3564 
3565  template< typename MT2, bool SO2 >
3566  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3567  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3569  //**********************************************************************************************
3570 
3571  //**Utility functions***************************************************************************
3574  using DataType::idx;
3575  using DataType::idces;
3576  using DataType::rows;
3577 
3578  inline MT& operand() noexcept;
3579  inline const MT& operand() const noexcept;
3580 
3581  inline size_t columns() const noexcept;
3582  inline size_t spacing() const noexcept;
3583  inline size_t capacity() const noexcept;
3584  inline size_t capacity( size_t i ) const noexcept;
3585  inline size_t nonZeros() const;
3586  inline size_t nonZeros( size_t i ) const;
3587  inline void reset();
3588  inline void reset( size_t i );
3590  //**********************************************************************************************
3591 
3592  //**Numeric functions***************************************************************************
3595  inline Rows& transpose();
3596  inline Rows& ctranspose();
3597 
3598  template< typename Other > inline Rows& scale( const Other& scalar );
3600  //**********************************************************************************************
3601 
3602  //**Expression template evaluation functions****************************************************
3605  template< typename Other >
3606  inline bool canAlias( const Other* alias ) const noexcept;
3607 
3608  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
3609  inline bool canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
3610 
3611  template< typename Other >
3612  inline bool isAliased( const Other* alias ) const noexcept;
3613 
3614  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
3615  inline bool isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
3616 
3617  inline bool isAligned () const noexcept;
3618  inline bool canSMPAssign() const noexcept;
3619 
3620  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3621  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
3622  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3623  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3624 
3625  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3626  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
3627  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3628  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3629 
3630  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3631  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
3632  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3633  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3634 
3635  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
3636  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
3637  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
3638  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
3640  //**********************************************************************************************
3641 
3642  private:
3643  //**Member variables****************************************************************************
3646  Operand matrix_;
3647 
3648  //**********************************************************************************************
3649 
3650  //**Friend declarations*************************************************************************
3651  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CRAs2 > friend class Rows;
3652  //**********************************************************************************************
3653 
3654  //**Compile time checks*************************************************************************
3664  //**********************************************************************************************
3665 };
3667 //*************************************************************************************************
3668 
3669 
3670 
3671 
3672 //=================================================================================================
3673 //
3674 // CONSTRUCTORS
3675 //
3676 //=================================================================================================
3677 
3678 //*************************************************************************************************
3691 template< typename MT // Type of the dense matrix
3692  , typename... CRAs > // Compile time row arguments
3693 template< typename... RRAs > // Runtime row arguments
3694 inline Rows<MT,false,true,false,CRAs...>::Rows( MT& matrix, RRAs... args )
3695  : DataType( args... ) // Base class initialization
3696  , matrix_ ( matrix ) // The matrix containing the rows
3697 {
3698  if( !Contains_v< TypeList<RRAs...>, Unchecked > ) {
3699  for( size_t i=0UL; i<rows(); ++i ) {
3700  if( matrix_.rows() <= idx(i) ) {
3701  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
3702  }
3703  }
3704  }
3705 }
3707 //*************************************************************************************************
3708 
3709 
3710 
3711 
3712 //=================================================================================================
3713 //
3714 // DATA ACCESS FUNCTIONS
3715 //
3716 //=================================================================================================
3717 
3718 //*************************************************************************************************
3729 template< typename MT // Type of the dense matrix
3730  , typename... CRAs > // Compile time row arguments
3731 inline typename Rows<MT,false,true,false,CRAs...>::Reference
3732  Rows<MT,false,true,false,CRAs...>::operator()( size_t i, size_t j )
3733 {
3734  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3735  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3736 
3737  return matrix_(idx(i),j);
3738 }
3740 //*************************************************************************************************
3741 
3742 
3743 //*************************************************************************************************
3754 template< typename MT // Type of the dense matrix
3755  , typename... CRAs > // Compile time row arguments
3756 inline typename Rows<MT,false,true,false,CRAs...>::ConstReference
3757  Rows<MT,false,true,false,CRAs...>::operator()( size_t i, size_t j ) const
3758 {
3759  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3760  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3761 
3762  return const_cast<const MT&>( matrix_ )(idx(i),j);
3763 }
3765 //*************************************************************************************************
3766 
3767 
3768 //*************************************************************************************************
3780 template< typename MT // Type of the dense matrix
3781  , typename... CRAs > // Compile time row arguments
3782 inline typename Rows<MT,false,true,false,CRAs...>::Reference
3783  Rows<MT,false,true,false,CRAs...>::at( size_t i, size_t j )
3784 {
3785  if( i >= rows() ) {
3786  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3787  }
3788  if( j >= columns() ) {
3789  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3790  }
3791  return (*this)(i,j);
3792 }
3794 //*************************************************************************************************
3795 
3796 
3797 //*************************************************************************************************
3809 template< typename MT // Type of the dense matrix
3810  , typename... CRAs > // Compile time row arguments
3811 inline typename Rows<MT,false,true,false,CRAs...>::ConstReference
3812  Rows<MT,false,true,false,CRAs...>::at( size_t i, size_t j ) const
3813 {
3814  if( i >= rows() ) {
3815  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3816  }
3817  if( j >= columns() ) {
3818  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3819  }
3820  return (*this)(i,j);
3821 }
3823 //*************************************************************************************************
3824 
3825 
3826 //*************************************************************************************************
3836 template< typename MT // Type of the dense matrix
3837  , typename... CRAs > // Compile time row arguments
3838 inline typename Rows<MT,false,true,false,CRAs...>::Pointer
3840 {
3841  return matrix_.data() + idx(0UL);
3842 }
3844 //*************************************************************************************************
3845 
3846 
3847 //*************************************************************************************************
3857 template< typename MT // Type of the dense matrix
3858  , typename... CRAs > // Compile time row arguments
3859 inline typename Rows<MT,false,true,false,CRAs...>::ConstPointer
3861 {
3862  return matrix_.data() + idx(0UL);
3863 }
3865 //*************************************************************************************************
3866 
3867 
3868 //*************************************************************************************************
3877 template< typename MT // Type of the dense matrix
3878  , typename... CRAs > // Compile time row arguments
3879 inline typename Rows<MT,false,true,false,CRAs...>::Pointer
3880  Rows<MT,false,true,false,CRAs...>::data( size_t i ) noexcept
3881 {
3882  return matrix_.data() + idx(i);
3883 }
3885 //*************************************************************************************************
3886 
3887 
3888 //*************************************************************************************************
3897 template< typename MT // Type of the dense matrix
3898  , typename... CRAs > // Compile time row arguments
3899 inline typename Rows<MT,false,true,false,CRAs...>::ConstPointer
3900  Rows<MT,false,true,false,CRAs...>::data( size_t i ) const noexcept
3901 {
3902  return matrix_.data() + idx(i);
3903 }
3905 //*************************************************************************************************
3906 
3907 
3908 //*************************************************************************************************
3917 template< typename MT // Type of the dense matrix
3918  , typename... CRAs > // Compile time row arguments
3919 inline typename Rows<MT,false,true,false,CRAs...>::Iterator
3921 {
3922  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3923  return Iterator( matrix_, idx(i), 0UL );
3924 }
3926 //*************************************************************************************************
3927 
3928 
3929 //*************************************************************************************************
3938 template< typename MT // Type of the dense matrix
3939  , typename... CRAs > // Compile time row arguments
3940 inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
3942 {
3943  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3944  return ConstIterator( matrix_, idx(i), 0UL );
3945 }
3947 //*************************************************************************************************
3948 
3949 
3950 //*************************************************************************************************
3959 template< typename MT // Type of the dense matrix
3960  , typename... CRAs > // Compile time row arguments
3961 inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
3963 {
3964  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3965  return ConstIterator( matrix_, idx(i), 0UL );
3966 }
3968 //*************************************************************************************************
3969 
3970 
3971 //*************************************************************************************************
3980 template< typename MT // Type of the dense matrix
3981  , typename... CRAs > // Compile time row arguments
3982 inline typename Rows<MT,false,true,false,CRAs...>::Iterator
3984 {
3985  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3986  return Iterator( matrix_, idx(i), columns() );
3987 }
3989 //*************************************************************************************************
3990 
3991 
3992 //*************************************************************************************************
4001 template< typename MT // Type of the dense matrix
4002  , typename... CRAs > // Compile time row arguments
4003 inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
4004  Rows<MT,false,true,false,CRAs...>::end( size_t i ) const
4005 {
4006  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4007  return ConstIterator( matrix_, idx(i), columns() );
4008 }
4010 //*************************************************************************************************
4011 
4012 
4013 //*************************************************************************************************
4022 template< typename MT // Type of the dense matrix
4023  , typename... CRAs > // Compile time row arguments
4024 inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
4025  Rows<MT,false,true,false,CRAs...>::cend( size_t i ) const
4026 {
4027  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4028  return ConstIterator( matrix_, idx(i), columns() );
4029 }
4031 //*************************************************************************************************
4032 
4033 
4034 
4035 
4036 //=================================================================================================
4037 //
4038 // ASSIGNMENT OPERATORS
4039 //
4040 //=================================================================================================
4041 
4042 //*************************************************************************************************
4053 template< typename MT // Type of the dense matrix
4054  , typename... CRAs > // Compile time row arguments
4055 inline Rows<MT,false,true,false,CRAs...>&
4056  Rows<MT,false,true,false,CRAs...>::operator=( const ElementType& rhs )
4057 {
4058  for( size_t i=0UL; i<rows(); ++i ) {
4059  row( matrix_, idx(i), unchecked ) = rhs;
4060  }
4061 
4062  return *this;
4063 }
4065 //*************************************************************************************************
4066 
4067 
4068 //*************************************************************************************************
4084 template< typename MT // Type of the dense matrix
4085  , typename... CRAs > // Compile time row arguments
4086 inline Rows<MT,false,true,false,CRAs...>&
4087  Rows<MT,false,true,false,CRAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
4088 {
4091 
4092  if( list.size() != rows() ) {
4093  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row selection" );
4094  }
4095 
4096  if( IsRestricted_v<MT> ) {
4097  size_t i( 0UL );
4098  for( const auto& rowList : list ) {
4099  const InitializerVector<ElementType> tmp( rowList, columns() );
4100  if( !tryAssign( row( matrix_, idx(i), unchecked ), tmp, 0UL ) ){
4101  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4102  }
4103  ++i;
4104  }
4105  }
4106 
4107  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4108  size_t i( 0UL );
4109 
4110  for( const auto& rowList : list ) {
4111  std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
4112  ++i;
4113  }
4114 
4115  return *this;
4116 }
4118 //*************************************************************************************************
4119 
4120 
4121 //*************************************************************************************************
4136 template< typename MT // Type of the dense matrix
4137  , typename... CRAs > // Compile time row arguments
4138 inline Rows<MT,false,true,false,CRAs...>&
4139  Rows<MT,false,true,false,CRAs...>::operator=( const Rows& rhs )
4140 {
4143 
4146 
4147  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
4148  return *this;
4149 
4150  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
4151  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4152  }
4153 
4154  if( IsRestricted_v<MT> ) {
4155  for( size_t i=0UL; i<rows(); ++i ) {
4156  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( rhs, i, unchecked ), 0UL ) ) {
4157  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4158  }
4159  }
4160  }
4161 
4162  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4163 
4164  if( rhs.canAlias( &matrix_ ) ) {
4165  const ResultType tmp( rhs );
4166  smpAssign( left, tmp );
4167  }
4168  else {
4169  smpAssign( left, rhs );
4170  }
4171 
4172  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4173 
4174  return *this;
4175 }
4177 //*************************************************************************************************
4178 
4179 
4180 //*************************************************************************************************
4195 template< typename MT // Type of the dense matrix
4196  , typename... CRAs > // Compile time row arguments
4197 template< typename MT2 // Type of the right-hand side matrix
4198  , bool SO2 > // Storage order of the right-hand side matrix
4199 inline Rows<MT,false,true,false,CRAs...>&
4200  Rows<MT,false,true,false,CRAs...>::operator=( const Matrix<MT2,SO2>& rhs )
4201 {
4204 
4205  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4206 
4207  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4208  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4209  }
4210 
4211  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
4212  Right right( ~rhs );
4213 
4214  if( IsRestricted_v<MT> ) {
4215  for( size_t i=0UL; i<rows(); ++i ) {
4216  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( right, i, unchecked ), 0UL ) ) {
4217  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4218  }
4219  }
4220  }
4221 
4222  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4223 
4224  if( IsSparseMatrix_v<MT2> ) {
4225  reset();
4226  }
4227 
4228  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
4229  const ResultType_t<MT2> tmp( right );
4230  smpAssign( left, tmp );
4231  }
4232  else {
4233  smpAssign( left, right );
4234  }
4235 
4236  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4237 
4238  return *this;
4239 }
4241 //*************************************************************************************************
4242 
4243 
4244 //*************************************************************************************************
4258 template< typename MT // Type of the dense matrix
4259  , typename... CRAs > // Compile time row arguments
4260 template< typename MT2 // Type of the right-hand side matrix
4261  , bool SO2 > // Storage order of the right-hand side matrix
4262 inline auto Rows<MT,false,true,false,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4263  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4264 {
4267 
4270  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4271 
4272  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4273 
4276 
4277  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4278  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4279  }
4280 
4281  if( IsRestricted_v<MT> ) {
4282  for( size_t i=0UL; i<rows(); ++i ) {
4283  if( !tryAddAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
4284  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4285  }
4286  }
4287  }
4288 
4289  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4290 
4291  if( (~rhs).canAlias( &matrix_ ) ) {
4292  const AddType tmp( *this + (~rhs) );
4293  smpAssign( left, tmp );
4294  }
4295  else {
4296  smpAddAssign( left, ~rhs );
4297  }
4298 
4299  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4300 
4301  return *this;
4302 }
4304 //*************************************************************************************************
4305 
4306 
4307 //*************************************************************************************************
4321 template< typename MT // Type of the dense matrix
4322  , typename... CRAs > // Compile time row arguments
4323 template< typename MT2 // Type of the right-hand side matrix
4324  , bool SO2 > // Storage order of the right-hand side matrix
4325 inline auto Rows<MT,false,true,false,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4326  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4327 {
4330 
4333  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4334 
4335  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4336 
4339 
4340  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4341  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4342  }
4343 
4344  const AddType tmp( *this + (~rhs) );
4345 
4346  if( IsRestricted_v<MT> ) {
4347  for( size_t i=0UL; i<rows(); ++i ) {
4348  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
4349  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4350  }
4351  }
4352  }
4353 
4354  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4355 
4356  smpAssign( left, tmp );
4357 
4358  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4359 
4360  return *this;
4361 }
4363 //*************************************************************************************************
4364 
4365 
4366 //*************************************************************************************************
4380 template< typename MT // Type of the dense matrix
4381  , typename... CRAs > // Compile time row arguments
4382 template< typename MT2 // Type of the right-hand side matrix
4383  , bool SO2 > // Storage order of the right-hand side matrix
4384 inline auto Rows<MT,false,true,false,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4385  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4386 {
4389 
4392  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4393 
4394  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4395 
4398 
4399  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4400  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4401  }
4402 
4403  if( IsRestricted_v<MT> ) {
4404  for( size_t i=0UL; i<rows(); ++i ) {
4405  if( !trySubAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
4406  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4407  }
4408  }
4409  }
4410 
4411  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4412 
4413  if( (~rhs).canAlias( &matrix_ ) ) {
4414  const SubType tmp( *this - (~rhs ) );
4415  smpAssign( left, tmp );
4416  }
4417  else {
4418  smpSubAssign( left, ~rhs );
4419  }
4420 
4421  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4422 
4423  return *this;
4424 }
4426 //*************************************************************************************************
4427 
4428 
4429 //*************************************************************************************************
4443 template< typename MT // Type of the dense matrix
4444  , typename... CRAs > // Compile time row arguments
4445 template< typename MT2 // Type of the right-hand side matrix
4446  , bool SO2 > // Storage order of the right-hand side matrix
4447 inline auto Rows<MT,false,true,false,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4448  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4449 {
4452 
4455  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4456 
4457  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4458 
4461 
4462  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4463  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4464  }
4465 
4466  const SubType tmp( *this - (~rhs) );
4467 
4468  if( IsRestricted_v<MT> ) {
4469  for( size_t i=0UL; i<rows(); ++i ) {
4470  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
4471  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4472  }
4473  }
4474  }
4475 
4476  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4477 
4478  smpAssign( left, tmp );
4479 
4480  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4481 
4482  return *this;
4483 }
4485 //*************************************************************************************************
4486 
4487 
4488 //*************************************************************************************************
4502 template< typename MT // Type of the dense matrix
4503  , typename... CRAs > // Compile time row arguments
4504 template< typename MT2 // Type of the right-hand side matrix
4505  , bool SO2 > // Storage order of the right-hand side matrix
4506 inline auto Rows<MT,false,true,false,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4507  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4508 {
4511 
4514  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4515 
4516  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4517 
4519 
4520  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4521  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4522  }
4523 
4524  if( IsRestricted_v<MT> ) {
4525  for( size_t i=0UL; i<rows(); ++i ) {
4526  if( !tryMultAssign( row( matrix_, idx(i), unchecked ), row( ~rhs, i, unchecked ), 0UL ) ) {
4527  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4528  }
4529  }
4530  }
4531 
4532  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4533 
4534  if( (~rhs).canAlias( &matrix_ ) ) {
4535  const SchurType tmp( *this % (~rhs) );
4536  if( IsSparseMatrix_v<SchurType> )
4537  reset();
4538  smpAssign( left, tmp );
4539  }
4540  else {
4541  smpSchurAssign( left, ~rhs );
4542  }
4543 
4544  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4545 
4546  return *this;
4547 }
4549 //*************************************************************************************************
4550 
4551 
4552 //*************************************************************************************************
4566 template< typename MT // Type of the dense matrix
4567  , typename... CRAs > // Compile time row arguments
4568 template< typename MT2 // Type of the right-hand side matrix
4569  , bool SO2 > // Storage order of the right-hand side matrix
4570 inline auto Rows<MT,false,true,false,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4571  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4572 {
4575 
4578  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4579 
4580  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4581 
4583 
4584  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4585  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4586  }
4587 
4588  const SchurType tmp( *this % (~rhs) );
4589 
4590  if( IsRestricted_v<MT> ) {
4591  for( size_t i=0UL; i<rows(); ++i ) {
4592  if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
4593  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4594  }
4595  }
4596  }
4597 
4598  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4599 
4600  if( IsSparseMatrix_v<SchurType> ) {
4601  reset();
4602  }
4603 
4604  smpAssign( left, tmp );
4605 
4606  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4607 
4608  return *this;
4609 }
4611 //*************************************************************************************************
4612 
4613 
4614 
4615 
4616 //=================================================================================================
4617 //
4618 // UTILITY FUNCTIONS
4619 //
4620 //=================================================================================================
4621 
4622 //*************************************************************************************************
4628 template< typename MT // Type of the dense matrix
4629  , typename... CRAs > // Compile time row arguments
4630 inline MT& Rows<MT,false,true,false,CRAs...>::operand() noexcept
4631 {
4632  return matrix_;
4633 }
4635 //*************************************************************************************************
4636 
4637 
4638 //*************************************************************************************************
4644 template< typename MT // Type of the dense matrix
4645  , typename... CRAs > // Compile time row arguments
4646 inline const MT& Rows<MT,false,true,false,CRAs...>::operand() const noexcept
4647 {
4648  return matrix_;
4649 }
4651 //*************************************************************************************************
4652 
4653 
4654 //*************************************************************************************************
4660 template< typename MT // Type of the dense matrix
4661  , typename... CRAs > // Compile time row arguments
4662 inline size_t Rows<MT,false,true,false,CRAs...>::columns() const noexcept
4663 {
4664  return matrix_.columns();
4665 }
4667 //*************************************************************************************************
4668 
4669 
4670 //*************************************************************************************************
4679 template< typename MT // Type of the dense matrix
4680  , typename... CRAs > // Compile time row arguments
4681 inline size_t Rows<MT,false,true,false,CRAs...>::spacing() const noexcept
4682 {
4683  return matrix_.columns();
4684 }
4686 //*************************************************************************************************
4687 
4688 
4689 //*************************************************************************************************
4695 template< typename MT // Type of the dense matrix
4696  , typename... CRAs > // Compile time row arguments
4697 inline size_t Rows<MT,false,true,false,CRAs...>::capacity() const noexcept
4698 {
4699  return rows() * columns();
4700 }
4702 //*************************************************************************************************
4703 
4704 
4705 //*************************************************************************************************
4714 template< typename MT // Type of the dense matrix
4715  , typename... CRAs > // Compile time row arguments
4716 inline size_t Rows<MT,false,true,false,CRAs...>::capacity( size_t i ) const noexcept
4717 {
4718  UNUSED_PARAMETER( i );
4719 
4720  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4721 
4722  return columns();
4723 }
4725 //*************************************************************************************************
4726 
4727 
4728 //*************************************************************************************************
4734 template< typename MT // Type of the dense matrix
4735  , typename... CRAs > // Compile time row arguments
4736 inline size_t Rows<MT,false,true,false,CRAs...>::nonZeros() const
4737 {
4738  size_t nonzeros( 0UL );
4739 
4740  for( size_t i=0UL; i<rows(); ++i ) {
4741  nonzeros += nonZeros( i );
4742  }
4743 
4744  return nonzeros;
4745 }
4747 //*************************************************************************************************
4748 
4749 
4750 //*************************************************************************************************
4759 template< typename MT // Type of the dense matrix
4760  , typename... CRAs > // Compile time row arguments
4761 inline size_t Rows<MT,false,true,false,CRAs...>::nonZeros( size_t i ) const
4762 {
4763  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4764 
4765  size_t nonzeros( 0UL );
4766 
4767  const size_t index( idx(i) );
4768  for( size_t j=0UL; j<columns(); ++j ) {
4769  if( !isDefault( matrix_( index, j ) ) )
4770  ++nonzeros;
4771  }
4772 
4773  return nonzeros;
4774 }
4776 //*************************************************************************************************
4777 
4778 
4779 //*************************************************************************************************
4785 template< typename MT // Type of the dense matrix
4786  , typename... CRAs > // Compile time row arguments
4788 {
4789  for( size_t i=0UL; i<rows(); ++i ) {
4790  reset( i );
4791  }
4792 }
4794 //*************************************************************************************************
4795 
4796 
4797 //*************************************************************************************************
4806 template< typename MT // Type of the dense matrix
4807  , typename... CRAs > // Compile time row arguments
4808 inline void Rows<MT,false,true,false,CRAs...>::reset( size_t i )
4809 {
4810  using blaze::reset;
4811 
4812  const size_t index( idx(i) );
4813  for( size_t j=0UL; j<columns(); ++j ) {
4814  reset( matrix_( index, j ) );
4815  }
4816 }
4818 //*************************************************************************************************
4819 
4820 
4821 
4822 
4823 //=================================================================================================
4824 //
4825 // NUMERIC FUNCTIONS
4826 //
4827 //=================================================================================================
4828 
4829 //*************************************************************************************************
4842 template< typename MT // Type of the dense matrix
4843  , typename... CRAs > // Compile time row arguments
4844 inline Rows<MT,false,true,false,CRAs...>&
4846 {
4849 
4850  if( rows() != columns() ) {
4851  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4852  }
4853 
4854  const ResultType tmp( trans( *this ) );
4855 
4856  if( IsRestricted_v<MT> ) {
4857  for( size_t i=0UL; i<rows(); ++i ) {
4858  if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
4859  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4860  }
4861  }
4862  }
4863 
4864  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4865 
4866  smpAssign( left, tmp );
4867 
4868  return *this;
4869 }
4871 //*************************************************************************************************
4872 
4873 
4874 //*************************************************************************************************
4887 template< typename MT // Type of the dense matrix
4888  , typename... CRAs > // Compile time row arguments
4889 inline Rows<MT,false,true,false,CRAs...>&
4891 {
4894 
4895  if( rows() != columns() ) {
4896  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4897  }
4898 
4899  const ResultType tmp( ctrans( *this ) );
4900 
4901  if( IsRestricted_v<MT> ) {
4902  for( size_t i=0UL; i<rows(); ++i ) {
4903  if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
4904  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4905  }
4906  }
4907  }
4908 
4909  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4910 
4911  smpAssign( left, tmp );
4912 
4913  return *this;
4914 }
4916 //*************************************************************************************************
4917 
4918 
4919 //*************************************************************************************************
4932 template< typename MT // Type of the dense matrix
4933  , typename... CRAs > // Compile time row arguments
4934 template< typename Other > // Data type of the scalar value
4935 inline Rows<MT,false,true,false,CRAs...>&
4936  Rows<MT,false,true,false,CRAs...>::scale( const Other& scalar )
4937 {
4941 
4942  for( size_t i=0UL; i<rows(); ++i )
4943  {
4944  const size_t index ( idx(i) );
4945  const size_t jbegin( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index+1UL : index ) : 0UL );
4946  const size_t jend ( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index : index+1UL ) : columns() );
4947 
4948  for( size_t j=jbegin; j<jend; ++j ) {
4949  matrix_(index,j) *= scalar;
4950  }
4951  }
4952 
4953  return *this;
4954 }
4956 //*************************************************************************************************
4957 
4958 
4959 
4960 
4961 //=================================================================================================
4962 //
4963 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4964 //
4965 //=================================================================================================
4966 
4967 //*************************************************************************************************
4978 template< typename MT // Type of the dense matrix
4979  , typename... CRAs > // Compile time row arguments
4980 template< typename Other > // Data type of the foreign expression
4981 inline bool Rows<MT,false,true,false,CRAs...>::canAlias( const Other* alias ) const noexcept
4982 {
4983  return matrix_.isAliased( alias );
4984 }
4986 //*************************************************************************************************
4987 
4988 
4989 //*************************************************************************************************
5001 template< typename MT // Type of the dense matrix
5002  , typename... CRAs > // Compile time row arguments
5003 template< typename MT2 // Data type of the foreign dense row selection
5004  , bool SO2 // Storage order of the foreign dense row selection
5005  , bool SF2 // Symmetry flag of the foreign dense row selection
5006  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
5007 inline bool
5008  Rows<MT,false,true,false,CRAs...>::canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
5009 {
5010  return matrix_.isAliased( &alias->matrix_ );
5011 }
5013 //*************************************************************************************************
5014 
5015 
5016 //*************************************************************************************************
5027 template< typename MT // Type of the dense matrix
5028  , typename... CRAs > // Compile time row arguments
5029 template< typename Other > // Data type of the foreign expression
5030 inline bool Rows<MT,false,true,false,CRAs...>::isAliased( const Other* alias ) const noexcept
5031 {
5032  return matrix_.isAliased( alias );
5033 }
5035 //*************************************************************************************************
5036 
5037 
5038 //*************************************************************************************************
5050 template< typename MT // Type of the dense matrix
5051  , typename... CRAs > // Compile time row arguments
5052 template< typename MT2 // Data type of the foreign dense row selection
5053  , bool SO2 // Storage order of the foreign dense row selection
5054  , bool SF2 // Symmetry flag of the foreign dense row selection
5055  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
5056 inline bool
5057  Rows<MT,false,true,false,CRAs...>::isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
5058 {
5059  return matrix_.isAliased( &alias->matrix_ );
5060 }
5062 //*************************************************************************************************
5063 
5064 
5065 //*************************************************************************************************
5075 template< typename MT // Type of the dense matrix
5076  , typename... CRAs > // Compile time row arguments
5077 inline bool Rows<MT,false,true,false,CRAs...>::isAligned() const noexcept
5078 {
5079  return false;
5080 }
5082 //*************************************************************************************************
5083 
5084 
5085 //*************************************************************************************************
5096 template< typename MT // Type of the dense matrix
5097  , typename... CRAs > // Compile time row arguments
5098 inline bool Rows<MT,false,true,false,CRAs...>::canSMPAssign() const noexcept
5099 {
5100  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
5101 }
5103 //*************************************************************************************************
5104 
5105 
5106 //*************************************************************************************************
5118 template< typename MT // Type of the dense matrix
5119  , typename... CRAs > // Compile time row arguments
5120 template< typename MT2 > // Type of the right-hand side dense matrix
5121 inline void Rows<MT,false,true,false,CRAs...>::assign( const DenseMatrix<MT2,false>& rhs )
5122 {
5125 
5126  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5127  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5128 
5129  const size_t jpos( columns() & size_t(-2) );
5130  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
5131 
5132  for( size_t i=0UL; i<rows(); ++i ) {
5133  const size_t index( idx(i) );
5134  for( size_t j=0UL; j<jpos; j+=2UL ) {
5135  matrix_(index,j ) = (~rhs)(i,j );
5136  matrix_(index,j+1UL) = (~rhs)(i,j+1UL);
5137  }
5138  if( jpos < columns() ) {
5139  matrix_(index,jpos) = (~rhs)(i,jpos);
5140  }
5141  }
5142 }
5144 //*************************************************************************************************
5145 
5146 
5147 //*************************************************************************************************
5159 template< typename MT // Type of the dense matrix
5160  , typename... CRAs > // Compile time row arguments
5161 template< typename MT2 > // Type of the right-hand side dense matrix
5162 inline void Rows<MT,false,true,false,CRAs...>::assign( const DenseMatrix<MT2,true>& rhs )
5163 {
5166 
5168 
5169  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5170  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5171 
5172  constexpr size_t block( BLOCK_SIZE );
5173 
5174  if( rows() < block && columns() < block )
5175  {
5176  const size_t jpos( (~rhs).columns() & size_t(-2) );
5177  for( size_t i=0UL; i<rows(); ++i ) {
5178  const size_t index( idx(i) );
5179  for( size_t j=0UL; j<jpos; j+=2UL ) {
5180  matrix_(index,j ) = (~rhs)(i,j );
5181  matrix_(index,j+1UL) = (~rhs)(i,j+1UL);
5182  }
5183  if( jpos < (~rhs).columns() )
5184  matrix_(index,jpos) = (~rhs)(i,jpos);
5185  }
5186  }
5187  else
5188  {
5189  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5190  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5191  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5192  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5193  for( size_t i=ii; i<iend; ++i ) {
5194  const size_t index( idx(i) );
5195  for( size_t j=jj; j<jend; ++j ) {
5196  matrix_(index,j) = (~rhs)(i,j);
5197  }
5198  }
5199  }
5200  }
5201  }
5202 }
5204 //*************************************************************************************************
5205 
5206 
5207 //*************************************************************************************************
5219 template< typename MT // Type of the dense matrix
5220  , typename... CRAs > // Compile time row arguments
5221 template< typename MT2 > // Type of the right-hand side sparse matrix
5222 inline void Rows<MT,false,true,false,CRAs...>::assign( const SparseMatrix<MT2,false>& rhs )
5223 {
5226 
5227  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5228  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5229 
5230  for( size_t i=0UL; i<rows(); ++i ) {
5231  const size_t index( idx(i) );
5232  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5233  matrix_(index,element->index()) = element->value();
5234  }
5235 }
5237 //*************************************************************************************************
5238 
5239 
5240 //*************************************************************************************************
5252 template< typename MT // Type of the dense matrix
5253  , typename... CRAs > // Compile time row arguments
5254 template< typename MT2 > // Type of the right-hand side sparse matrix
5255 inline void Rows<MT,false,true,false,CRAs...>::assign( const SparseMatrix<MT2,true>& rhs )
5256 {
5259 
5261 
5262  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5263  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5264 
5265  for( size_t j=0UL; j<columns(); ++j ) {
5266  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5267  matrix_(idx(element->index()),j) = element->value();
5268  }
5269 }
5271 //*************************************************************************************************
5272 
5273 
5274 //*************************************************************************************************
5286 template< typename MT // Type of the dense matrix
5287  , typename... CRAs > // Compile time row arguments
5288 template< typename MT2 > // Type of the right-hand side dense matrix
5289 inline void Rows<MT,false,true,false,CRAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
5290 {
5293 
5294  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5295  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5296 
5297  const size_t jpos( columns() & size_t(-2) );
5298  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
5299 
5300  for( size_t i=0UL; i<rows(); ++i )
5301  {
5302  const size_t index( idx(i) );
5303  if( IsDiagonal_v<MT2> ) {
5304  matrix_(index,i) += (~rhs)(i,i);
5305  }
5306  else {
5307  for( size_t j=0UL; j<jpos; j+=2UL ) {
5308  matrix_(index,j ) += (~rhs)(i,j );
5309  matrix_(index,j+1UL) += (~rhs)(i,j+1UL);
5310  }
5311  if( jpos < columns() ) {
5312  matrix_(index,jpos) += (~rhs)(i,jpos);
5313  }
5314  }
5315  }
5316 }
5318 //*************************************************************************************************
5319 
5320 
5321 //*************************************************************************************************
5333 template< typename MT // Type of the dense matrix
5334  , typename... CRAs > // Compile time row arguments
5335 template< typename MT2 > // Type of the right-hand side dense matrix
5336 inline void Rows<MT,false,true,false,CRAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
5337 {
5340 
5342 
5343  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5344  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5345 
5346  constexpr size_t block( BLOCK_SIZE );
5347 
5348  if( rows() < block && columns() < block )
5349  {
5350  const size_t jpos( (~rhs).columns() & size_t(-2) );
5351  for( size_t i=0UL; i<rows(); ++i ) {
5352  const size_t index( idx(i) );
5353  for( size_t j=0UL; j<jpos; j+=2UL ) {
5354  matrix_(index,j ) += (~rhs)(i,j );
5355  matrix_(index,j+1UL) += (~rhs)(i,j+1UL);
5356  }
5357  if( jpos < (~rhs).columns() )
5358  matrix_(index,jpos) += (~rhs)(i,jpos);
5359  }
5360  }
5361  else
5362  {
5363  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5364  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5365  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5366  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5367  for( size_t i=ii; i<iend; ++i ) {
5368  const size_t index( idx(i) );
5369  for( size_t j=jj; j<jend; ++j ) {
5370  matrix_(index,j) += (~rhs)(i,j);
5371  }
5372  }
5373  }
5374  }
5375  }
5376 }
5378 //*************************************************************************************************
5379 
5380 
5381 //*************************************************************************************************
5393 template< typename MT // Type of the dense matrix
5394  , typename... CRAs > // Compile time row arguments
5395 template< typename MT2 > // Type of the right-hand side sparse matrix
5396 inline void Rows<MT,false,true,false,CRAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
5397 {
5400 
5401  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5402  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5403 
5404  for( size_t i=0UL; i<rows(); ++i ) {
5405  const size_t index( idx(i) );
5406  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5407  matrix_(index,element->index()) += element->value();
5408  }
5409 }
5411 //*************************************************************************************************
5412 
5413 
5414 //*************************************************************************************************
5426 template< typename MT // Type of the dense matrix
5427  , typename... CRAs > // Compile time row arguments
5428 template< typename MT2 > // Type of the right-hand side sparse matrix
5429 inline void Rows<MT,false,true,false,CRAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
5430 {
5433 
5435 
5436  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5437  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5438 
5439  for( size_t j=0UL; j<columns(); ++j ) {
5440  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5441  matrix_(idx(element->index()),j) += element->value();
5442  }
5443 }
5445 //*************************************************************************************************
5446 
5447 
5448 //*************************************************************************************************
5460 template< typename MT // Type of the dense matrix
5461  , typename... CRAs > // Compile time row arguments
5462 template< typename MT2 > // Type of the right-hand side dense matrix
5463 inline void Rows<MT,false,true,false,CRAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
5464 {
5467 
5468  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5469  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5470 
5471  const size_t jpos( columns() & size_t(-2) );
5472  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
5473 
5474  for( size_t i=0UL; i<rows(); ++i )
5475  {
5476  const size_t index( idx(i) );
5477 
5478  if( IsDiagonal_v<MT2> ) {
5479  matrix_(index,i) -= (~rhs)(i,i);
5480  }
5481  else {
5482  for( size_t j=0UL; j<jpos; j+=2UL ) {
5483  matrix_(index,j ) -= (~rhs)(i,j );
5484  matrix_(index,j+1UL) -= (~rhs)(i,j+1UL);
5485  }
5486  if( jpos < columns() ) {
5487  matrix_(index,jpos) -= (~rhs)(i,jpos);
5488  }
5489  }
5490  }
5491 }
5493 //*************************************************************************************************
5494 
5495 
5496 //*************************************************************************************************
5508 template< typename MT // Type of the dense matrix
5509  , typename... CRAs > // Compile time row arguments
5510 template< typename MT2 > // Type of the right-hand side dense matrix
5511 inline void Rows<MT,false,true,false,CRAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
5512 {
5515 
5517 
5518  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5519  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5520 
5521  constexpr size_t block( BLOCK_SIZE );
5522 
5523  if( rows() < block && columns() < block )
5524  {
5525  const size_t jpos( (~rhs).columns() & size_t(-2) );
5526  for( size_t i=0UL; i<rows(); ++i ) {
5527  const size_t index( idx(i) );
5528  for( size_t j=0UL; j<jpos; j+=2UL ) {
5529  matrix_(index,j ) -= (~rhs)(i,j );
5530  matrix_(index,j+1UL) -= (~rhs)(i,j+1UL);
5531  }
5532  if( jpos < (~rhs).columns() )
5533  matrix_(index,jpos) -= (~rhs)(i,jpos);
5534  }
5535  }
5536  else
5537  {
5538  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5539  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5540  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5541  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5542  for( size_t i=ii; i<iend; ++i ) {
5543  const size_t index( idx(i) );
5544  for( size_t j=jj; j<jend; ++j ) {
5545  matrix_(index,j) -= (~rhs)(i,j);
5546  }
5547  }
5548  }
5549  }
5550  }
5551 }
5553 //*************************************************************************************************
5554 
5555 
5556 //*************************************************************************************************
5568 template< typename MT // Type of the dense matrix
5569  , typename... CRAs > // Compile time row arguments
5570 template< typename MT2 > // Type of the right-hand side sparse matrix
5571 inline void Rows<MT,false,true,false,CRAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
5572 {
5575 
5576  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5577  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5578 
5579  for( size_t i=0UL; i<rows(); ++i ) {
5580  const size_t index( idx(i) );
5581  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5582  matrix_(index,element->index()) -= element->value();
5583  }
5584 }
5586 //*************************************************************************************************
5587 
5588 
5589 //*************************************************************************************************
5601 template< typename MT // Type of the dense matrix
5602  , typename... CRAs > // Compile time row arguments
5603 template< typename MT2 > // Type of the right-hand side sparse matrix
5604 inline void Rows<MT,false,true,false,CRAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
5605 {
5608 
5610 
5611  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5612  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5613 
5614  for( size_t j=0UL; j<columns(); ++j ) {
5615  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5616  matrix_(idx(element->index()),j) -= element->value();
5617  }
5618 }
5620 //*************************************************************************************************
5621 
5622 
5623 //*************************************************************************************************
5635 template< typename MT // Type of the dense matrix
5636  , typename... CRAs > // Compile time row arguments
5637 template< typename MT2 > // Type of the right-hand side dense matrix
5638 inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
5639 {
5642 
5643  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5644  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5645 
5646  const size_t jpos( columns() & size_t(-2) );
5647  BLAZE_INTERNAL_ASSERT( ( columns() - ( columns() % 2UL ) ) == jpos, "Invalid end calculation" );
5648 
5649  for( size_t i=0UL; i<rows(); ++i ) {
5650  const size_t index( idx(i) );
5651  for( size_t j=0UL; j<jpos; j+=2UL ) {
5652  matrix_(index,j ) *= (~rhs)(i,j );
5653  matrix_(index,j+1UL) *= (~rhs)(i,j+1UL);
5654  }
5655  if( jpos < columns() ) {
5656  matrix_(index,jpos) *= (~rhs)(i,jpos);
5657  }
5658  }
5659 }
5661 //*************************************************************************************************
5662 
5663 
5664 //*************************************************************************************************
5676 template< typename MT // Type of the dense matrix
5677  , typename... CRAs > // Compile time row arguments
5678 template< typename MT2 > // Type of the right-hand side dense matrix
5679 inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
5680 {
5683 
5685 
5686  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5687  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5688 
5689  constexpr size_t block( BLOCK_SIZE );
5690 
5691  if( rows() < block && columns() < block )
5692  {
5693  const size_t jpos( (~rhs).columns() & size_t(-2) );
5694  for( size_t i=0UL; i<rows(); ++i ) {
5695  const size_t index( idx(i) );
5696  for( size_t j=0UL; j<jpos; j+=2UL ) {
5697  matrix_(index,j ) *= (~rhs)(i,j );
5698  matrix_(index,j+1UL) *= (~rhs)(i,j+1UL);
5699  }
5700  if( jpos < (~rhs).columns() )
5701  matrix_(index,jpos) *= (~rhs)(i,jpos);
5702  }
5703  }
5704  else
5705  {
5706  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5707  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5708  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5709  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5710  for( size_t i=ii; i<iend; ++i ) {
5711  const size_t index( idx(i) );
5712  for( size_t j=jj; j<jend; ++j ) {
5713  matrix_(index,j) *= (~rhs)(i,j);
5714  }
5715  }
5716  }
5717  }
5718  }
5719 }
5721 //*************************************************************************************************
5722 
5723 
5724 //*************************************************************************************************
5736 template< typename MT // Type of the dense matrix
5737  , typename... CRAs > // Compile time row arguments
5738 template< typename MT2 > // Type of the right-hand side sparse matrix
5739 inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
5740 {
5741  using blaze::reset;
5742 
5745 
5746  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5747  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5748 
5749  for( size_t i=0UL; i<rows(); ++i )
5750  {
5751  const size_t index( idx(i) );
5752  size_t j( 0UL );
5753 
5754  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
5755  for( ; j<element->index(); ++j )
5756  reset( matrix_(index,j) );
5757  matrix_(index,j) *= element->value();
5758  ++j;
5759  }
5760 
5761  for( ; j<columns(); ++j ) {
5762  reset( matrix_(index,j) );
5763  }
5764  }
5765 }
5767 //*************************************************************************************************
5768 
5769 
5770 //*************************************************************************************************
5782 template< typename MT // Type of the dense matrix
5783  , typename... CRAs > // Compile time row arguments
5784 template< typename MT2 > // Type of the right-hand side sparse matrix
5785 inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
5786 {
5787  using blaze::reset;
5788 
5791 
5793 
5794  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5795  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5796 
5797  for( size_t j=0UL; j<columns(); ++j )
5798  {
5799  size_t i( 0UL );
5800 
5801  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
5802  for( ; i<element->index(); ++i )
5803  reset( matrix_(idx(i),j) );
5804  matrix_(idx(i),j) *= element->value();
5805  ++i;
5806  }
5807 
5808  for( ; i<rows(); ++i ) {
5809  reset( matrix_(idx(i),j) );
5810  }
5811  }
5812 }
5814 //*************************************************************************************************
5815 
5816 
5817 
5818 
5819 
5820 
5821 
5822 
5823 //=================================================================================================
5824 //
5825 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR DENSE MATRICES
5826 //
5827 //=================================================================================================
5828 
5829 //*************************************************************************************************
5837 template< typename MT // Type of the dense matrix
5838  , typename... CRAs > // Compile time row arguments
5839 class Rows<MT,false,true,true,CRAs...>
5840  : public View< DenseMatrix< Rows<MT,false,true,true,CRAs...>, false > >
5841  , private RowsData<CRAs...>
5842 {
5843  private:
5844  //**Type definitions****************************************************************************
5845  using DataType = RowsData<CRAs...>;
5846  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
5847  //**********************************************************************************************
5848 
5849  //**Compile time flags**************************************************************************
5850  using DataType::N;
5851  //**********************************************************************************************
5852 
5853  public:
5854  //**Type definitions****************************************************************************
5856  using This = Rows<MT,false,true,true,CRAs...>;
5857 
5858  using BaseType = DenseMatrix<This,false>;
5859  using ViewedType = MT;
5860  using ResultType = RowsTrait_t<MT,N>;
5861  using OppositeType = OppositeType_t<ResultType>;
5862  using TransposeType = TransposeType_t<ResultType>;
5863  using ElementType = ElementType_t<MT>;
5864  using SIMDType = SIMDTrait_t<ElementType>;
5865  using ReturnType = ReturnType_t<MT>;
5866  using CompositeType = const Rows&;
5867 
5869  using ConstReference = ConstReference_t<MT>;
5870 
5872  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
5873 
5875  using ConstPointer = ConstPointer_t<MT>;
5876 
5878  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
5879 
5881  using ConstIterator = ConstIterator_t<MT>;
5882 
5884  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
5885  //**********************************************************************************************
5886 
5887  //**Compilation flags***************************************************************************
5889  static constexpr bool simdEnabled = MT::simdEnabled;
5890 
5892  static constexpr bool smpAssignable = MT::smpAssignable;
5893  //**********************************************************************************************
5894 
5895  //**Constructors********************************************************************************
5898  template< typename... RRAs >
5899  explicit inline Rows( MT& matrix, RRAs... args );
5900 
5901  Rows( const Rows& ) = default;
5902  Rows( Rows&& ) = default;
5904  //**********************************************************************************************
5905 
5906  //**Destructor**********************************************************************************
5909  ~Rows() = default;
5911  //**********************************************************************************************
5912 
5913  //**Data access functions***********************************************************************
5916  inline Reference operator()( size_t i, size_t j );
5917  inline ConstReference operator()( size_t i, size_t j ) const;
5918  inline Reference at( size_t i, size_t j );
5919  inline ConstReference at( size_t i, size_t j ) const;
5920  inline Pointer data () noexcept;
5921  inline ConstPointer data () const noexcept;
5922  inline Pointer data ( size_t i ) noexcept;
5923  inline ConstPointer data ( size_t i ) const noexcept;
5924  inline Iterator begin ( size_t i );
5925  inline ConstIterator begin ( size_t i ) const;
5926  inline ConstIterator cbegin( size_t i ) const;
5927  inline Iterator end ( size_t i );
5928  inline ConstIterator end ( size_t i ) const;
5929  inline ConstIterator cend ( size_t i ) const;
5931  //**********************************************************************************************
5932 
5933  //**Assignment operators************************************************************************
5936  inline Rows& operator=( const ElementType& rhs );
5937 
5938  Rows& operator=( const Rows& ) = delete;
5940  //**********************************************************************************************
5941 
5942  //**Utility functions***************************************************************************
5945  using DataType::idx;
5946  using DataType::idces;
5947  using DataType::rows;
5948 
5949  inline MT& operand() noexcept;
5950  inline const MT& operand() const noexcept;
5951 
5952  inline size_t columns() const noexcept;
5953  inline size_t spacing() const noexcept;
5954  inline size_t capacity() const noexcept;
5955  inline size_t capacity( size_t i ) const noexcept;
5956  inline size_t nonZeros() const;
5957  inline size_t nonZeros( size_t i ) const;
5958  inline void reset();
5959  inline void reset( size_t i );
5961  //**********************************************************************************************
5962 
5963  //**Expression template evaluation functions****************************************************
5966  template< typename Other >
5967  inline bool canAlias( const Other* alias ) const noexcept;
5968 
5969  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
5970  inline bool canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
5971 
5972  template< typename Other >
5973  inline bool isAliased( const Other* alias ) const noexcept;
5974 
5975  template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
5976  inline bool isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
5977 
5978  inline bool isAligned () const noexcept;
5979  inline bool canSMPAssign() const noexcept;
5980 
5981  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
5982  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
5983  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
5985  //**********************************************************************************************
5986 
5987  private:
5988  //**Member variables****************************************************************************
5991  Operand matrix_;
5992 
5993  //**********************************************************************************************
5994 
5995  //**Friend declarations*************************************************************************
5996  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CRAs2 > friend class Rows;
5997  //**********************************************************************************************
5998 
5999  //**Compile time checks*************************************************************************
6009  //**********************************************************************************************
6010 };
6012 //*************************************************************************************************
6013 
6014 
6015 
6016 
6017 //=================================================================================================
6018 //
6019 // CONSTRUCTORS
6020 //
6021 //=================================================================================================
6022 
6023 //*************************************************************************************************
6036 template< typename MT // Type of the dense matrix
6037  , typename... CRAs > // Compile time row arguments
6038 template< typename... RRAs > // Runtime row arguments
6039 inline Rows<MT,false,true,true,CRAs...>::Rows( MT& matrix, RRAs... args )
6040  : DataType( args... ) // Base class initialization
6041  , matrix_ ( matrix ) // The matrix containing the rows
6042 {
6043  if( !Contains_v< TypeList<RRAs...>, Unchecked > ) {
6044  for( size_t i=0UL; i<rows(); ++i ) {
6045  if( matrix_.rows() <= idx(i) ) {
6046  BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
6047  }
6048  }
6049  }
6050 }
6052 //*************************************************************************************************
6053 
6054 
6055 
6056 
6057 //=================================================================================================
6058 //
6059 // DATA ACCESS FUNCTIONS
6060 //
6061 //=================================================================================================
6062 
6063 //*************************************************************************************************
6074 template< typename MT // Type of the dense matrix
6075  , typename... CRAs > // Compile time row arguments
6076 inline typename Rows<MT,false,true,true,CRAs...>::Reference
6077  Rows<MT,false,true,true,CRAs...>::operator()( size_t i, size_t j )
6078 {
6079  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6080  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6081 
6082  return matrix_(j,idx(i));
6083 }
6085 //*************************************************************************************************
6086 
6087 
6088 //*************************************************************************************************
6099 template< typename MT // Type of the dense matrix
6100  , typename... CRAs > // Compile time row arguments
6101 inline typename Rows<MT,false,true,true,CRAs...>::ConstReference
6102  Rows<MT,false,true,true,CRAs...>::operator()( size_t i, size_t j ) const
6103 {
6104  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6105  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6106 
6107  return const_cast<const MT&>( matrix_ )(j,idx(i));
6108 }
6110 //*************************************************************************************************
6111 
6112 
6113 //*************************************************************************************************
6125 template< typename MT // Type of the dense matrix
6126  , typename... CRAs > // Compile time row arguments
6127 inline typename Rows<MT,false,true,true,CRAs...>::Reference
6128  Rows<MT,false,true,true,CRAs...>::at( size_t i, size_t j )
6129 {
6130  if( i >= rows() ) {
6131  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6132  }
6133  if( j >= columns() ) {
6134  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6135  }
6136  return (*this)(i,j);
6137 }
6139 //*************************************************************************************************
6140 
6141 
6142 //*************************************************************************************************
6154 template< typename MT // Type of the dense matrix
6155  , typename... CRAs > // Compile time row arguments
6156 inline typename Rows<MT,false,true,true,CRAs...>::ConstReference
6157  Rows<MT,false,true,true,CRAs...>::at( size_t i, size_t j ) const
6158 {
6159  if( i >= rows() ) {
6160  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6161  }
6162  if( j >= columns() ) {
6163  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6164  }
6165  return (*this)(i,j);
6166 }
6168 //*************************************************************************************************
6169 
6170 
6171 //*************************************************************************************************
6181 template< typename MT // Type of the dense matrix
6182  , typename... CRAs > // Compile time row arguments
6183 inline typename Rows<MT,false,true,true,CRAs...>::Pointer
6185 {
6186  return matrix_.data( idx(0UL) );
6187 }
6189 //*************************************************************************************************
6190 
6191 
6192 //*************************************************************************************************
6202 template< typename MT // Type of the dense matrix
6203  , typename... CRAs > // Compile time row arguments
6204 inline typename Rows<MT,false,true,true,CRAs...>::ConstPointer
6206 {
6207  return matrix_.data( idx(0UL) );
6208 }
6210 //*************************************************************************************************
6211 
6212 
6213 //*************************************************************************************************
6222 template< typename MT // Type of the dense matrix
6223  , typename... CRAs > // Compile time row arguments
6224 inline typename Rows<MT,false,true,true,CRAs...>::Pointer
6225  Rows<MT,false,true,true,CRAs...>::data( size_t i ) noexcept
6226 {
6227  return matrix_.data( idx(i) );
6228 }
6230 //*************************************************************************************************
6231 
6232 
6233 //*************************************************************************************************
6242 template< typename MT // Type of the dense matrix
6243  , typename... CRAs > // Compile time row arguments
6244 inline typename Rows<MT,false,true,true,CRAs...>::ConstPointer
6245  Rows<MT,false,true,true,CRAs...>::data( size_t i ) const noexcept
6246 {
6247  return matrix_.data( idx(i) );
6248 }
6250 //*************************************************************************************************
6251 
6252 
6253 //*************************************************************************************************
6262 template< typename MT // Type of the dense matrix
6263  , typename... CRAs > // Compile time row arguments
6264 inline typename Rows<MT,false,true,true,CRAs...>::Iterator
6266 {
6267  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6268  return matrix_.begin( idx(i) );
6269 }
6271 //*************************************************************************************************
6272 
6273 
6274 //*************************************************************************************************
6283 template< typename MT // Type of the dense matrix
6284  , typename... CRAs > // Compile time row arguments
6285 inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6286  Rows<MT,false,true,true,CRAs...>::begin( size_t i ) const
6287 {
6288  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6289  return matrix_.cbegin( idx(i) );
6290 }
6292 //*************************************************************************************************
6293 
6294 
6295 //*************************************************************************************************
6304 template< typename MT // Type of the dense matrix
6305  , typename... CRAs > // Compile time row arguments
6306 inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6308 {
6309  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6310  return matrix_.cbegin( idx(i) );
6311 }
6313 //*************************************************************************************************
6314 
6315 
6316 //*************************************************************************************************
6325 template< typename MT // Type of the dense matrix
6326  , typename... CRAs > // Compile time row arguments
6327 inline typename Rows<MT,false,true,true,CRAs...>::Iterator
6329 {
6330  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6331  return matrix_.end( idx(i) );
6332 }
6334 //*************************************************************************************************
6335 
6336 
6337 //*************************************************************************************************
6346 template< typename MT // Type of the dense matrix
6347  , typename... CRAs > // Compile time row arguments
6348 inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6349  Rows<MT,false,true,true,CRAs...>::end( size_t i ) const
6350 {
6351  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6352  return matrix_.cend( idx(i) );
6353 }
6355 //*************************************************************************************************
6356 
6357 
6358 //*************************************************************************************************
6367 template< typename MT // Type of the dense matrix
6368  , typename... CRAs > // Compile time row arguments
6369 inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6370  Rows<MT,false,true,true,CRAs...>::cend( size_t i ) const
6371 {
6372  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6373  return matrix_.cend( idx(i) );
6374 }
6376 //*************************************************************************************************
6377 
6378 
6379 
6380 
6381 //=================================================================================================
6382 //
6383 // ASSIGNMENT OPERATORS
6384 //
6385 //=================================================================================================
6386 
6387 //*************************************************************************************************
6398 template< typename MT // Type of the dense matrix
6399  , typename... CRAs > // Compile time row arguments
6400 inline Rows<MT,false,true,true,CRAs...>&
6401  Rows<MT,false,true,true,CRAs...>::operator=( const ElementType& rhs )
6402 {
6403  for( size_t i=0UL; i<rows(); ++i ) {
6404  column( matrix_, idx(i), unchecked ) = rhs;
6405  }
6406 
6407  return *this;
6408 }
6410 //*************************************************************************************************
6411 
6412 
6413 
6414 
6415 //=================================================================================================
6416 //
6417 // UTILITY FUNCTIONS
6418 //
6419 //=================================================================================================
6420 
6421 //*************************************************************************************************
6427 template< typename MT // Type of the dense matrix
6428  , typename... CRAs > // Compile time row arguments
6429 inline MT& Rows<MT,false,true,true,CRAs...>::operand() noexcept
6430 {
6431  return matrix_;
6432 }
6434 //*************************************************************************************************
6435 
6436 
6437 //*************************************************************************************************
6443 template< typename MT // Type of the dense matrix
6444  , typename... CRAs > // Compile time row arguments
6445 inline const MT& Rows<MT,false,true,true,CRAs...>::operand() const noexcept
6446 {
6447  return matrix_;
6448 }
6450 //*************************************************************************************************
6451 
6452 
6453 //*************************************************************************************************
6459 template< typename MT // Type of the dense matrix
6460  , typename... CRAs > // Compile time row arguments
6461 inline size_t Rows<MT,false,true,true,CRAs...>::columns() const noexcept
6462 {
6463  return matrix_.columns();
6464 }
6466 //*************************************************************************************************
6467 
6468 
6469 //*************************************************************************************************
6478 template< typename MT // Type of the dense matrix
6479  , typename... CRAs > // Compile time row arguments
6480 inline size_t Rows<MT,false,true,true,CRAs...>::spacing() const noexcept
6481 {
6482  return matrix_.spacing();
6483 }
6485 //*************************************************************************************************
6486 
6487 
6488 //*************************************************************************************************
6494 template< typename MT // Type of the dense matrix
6495  , typename... CRAs > // Compile time row arguments
6496 inline size_t Rows<MT,false,true,true,CRAs...>::capacity() const noexcept
6497 {
6498  return rows() * columns();
6499 }
6501 //*************************************************************************************************
6502 
6503 
6504 //*************************************************************************************************
6513 template< typename MT // Type of the dense matrix
6514  , typename... CRAs > // Compile time row arguments
6515 inline size_t Rows<MT,false,true,true,CRAs...>::capacity( size_t i ) const noexcept
6516 {
6517  UNUSED_PARAMETER( i );
6518 
6519  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6520 
6521  return columns();
6522 }
6524 //*************************************************************************************************
6525 
6526 
6527 //*************************************************************************************************
6533 template< typename MT // Type of the dense matrix
6534  , typename... CRAs > // Compile time row arguments
6535 inline size_t Rows<MT,false,true,true,CRAs...>::nonZeros() const
6536 {
6537  size_t nonzeros( 0UL );
6538 
6539  for( size_t i=0UL; i<rows(); ++i ) {
6540  nonzeros += matrix_.nonZeros( idx(i) );
6541  }
6542 
6543  return nonzeros;
6544 }
6546 //*************************************************************************************************
6547 
6548 
6549 //*************************************************************************************************
6558 template< typename MT // Type of the dense matrix
6559  , typename... CRAs > // Compile time row arguments
6560 inline size_t Rows<MT,false,true,true,CRAs...>::nonZeros( size_t i ) const
6561 {
6562  BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6563 
6564  return matrix_.nonZeros( idx(i) );
6565 }
6567 //*************************************************************************************************
6568 
6569 
6570 //*************************************************************************************************
6576 template< typename MT // Type of the dense matrix
6577  , typename... CRAs > // Compile time row arguments
6579 {
6580  for( size_t i=0UL; i<rows(); ++i ) {
6581  matrix_.reset( idx(i) );
6582  }
6583 }
6585 //*************************************************************************************************
6586 
6587 
6588 //*************************************************************************************************
6597 template< typename MT // Type of the dense matrix
6598  , typename... CRAs > // Compile time row arguments
6599 inline void Rows<MT,false,true,true,CRAs...>::reset( size_t i )
6600 {
6601  matrix_.reset( idx(i) );
6602 }
6604 //*************************************************************************************************
6605 
6606 
6607 
6608 
6609 //=================================================================================================
6610 //
6611 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6612 //
6613 //=================================================================================================
6614 
6615 //*************************************************************************************************
6626 template< typename MT // Type of the dense matrix
6627  , typename... CRAs > // Compile time row arguments
6628 template< typename Other > // Data type of the foreign expression
6629 inline bool Rows<MT,false,true,true,CRAs...>::canAlias( const Other* alias ) const noexcept
6630 {
6631  return matrix_.isAliased( alias );
6632 }
6634 //*************************************************************************************************
6635 
6636 
6637 //*************************************************************************************************
6649 template< typename MT // Type of the dense matrix
6650  , typename... CRAs > // Compile time row arguments
6651 template< typename MT2 // Data type of the foreign dense row selection
6652  , bool SO2 // Storage order of the foreign dense row selection
6653  , bool SF2 // Symmetry flag of the foreign dense row selection
6654  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
6655 inline bool
6656  Rows<MT,false,true,true,CRAs...>::canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
6657 {
6658  return matrix_.isAliased( &alias->matrix_ );
6659 }
6661 //*************************************************************************************************
6662 
6663 
6664 //*************************************************************************************************
6675 template< typename MT // Type of the dense matrix
6676  , typename... CRAs > // Compile time row arguments
6677 template< typename Other > // Data type of the foreign expression
6678 inline bool Rows<MT,false,true,true,CRAs...>::isAliased( const Other* alias ) const noexcept
6679 {
6680  return matrix_.isAliased( alias );
6681 }
6683 //*************************************************************************************************
6684 
6685 
6686 //*************************************************************************************************
6698 template< typename MT // Type of the dense matrix
6699  , typename... CRAs > // Compile time row arguments
6700 template< typename MT2 // Data type of the foreign dense row selection
6701  , bool SO2 // Storage order of the foreign dense row selection
6702  , bool SF2 // Symmetry flag of the foreign dense row selection
6703  , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
6704 inline bool
6705  Rows<MT,false,true,true,CRAs...>::isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
6706 {
6707  return matrix_.isAliased( &alias->matrix_ );
6708 }
6710 //*************************************************************************************************
6711 
6712 
6713 //*************************************************************************************************
6723 template< typename MT // Type of the dense matrix
6724  , typename... CRAs > // Compile time row arguments
6725 inline bool Rows<MT,false,true,true,CRAs...>::isAligned() const noexcept
6726 {
6727  return matrix_.isAligned();
6728 }
6730 //*************************************************************************************************
6731 
6732 
6733 //*************************************************************************************************
6744 template< typename MT // Type of the dense matrix
6745  , typename... CRAs > // Compile time row arguments
6746 inline bool Rows<MT,false,true,true,CRAs...>::canSMPAssign() const noexcept
6747 {
6748  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
6749 }
6751 //*************************************************************************************************
6752 
6753 
6754 //*************************************************************************************************
6769 template< typename MT // Type of the dense matrix
6770  , typename... CRAs > // Compile time row arguments
6771 BLAZE_ALWAYS_INLINE typename Rows<MT,false,true,true,CRAs...>::SIMDType
6772  Rows<MT,false,true,true,CRAs...>::load( size_t i, size_t j ) const noexcept
6773 {
6774  return matrix_.load( j, idx(i) );
6775 }
6777 //*************************************************************************************************
6778 
6779 
6780 //*************************************************************************************************
6795 template< typename MT // Type of the dense matrix
6796  , typename... CRAs > // Compile time row arguments
6797 BLAZE_ALWAYS_INLINE typename Rows<MT,false,true,true,CRAs...>::SIMDType
6798  Rows<MT,false,true,true,CRAs...>::loada( size_t i, size_t j ) const noexcept
6799 {
6800  return matrix_.loada( j, idx(i) );
6801 }
6803 //*************************************************************************************************
6804 
6805 
6806 //*************************************************************************************************
6821 template< typename MT // Type of the dense matrix
6822  , typename... CRAs > // Compile time row arguments
6823 BLAZE_ALWAYS_INLINE typename Rows<MT,false,true,true,CRAs...>::SIMDType
6824  Rows<MT,false,true,true,CRAs...>::loadu( size_t i, size_t j ) const noexcept
6825 {
6826  return matrix_.loadu( j, idx(i) );
6827 }
6829 //*************************************************************************************************
6830 
6831 } // namespace blaze
6832 
6833 #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.
Header file for kernel specific block sizes.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3078
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, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the UNUSED_PARAMETER function template.
Header file for the 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:169
Header file for the View base class.
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:188
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
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
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3077
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3079
#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. a dense or sparse submatrix), a compilation error is created.
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
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3084
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
#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.
Header file for the decltype(auto) workaround.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3085
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 void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
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:252
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.
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3083
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#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:1364
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
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:189
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3080
#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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:253
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:139
Header file for the IsLower type trait.
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
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8908
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
Constraint on the data type.
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, a compilation error is created.
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.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the 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, a compilation error is created.
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.
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 bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.The IsDiagonal_v variable template provides...
Definition: IsDiagonal.h:148
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
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
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
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3082
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:188
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
#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, a compilation error is created.
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
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
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, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
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