Blaze 3.9
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>
63#include <blaze/math/SIMD.h>
87#include <blaze/system/Inline.h>
90#include <blaze/util/Assert.h>
94#include <blaze/util/EnableIf.h>
96#include <blaze/util/mpl/If.h>
97#include <blaze/util/Types.h>
100
101
102namespace blaze {
103
104//=================================================================================================
105//
106// CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR DENSE MATRICES
107//
108//=================================================================================================
109
110//*************************************************************************************************
118template< typename MT // Type of the dense matrix
119 , bool SF // Symmetry flag
120 , typename... CRAs > // Compile time row arguments
121class Rows<MT,true,true,SF,CRAs...>
122 : public View< DenseMatrix< Rows<MT,true,true,SF,CRAs...>, false > >
123 , private RowsData<CRAs...>
124{
125 private:
126 //**Type definitions****************************************************************************
127 using DataType = RowsData<CRAs...>;
128 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
129 //**********************************************************************************************
130
131 //**Compile time flags**************************************************************************
132 using DataType::N;
133 //**********************************************************************************************
134
135 //**********************************************************************************************
137 template< typename MT1, typename MT2 >
138 static constexpr bool EnforceEvaluation_v =
139 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
140 //**********************************************************************************************
141
142 public:
143 //**Type definitions****************************************************************************
145 using This = Rows<MT,true,true,SF,CRAs...>;
146
148 using BaseType = View< DenseMatrix<This,false> >;
149
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
186 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
187 //**********************************************************************************************
188
189 //**Constructors********************************************************************************
192 template< typename... RRAs >
193 explicit inline Rows( MT& matrix, RRAs... args );
194
195 Rows( const Rows& ) = default;
196 Rows( Rows&& ) = default;
198 //**********************************************************************************************
199
200 //**Destructor**********************************************************************************
203 ~Rows() = default;
205 //**********************************************************************************************
206
207 //**Data access functions***********************************************************************
210 inline Reference operator()( size_t i, size_t j );
211 inline ConstReference operator()( size_t i, size_t j ) const;
212 inline Reference at( size_t i, size_t j );
213 inline ConstReference at( size_t i, size_t j ) const;
214 inline Pointer data () noexcept;
215 inline ConstPointer data () const noexcept;
216 inline Pointer data ( size_t i ) noexcept;
217 inline ConstPointer data ( size_t i ) const noexcept;
218 inline Iterator begin ( size_t i );
219 inline ConstIterator begin ( size_t i ) const;
220 inline ConstIterator cbegin( size_t i ) const;
221 inline Iterator end ( size_t i );
222 inline ConstIterator end ( size_t i ) const;
223 inline ConstIterator cend ( size_t i ) const;
225 //**********************************************************************************************
226
227 //**Assignment operators************************************************************************
230 inline Rows& operator=( const ElementType& rhs );
231 inline Rows& operator=( initializer_list< initializer_list<ElementType> > list );
232 inline Rows& operator=( const Rows& rhs );
233
234 template< typename MT2, bool SO2 >
235 inline Rows& operator=( const Matrix<MT2,SO2>& rhs );
236
237 template< typename MT2, bool SO2 >
238 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
239 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
240
241 template< typename MT2, bool SO2 >
242 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
243 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
244
245 template< typename MT2, bool SO2 >
246 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
247 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
248
249 template< typename MT2, bool SO2 >
250 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
251 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
252
253 template< typename MT2, bool SO2 >
254 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
255 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
256
257 template< typename MT2, bool SO2 >
258 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
259 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
261 //**********************************************************************************************
262
263 //**Utility functions***************************************************************************
266 using DataType::idx;
267 using DataType::idces;
268 using DataType::rows;
269
270 inline MT& operand() noexcept;
271 inline const MT& operand() const noexcept;
272
273 inline size_t columns() const noexcept;
274 inline size_t spacing() const noexcept;
275 inline size_t capacity() const noexcept;
276 inline size_t capacity( size_t i ) const noexcept;
277 inline size_t nonZeros() const;
278 inline size_t nonZeros( size_t i ) const;
279 inline void reset();
280 inline void reset( size_t i );
282 //**********************************************************************************************
283
284 //**Numeric functions***************************************************************************
287 inline Rows& transpose();
288 inline Rows& ctranspose();
289
290 template< typename Other > inline Rows& scale( const Other& scalar );
292 //**********************************************************************************************
293
294 private:
295 //**********************************************************************************************
297 template< typename MT2 >
298 static constexpr bool VectorizedAssign_v =
299 ( useOptimizedKernels &&
300 simdEnabled && MT2::simdEnabled &&
301 IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > );
302 //**********************************************************************************************
303
304 //**********************************************************************************************
306 template< typename MT2 >
307 static constexpr bool VectorizedAddAssign_v =
308 ( VectorizedAssign_v<MT2> &&
309 HasSIMDAdd_v< ElementType, ElementType_t<MT2> > &&
310 !IsDiagonal_v<MT2> );
311 //**********************************************************************************************
312
313 //**********************************************************************************************
315 template< typename MT2 >
316 static constexpr bool VectorizedSubAssign_v =
317 ( VectorizedAssign_v<MT2> &&
318 HasSIMDSub_v< ElementType, ElementType_t<MT2> > &&
319 !IsDiagonal_v<MT2> );
320 //**********************************************************************************************
321
322 //**********************************************************************************************
324 template< typename MT2 >
325 static constexpr bool VectorizedSchurAssign_v =
326 ( VectorizedAssign_v<MT2> &&
327 HasSIMDMult_v< ElementType, ElementType_t<MT2> > );
328 //**********************************************************************************************
329
330 //**SIMD properties*****************************************************************************
332 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
333 //**********************************************************************************************
334
335 public:
336 //**Expression template evaluation functions****************************************************
339 template< typename Other >
340 inline bool canAlias( const Other* alias ) const noexcept;
341
342 template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
343 inline bool canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
344
345 template< typename Other >
346 inline bool isAliased( const Other* alias ) const noexcept;
347
348 template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
349 inline bool isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
350
351 inline bool isAligned () const noexcept;
352 inline bool canSMPAssign() const noexcept;
353
354 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
355 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
356 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
357
358 BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
359 BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
360 BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
361 BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
362
363 template< typename MT2 >
364 inline auto assign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT2> >;
365
366 template< typename MT2 >
367 inline auto assign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT2> >;
368
369 template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
370
371 template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
372 template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
373
374 template< typename MT2 >
375 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT2> >;
376
377 template< typename MT2 >
378 inline auto addAssign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT2> >;
379
380 template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
381 template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
382 template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
383
384 template< typename MT2 >
385 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT2> >;
386
387 template< typename MT2 >
388 inline auto subAssign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT2> >;
389
390 template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
391 template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
392 template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
393
394 template< typename MT2 >
395 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT2> >;
396
397 template< typename MT2 >
398 inline auto schurAssign( const DenseMatrix<MT2,false>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT2> >;
399
400 template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
401 template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
402 template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
404 //**********************************************************************************************
405
406 private:
407 //**Member variables****************************************************************************
410 Operand matrix_;
412 //**********************************************************************************************
413
414 //**Friend declarations*************************************************************************
415 template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CRAs2 > friend class Rows;
416 //**********************************************************************************************
417
418 //**Compile time checks*************************************************************************
427 //**********************************************************************************************
428};
430//*************************************************************************************************
431
432
433
434
435//=================================================================================================
436//
437// CONSTRUCTORS
438//
439//=================================================================================================
440
441//*************************************************************************************************
454template< typename MT // Type of the dense matrix
455 , bool SF // Symmetry flag
456 , typename... CRAs > // Compile time row arguments
457template< typename... RRAs > // Runtime row arguments
458inline Rows<MT,true,true,SF,CRAs...>::Rows( MT& matrix, RRAs... args )
459 : DataType( args... ) // Base class initialization
460 , matrix_ ( matrix ) // The matrix containing the rows
461{
462 if( isChecked( args... ) ) {
463 for( size_t i=0UL; i<rows(); ++i ) {
464 if( matrix_.rows() <= idx(i) ) {
465 BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
466 }
467 }
468 }
469}
471//*************************************************************************************************
472
473
474
475
476//=================================================================================================
477//
478// DATA ACCESS FUNCTIONS
479//
480//=================================================================================================
481
482//*************************************************************************************************
493template< typename MT // Type of the dense matrix
494 , bool SF // Symmetry flag
495 , typename... CRAs > // Compile time row arguments
496inline typename Rows<MT,true,true,SF,CRAs...>::Reference
497 Rows<MT,true,true,SF,CRAs...>::operator()( size_t i, size_t j )
498{
499 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
500 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
501
502 return matrix_(idx(i),j);
503}
505//*************************************************************************************************
506
507
508//*************************************************************************************************
519template< typename MT // Type of the dense matrix
520 , bool SF // Symmetry flag
521 , typename... CRAs > // Compile time row arguments
522inline typename Rows<MT,true,true,SF,CRAs...>::ConstReference
523 Rows<MT,true,true,SF,CRAs...>::operator()( size_t i, size_t j ) const
524{
525 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
526 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
527
528 return const_cast<const MT&>( matrix_ )(idx(i),j);
529}
531//*************************************************************************************************
532
533
534//*************************************************************************************************
546template< typename MT // Type of the dense matrix
547 , bool SF // Symmetry flag
548 , typename... CRAs > // Compile time row arguments
549inline typename Rows<MT,true,true,SF,CRAs...>::Reference
550 Rows<MT,true,true,SF,CRAs...>::at( size_t i, size_t j )
551{
552 if( i >= rows() ) {
553 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
554 }
555 if( j >= columns() ) {
556 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
557 }
558 return (*this)(i,j);
559}
561//*************************************************************************************************
562
563
564//*************************************************************************************************
576template< typename MT // Type of the dense matrix
577 , bool SF // Symmetry flag
578 , typename... CRAs > // Compile time row arguments
579inline typename Rows<MT,true,true,SF,CRAs...>::ConstReference
580 Rows<MT,true,true,SF,CRAs...>::at( size_t i, size_t j ) const
581{
582 if( i >= rows() ) {
583 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
584 }
585 if( j >= columns() ) {
586 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
587 }
588 return (*this)(i,j);
589}
591//*************************************************************************************************
592
593
594//*************************************************************************************************
604template< typename MT // Type of the dense matrix
605 , bool SF // Symmetry flag
606 , typename... CRAs > // Compile time row arguments
607inline typename Rows<MT,true,true,SF,CRAs...>::Pointer
609{
610 return matrix_.data( idx(0UL) );
611}
613//*************************************************************************************************
614
615
616//*************************************************************************************************
626template< typename MT // Type of the dense matrix
627 , bool SF // Symmetry flag
628 , typename... CRAs > // Compile time row arguments
629inline typename Rows<MT,true,true,SF,CRAs...>::ConstPointer
631{
632 return matrix_.data( idx(0UL) );
633}
635//*************************************************************************************************
636
637
638//*************************************************************************************************
647template< typename MT // Type of the dense matrix
648 , bool SF // Symmetry flag
649 , typename... CRAs > // Compile time row arguments
650inline typename Rows<MT,true,true,SF,CRAs...>::Pointer
651 Rows<MT,true,true,SF,CRAs...>::data( size_t i ) noexcept
652{
653 return matrix_.data( idx(i) );
654}
656//*************************************************************************************************
657
658
659//*************************************************************************************************
668template< typename MT // Type of the dense matrix
669 , bool SF // Symmetry flag
670 , typename... CRAs > // Compile time row arguments
671inline typename Rows<MT,true,true,SF,CRAs...>::ConstPointer
672 Rows<MT,true,true,SF,CRAs...>::data( size_t i ) const noexcept
673{
674 return matrix_.data( idx(i) );
675}
677//*************************************************************************************************
678
679
680//*************************************************************************************************
689template< typename MT // Type of the dense matrix
690 , bool SF // Symmetry flag
691 , typename... CRAs > // Compile time row arguments
692inline typename Rows<MT,true,true,SF,CRAs...>::Iterator
694{
695 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
696 return matrix_.begin( idx(i) );
697}
699//*************************************************************************************************
700
701
702//*************************************************************************************************
711template< typename MT // Type of the dense matrix
712 , bool SF // Symmetry flag
713 , typename... CRAs > // Compile time row arguments
714inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
716{
717 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
718 return matrix_.cbegin( idx(i) );
719}
721//*************************************************************************************************
722
723
724//*************************************************************************************************
733template< typename MT // Type of the dense matrix
734 , bool SF // Symmetry flag
735 , typename... CRAs > // Compile time row arguments
736inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
738{
739 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
740 return matrix_.cbegin( idx(i) );
741}
743//*************************************************************************************************
744
745
746//*************************************************************************************************
755template< typename MT // Type of the dense matrix
756 , bool SF // Symmetry flag
757 , typename... CRAs > // Compile time row arguments
758inline typename Rows<MT,true,true,SF,CRAs...>::Iterator
760{
761 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
762 return matrix_.end( idx(i) );
763}
765//*************************************************************************************************
766
767
768//*************************************************************************************************
777template< typename MT // Type of the dense matrix
778 , bool SF // Symmetry flag
779 , typename... CRAs > // Compile time row arguments
780inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
781 Rows<MT,true,true,SF,CRAs...>::end( size_t i ) const
782{
783 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
784 return matrix_.cend( idx(i) );
785}
787//*************************************************************************************************
788
789
790//*************************************************************************************************
799template< typename MT // Type of the dense matrix
800 , bool SF // Symmetry flag
801 , typename... CRAs > // Compile time row arguments
802inline typename Rows<MT,true,true,SF,CRAs...>::ConstIterator
804{
805 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
806 return matrix_.cend( idx(i) );
807}
809//*************************************************************************************************
810
811
812
813
814//=================================================================================================
815//
816// ASSIGNMENT OPERATORS
817//
818//=================================================================================================
819
820//*************************************************************************************************
831template< typename MT // Type of the dense matrix
832 , bool SF // Symmetry flag
833 , typename... CRAs > // Compile time row arguments
834inline Rows<MT,true,true,SF,CRAs...>&
835 Rows<MT,true,true,SF,CRAs...>::operator=( const ElementType& rhs )
836{
837 for( size_t i=0UL; i<rows(); ++i ) {
838 row( matrix_, idx(i), unchecked ) = rhs;
839 }
840
841 return *this;
842}
844//*************************************************************************************************
845
846
847//*************************************************************************************************
863template< typename MT // Type of the dense matrix
864 , bool SF // Symmetry flag
865 , typename... CRAs > // Compile time row arguments
866inline Rows<MT,true,true,SF,CRAs...>&
867 Rows<MT,true,true,SF,CRAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
868{
871
872 if( list.size() != rows() ) {
873 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row selection" );
874 }
875
876 if( IsRestricted_v<MT> ) {
877 size_t i( 0UL );
878 for( const auto& rowList : list ) {
879 const InitializerVector<ElementType> tmp( rowList, columns() );
880 if( !tryAssign( row( matrix_, idx(i), unchecked ), tmp, 0UL ) ){
881 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
882 }
883 ++i;
884 }
885 }
886
887 decltype(auto) left( derestrict( *this ) );
888 size_t i( 0UL );
889
890 for( const auto& rowList : list ) {
891 std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
892 ++i;
893 }
894
895 return *this;
896}
898//*************************************************************************************************
899
900
901//*************************************************************************************************
916template< typename MT // Type of the dense matrix
917 , bool SF // Symmetry flag
918 , typename... CRAs > // Compile time row arguments
919inline Rows<MT,true,true,SF,CRAs...>&
920 Rows<MT,true,true,SF,CRAs...>::operator=( const Rows& rhs )
921{
924
927
928 if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
929 return *this;
930
931 if( rows() != rhs.rows() || columns() != rhs.columns() ) {
932 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
933 }
934
935 if( IsRestricted_v<MT> ) {
936 for( size_t i=0UL; i<rows(); ++i ) {
937 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( rhs, i, unchecked ), 0UL ) ) {
938 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
939 }
940 }
941 }
942
943 decltype(auto) left( derestrict( *this ) );
944
945 if( rhs.canAlias( this ) ) {
946 const ResultType tmp( rhs );
947 smpAssign( left, tmp );
948 }
949 else {
950 smpAssign( left, rhs );
951 }
952
953 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
954
955 return *this;
956}
958//*************************************************************************************************
959
960
961//*************************************************************************************************
976template< typename MT // Type of the dense matrix
977 , bool SF // Symmetry flag
978 , typename... CRAs > // Compile time row arguments
979template< typename MT2 // Type of the right-hand side matrix
980 , bool SO2 > // Storage order of the right-hand side matrix
981inline Rows<MT,true,true,SF,CRAs...>&
982 Rows<MT,true,true,SF,CRAs...>::operator=( const Matrix<MT2,SO2>& rhs )
983{
986
988
989 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
990 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
991 }
992
993 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
994 Right right( *rhs );
995
996 if( IsRestricted_v<MT> ) {
997 for( size_t i=0UL; i<rows(); ++i ) {
998 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( right, i, unchecked ), 0UL ) ) {
999 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1000 }
1001 }
1002 }
1003
1004 decltype(auto) left( derestrict( *this ) );
1005
1006 if( IsSparseMatrix_v<MT2> ) {
1007 reset();
1008 }
1009
1010 if( IsReference_v<Right> && right.canAlias( this ) ) {
1011 const ResultType_t<MT2> tmp( right );
1012 smpAssign( left, tmp );
1013 }
1014 else {
1015 smpAssign( left, right );
1016 }
1017
1018 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1019
1020 return *this;
1021}
1023//*************************************************************************************************
1024
1025
1026//*************************************************************************************************
1040template< typename MT // Type of the dense matrix
1041 , bool SF // Symmetry flag
1042 , typename... CRAs > // Compile time row arguments
1043template< typename MT2 // Type of the right-hand side matrix
1044 , bool SO2 > // Storage order of the right-hand side matrix
1045inline auto Rows<MT,true,true,SF,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1046 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1047{
1050
1054
1055 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1056
1059
1060 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1061 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1062 }
1063
1064 if( IsRestricted_v<MT> ) {
1065 for( size_t i=0UL; i<rows(); ++i ) {
1066 if( !tryAddAssign( row( matrix_, idx(i), unchecked ), row( *rhs, i, unchecked ), 0UL ) ) {
1067 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1068 }
1069 }
1070 }
1071
1072 decltype(auto) left( derestrict( *this ) );
1073
1074 if( (*rhs).canAlias( this ) ) {
1075 const AddType tmp( *this + (*rhs) );
1076 smpAssign( left, tmp );
1077 }
1078 else {
1079 smpAddAssign( left, *rhs );
1080 }
1081
1082 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1083
1084 return *this;
1085}
1087//*************************************************************************************************
1088
1089
1090//*************************************************************************************************
1104template< typename MT // Type of the dense matrix
1105 , bool SF // Symmetry flag
1106 , typename... CRAs > // Compile time row arguments
1107template< typename MT2 // Type of the right-hand side matrix
1108 , bool SO2 > // Storage order of the right-hand side matrix
1109inline auto Rows<MT,true,true,SF,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1110 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1111{
1114
1118
1119 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1120
1123
1124 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1125 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1126 }
1127
1128 const AddType tmp( *this + (*rhs) );
1129
1130 if( IsRestricted_v<MT> ) {
1131 for( size_t i=0UL; i<rows(); ++i ) {
1132 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
1133 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1134 }
1135 }
1136 }
1137
1138 decltype(auto) left( derestrict( *this ) );
1139
1140 smpAssign( left, tmp );
1141
1142 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1143
1144 return *this;
1145}
1147//*************************************************************************************************
1148
1149
1150//*************************************************************************************************
1164template< typename MT // Type of the dense matrix
1165 , bool SF // Symmetry flag
1166 , typename... CRAs > // Compile time row arguments
1167template< typename MT2 // Type of the right-hand side matrix
1168 , bool SO2 > // Storage order of the right-hand side matrix
1169inline auto Rows<MT,true,true,SF,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1170 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1171{
1174
1178
1179 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1180
1183
1184 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1185 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1186 }
1187
1188 if( IsRestricted_v<MT> ) {
1189 for( size_t i=0UL; i<rows(); ++i ) {
1190 if( !trySubAssign( row( matrix_, idx(i), unchecked ), row( *rhs, i, unchecked ), 0UL ) ) {
1191 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1192 }
1193 }
1194 }
1195
1196 decltype(auto) left( derestrict( *this ) );
1197
1198 if( (*rhs).canAlias( this ) ) {
1199 const SubType tmp( *this - (*rhs ) );
1200 smpAssign( left, tmp );
1201 }
1202 else {
1203 smpSubAssign( left, *rhs );
1204 }
1205
1206 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1207
1208 return *this;
1209}
1211//*************************************************************************************************
1212
1213
1214//*************************************************************************************************
1228template< typename MT // Type of the dense matrix
1229 , bool SF // Symmetry flag
1230 , typename... CRAs > // Compile time row arguments
1231template< typename MT2 // Type of the right-hand side matrix
1232 , bool SO2 > // Storage order of the right-hand side matrix
1233inline auto Rows<MT,true,true,SF,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1234 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1235{
1238
1242
1243 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1244
1247
1248 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1249 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1250 }
1251
1252 const SubType tmp( *this - (*rhs) );
1253
1254 if( IsRestricted_v<MT> ) {
1255 for( size_t i=0UL; i<rows(); ++i ) {
1256 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
1257 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1258 }
1259 }
1260 }
1261
1262 decltype(auto) left( derestrict( *this ) );
1263
1264 smpAssign( left, tmp );
1265
1266 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1267
1268 return *this;
1269}
1271//*************************************************************************************************
1272
1273
1274//*************************************************************************************************
1288template< typename MT // Type of the dense matrix
1289 , bool SF // Symmetry flag
1290 , typename... CRAs > // Compile time row arguments
1291template< typename MT2 // Type of the right-hand side matrix
1292 , bool SO2 > // Storage order of the right-hand side matrix
1293inline auto Rows<MT,true,true,SF,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1294 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1295{
1298
1302
1303 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1304
1306
1307 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1308 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1309 }
1310
1311 if( IsRestricted_v<MT> ) {
1312 for( size_t i=0UL; i<rows(); ++i ) {
1313 if( !tryMultAssign( row( matrix_, idx(i), unchecked ), row( *rhs, i, unchecked ), 0UL ) ) {
1314 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1315 }
1316 }
1317 }
1318
1319 decltype(auto) left( derestrict( *this ) );
1320
1321 if( (*rhs).canAlias( this ) ) {
1322 const SchurType tmp( *this % (*rhs) );
1323 if( IsSparseMatrix_v<SchurType> )
1324 reset();
1325 smpAssign( left, tmp );
1326 }
1327 else {
1328 smpSchurAssign( left, *rhs );
1329 }
1330
1331 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1332
1333 return *this;
1334}
1336//*************************************************************************************************
1337
1338
1339//*************************************************************************************************
1353template< typename MT // Type of the dense matrix
1354 , bool SF // Symmetry flag
1355 , typename... CRAs > // Compile time row arguments
1356template< typename MT2 // Type of the right-hand side matrix
1357 , bool SO2 > // Storage order of the right-hand side matrix
1358inline auto Rows<MT,true,true,SF,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1359 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
1360{
1363
1367
1368 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1369
1371
1372 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1373 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1374 }
1375
1376 const SchurType tmp( *this % (*rhs) );
1377
1378 if( IsRestricted_v<MT> ) {
1379 for( size_t i=0UL; i<rows(); ++i ) {
1380 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
1381 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1382 }
1383 }
1384 }
1385
1386 decltype(auto) left( derestrict( *this ) );
1387
1388 if( IsSparseMatrix_v<SchurType> ) {
1389 reset();
1390 }
1391
1392 smpAssign( left, tmp );
1393
1394 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1395
1396 return *this;
1397}
1399//*************************************************************************************************
1400
1401
1402
1403
1404//=================================================================================================
1405//
1406// UTILITY FUNCTIONS
1407//
1408//=================================================================================================
1409
1410//*************************************************************************************************
1416template< typename MT // Type of the dense matrix
1417 , bool SF // Symmetry flag
1418 , typename... CRAs > // Compile time row arguments
1419inline MT& Rows<MT,true,true,SF,CRAs...>::operand() noexcept
1420{
1421 return matrix_;
1422}
1424//*************************************************************************************************
1425
1426
1427//*************************************************************************************************
1433template< typename MT // Type of the dense matrix
1434 , bool SF // Symmetry flag
1435 , typename... CRAs > // Compile time row arguments
1436inline const MT& Rows<MT,true,true,SF,CRAs...>::operand() const noexcept
1437{
1438 return matrix_;
1439}
1441//*************************************************************************************************
1442
1443
1444//*************************************************************************************************
1450template< typename MT // Type of the dense matrix
1451 , bool SF // Symmetry flag
1452 , typename... CRAs > // Compile time row arguments
1453inline size_t Rows<MT,true,true,SF,CRAs...>::columns() const noexcept
1454{
1455 return matrix_.columns();
1456}
1458//*************************************************************************************************
1459
1460
1461//*************************************************************************************************
1470template< typename MT // Type of the dense matrix
1471 , bool SF // Symmetry flag
1472 , typename... CRAs > // Compile time row arguments
1473inline size_t Rows<MT,true,true,SF,CRAs...>::spacing() const noexcept
1474{
1475 return matrix_.spacing();
1476}
1478//*************************************************************************************************
1479
1480
1481//*************************************************************************************************
1487template< typename MT // Type of the dense matrix
1488 , bool SF // Symmetry flag
1489 , typename... CRAs > // Compile time row arguments
1490inline size_t Rows<MT,true,true,SF,CRAs...>::capacity() const noexcept
1491{
1492 return rows() * columns();
1493}
1495//*************************************************************************************************
1496
1497
1498//*************************************************************************************************
1507template< typename MT // Type of the dense matrix
1508 , bool SF // Symmetry flag
1509 , typename... CRAs > // Compile time row arguments
1510inline size_t Rows<MT,true,true,SF,CRAs...>::capacity( size_t i ) const noexcept
1511{
1512 MAYBE_UNUSED( i );
1513
1514 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1515
1516 return columns();
1517}
1519//*************************************************************************************************
1520
1521
1522//*************************************************************************************************
1528template< typename MT // Type of the dense matrix
1529 , bool SF // Symmetry flag
1530 , typename... CRAs > // Compile time row arguments
1531inline size_t Rows<MT,true,true,SF,CRAs...>::nonZeros() const
1532{
1533 size_t nonzeros( 0UL );
1534
1535 for( size_t i=0UL; i<rows(); ++i ) {
1536 nonzeros += matrix_.nonZeros( idx(i) );
1537 }
1538
1539 return nonzeros;
1540}
1542//*************************************************************************************************
1543
1544
1545//*************************************************************************************************
1554template< typename MT // Type of the dense matrix
1555 , bool SF // Symmetry flag
1556 , typename... CRAs > // Compile time row arguments
1557inline size_t Rows<MT,true,true,SF,CRAs...>::nonZeros( size_t i ) const
1558{
1559 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
1560
1561 return matrix_.nonZeros( idx(i) );
1562}
1564//*************************************************************************************************
1565
1566
1567//*************************************************************************************************
1573template< typename MT // Type of the dense matrix
1574 , bool SF // Symmetry flag
1575 , typename... CRAs > // Compile time row arguments
1577{
1578 for( size_t i=0UL; i<rows(); ++i ) {
1579 matrix_.reset( idx(i) );
1580 }
1581}
1583//*************************************************************************************************
1584
1585
1586//*************************************************************************************************
1595template< typename MT // Type of the dense matrix
1596 , bool SF // Symmetry flag
1597 , typename... CRAs > // Compile time row arguments
1598inline void Rows<MT,true,true,SF,CRAs...>::reset( size_t i )
1599{
1600 matrix_.reset( idx(i) );
1601}
1603//*************************************************************************************************
1604
1605
1606
1607
1608//=================================================================================================
1609//
1610// NUMERIC FUNCTIONS
1611//
1612//=================================================================================================
1613
1614//*************************************************************************************************
1627template< typename MT // Type of the dense matrix
1628 , bool SF // Symmetry flag
1629 , typename... CRAs > // Compile time row arguments
1630inline Rows<MT,true,true,SF,CRAs...>&
1632{
1635
1636 if( rows() != columns() ) {
1637 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1638 }
1639
1640 const ResultType tmp( trans( *this ) );
1641
1642 if( IsRestricted_v<MT> ) {
1643 for( size_t i=0UL; i<rows(); ++i ) {
1644 if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
1645 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1646 }
1647 }
1648 }
1649
1650 decltype(auto) left( derestrict( *this ) );
1651
1652 smpAssign( left, tmp );
1653
1654 return *this;
1655}
1657//*************************************************************************************************
1658
1659
1660//*************************************************************************************************
1673template< typename MT // Type of the dense matrix
1674 , bool SF // Symmetry flag
1675 , typename... CRAs > // Compile time row arguments
1676inline Rows<MT,true,true,SF,CRAs...>&
1678{
1681
1682 if( rows() != columns() ) {
1683 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1684 }
1685
1686 const ResultType tmp( ctrans( *this ) );
1687
1688 if( IsRestricted_v<MT> ) {
1689 for( size_t i=0UL; i<rows(); ++i ) {
1690 if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
1691 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1692 }
1693 }
1694 }
1695
1696 decltype(auto) left( derestrict( *this ) );
1697
1698 smpAssign( left, tmp );
1699
1700 return *this;
1701}
1703//*************************************************************************************************
1704
1705
1706//*************************************************************************************************
1719template< typename MT // Type of the dense matrix
1720 , bool SF // Symmetry flag
1721 , typename... CRAs > // Compile time row arguments
1722template< typename Other > // Data type of the scalar value
1723inline Rows<MT,true,true,SF,CRAs...>&
1724 Rows<MT,true,true,SF,CRAs...>::scale( const Other& scalar )
1725{
1729
1730 for( size_t i=0UL; i<rows(); ++i )
1731 {
1732 const size_t index ( idx(i) );
1733 const size_t jbegin( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index+1UL : index ) : 0UL );
1734 const size_t jend ( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index : index+1UL ) : columns() );
1735
1736 for( size_t j=jbegin; j<jend; ++j ) {
1737 matrix_(index,j) *= scalar;
1738 }
1739 }
1740
1741 return *this;
1742}
1744//*************************************************************************************************
1745
1746
1747
1748
1749//=================================================================================================
1750//
1751// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1752//
1753//=================================================================================================
1754
1755//*************************************************************************************************
1766template< typename MT // Type of the dense matrix
1767 , bool SF // Symmetry flag
1768 , typename... CRAs > // Compile time row arguments
1769template< typename Other > // Data type of the foreign expression
1770inline bool Rows<MT,true,true,SF,CRAs...>::canAlias( const Other* alias ) const noexcept
1771{
1772 return matrix_.isAliased( &unview( *alias ) );
1773}
1775//*************************************************************************************************
1776
1777
1778//*************************************************************************************************
1790template< typename MT // Type of the dense matrix
1791 , bool SF // Symmetry flag
1792 , typename... CRAs > // Compile time row arguments
1793template< typename MT2 // Data type of the foreign dense row selection
1794 , bool SO2 // Storage order of the foreign dense row selection
1795 , bool SF2 // Symmetry flag of the foreign dense row selection
1796 , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
1797inline bool
1798 Rows<MT,true,true,SF,CRAs...>::canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
1799{
1800 return matrix_.isAliased( &alias->matrix_ );
1801}
1803//*************************************************************************************************
1804
1805
1806//*************************************************************************************************
1817template< typename MT // Type of the dense matrix
1818 , bool SF // Symmetry flag
1819 , typename... CRAs > // Compile time row arguments
1820template< typename Other > // Data type of the foreign expression
1821inline bool Rows<MT,true,true,SF,CRAs...>::isAliased( const Other* alias ) const noexcept
1822{
1823 return matrix_.isAliased( &unview( *alias ) );
1824}
1826//*************************************************************************************************
1827
1828
1829//*************************************************************************************************
1841template< typename MT // Type of the dense matrix
1842 , bool SF // Symmetry flag
1843 , typename... CRAs > // Compile time row arguments
1844template< typename MT2 // Data type of the foreign dense row selection
1845 , bool SO2 // Storage order of the foreign dense row selection
1846 , bool SF2 // Symmetry flag of the foreign dense row selection
1847 , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
1848inline bool
1849 Rows<MT,true,true,SF,CRAs...>::isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
1850{
1851 return matrix_.isAliased( &alias->matrix_ );
1852}
1854//*************************************************************************************************
1855
1856
1857//*************************************************************************************************
1867template< typename MT // Type of the dense matrix
1868 , bool SF // Symmetry flag
1869 , typename... CRAs > // Compile time row arguments
1870inline bool Rows<MT,true,true,SF,CRAs...>::isAligned() const noexcept
1871{
1872 return matrix_.isAligned();
1873}
1875//*************************************************************************************************
1876
1877
1878//*************************************************************************************************
1889template< typename MT // Type of the dense matrix
1890 , bool SF // Symmetry flag
1891 , typename... CRAs > // Compile time row arguments
1892inline bool Rows<MT,true,true,SF,CRAs...>::canSMPAssign() const noexcept
1893{
1894 return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
1895}
1897//*************************************************************************************************
1898
1899
1900//*************************************************************************************************
1915template< typename MT // Type of the dense matrix
1916 , bool SF // Symmetry flag
1917 , typename... CRAs > // Compile time row arguments
1918BLAZE_ALWAYS_INLINE typename Rows<MT,true,true,SF,CRAs...>::SIMDType
1919 Rows<MT,true,true,SF,CRAs...>::load( size_t i, size_t j ) const noexcept
1920{
1921 return matrix_.load( idx(i), j );
1922}
1924//*************************************************************************************************
1925
1926
1927//*************************************************************************************************
1942template< typename MT // Type of the dense matrix
1943 , bool SF // Symmetry flag
1944 , typename... CRAs > // Compile time row arguments
1945BLAZE_ALWAYS_INLINE typename Rows<MT,true,true,SF,CRAs...>::SIMDType
1946 Rows<MT,true,true,SF,CRAs...>::loada( size_t i, size_t j ) const noexcept
1947{
1948 return matrix_.loada( idx(i), j );
1949}
1951//*************************************************************************************************
1952
1953
1954//*************************************************************************************************
1969template< typename MT // Type of the dense matrix
1970 , bool SF // Symmetry flag
1971 , typename... CRAs > // Compile time row arguments
1972BLAZE_ALWAYS_INLINE typename Rows<MT,true,true,SF,CRAs...>::SIMDType
1973 Rows<MT,true,true,SF,CRAs...>::loadu( size_t i, size_t j ) const noexcept
1974{
1975 return matrix_.loadu( idx(i), j );
1976}
1978//*************************************************************************************************
1979
1980
1981//*************************************************************************************************
1997template< typename MT // Type of the dense matrix
1998 , bool SF // Symmetry flag
1999 , typename... CRAs > // Compile time row arguments
2001 Rows<MT,true,true,SF,CRAs...>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2002{
2003 matrix_.store( idx(i), j, value );
2004}
2006//*************************************************************************************************
2007
2008
2009//*************************************************************************************************
2025template< typename MT // Type of the dense matrix
2026 , bool SF // Symmetry flag
2027 , typename... CRAs > // Compile time row arguments
2029 Rows<MT,true,true,SF,CRAs...>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2030{
2031 matrix_.storea( idx(i), j, value );
2032}
2034//*************************************************************************************************
2035
2036
2037//*************************************************************************************************
2053template< typename MT // Type of the dense matrix
2054 , bool SF // Symmetry flag
2055 , typename... CRAs > // Compile time row arguments
2057 Rows<MT,true,true,SF,CRAs...>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2058{
2059 matrix_.storeu( idx(i), j, value );
2060}
2062//*************************************************************************************************
2063
2064
2065//*************************************************************************************************
2081template< typename MT // Type of the dense matrix
2082 , bool SF // Symmetry flag
2083 , typename... CRAs > // Compile time row arguments
2085 Rows<MT,true,true,SF,CRAs...>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2086{
2087 matrix_.stream( idx(i), j, value );
2088}
2090//*************************************************************************************************
2091
2092
2093//*************************************************************************************************
2105template< typename MT // Type of the dense matrix
2106 , bool SF // Symmetry flag
2107 , typename... CRAs > // Compile time row arguments
2108template< typename MT2 > // Type of the right-hand side dense matrix
2109inline auto Rows<MT,true,true,SF,CRAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2110 -> DisableIf_t< VectorizedAssign_v<MT2> >
2111{
2114
2115 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2116 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2117
2118 const size_t jpos( prevMultiple( columns(), 2UL ) );
2119 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
2120
2121 for( size_t i=0UL; i<rows(); ++i ) {
2122 const size_t index( idx(i) );
2123 for( size_t j=0UL; j<jpos; j+=2UL ) {
2124 matrix_(index,j ) = (*rhs)(i,j );
2125 matrix_(index,j+1UL) = (*rhs)(i,j+1UL);
2126 }
2127 if( jpos < columns() ) {
2128 matrix_(index,jpos) = (*rhs)(i,jpos);
2129 }
2130 }
2131}
2133//*************************************************************************************************
2134
2135
2136//*************************************************************************************************
2148template< typename MT // Type of the dense matrix
2149 , bool SF // Symmetry flag
2150 , typename... CRAs > // Compile time row arguments
2151template< typename MT2 > // Type of the right-hand side dense matrix
2152inline auto Rows<MT,true,true,SF,CRAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2153 -> EnableIf_t< VectorizedAssign_v<MT2> >
2154{
2157
2159
2160 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2161 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2162
2163 const size_t jpos( prevMultiple( columns(), SIMDSIZE ) );
2164 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
2165
2166 if( useStreaming &&
2167 rows()*columns() > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2168 !(*rhs).isAliased( this ) )
2169 {
2170 for( size_t i=0UL; i<rows(); ++i )
2171 {
2172 size_t j( 0UL );
2173 Iterator left( begin(i) );
2174 ConstIterator_t<MT2> right( (*rhs).begin(i) );
2175
2176 for( ; j<jpos; j+=SIMDSIZE ) {
2177 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2178 }
2179 for( ; j<columns(); ++j ) {
2180 *left = *right;
2181 }
2182 }
2183 }
2184 else
2185 {
2186 for( size_t i=0UL; i<rows(); ++i )
2187 {
2188 size_t j( 0UL );
2189 Iterator left( begin(i) );
2190 ConstIterator_t<MT2> right( (*rhs).begin(i) );
2191
2192 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2193 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2194 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2195 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2196 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2197 }
2198 for( ; j<jpos; j+=SIMDSIZE ) {
2199 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2200 }
2201 for( ; j<columns(); ++j ) {
2202 *left = *right; ++left; ++right;
2203 }
2204 }
2205 }
2206}
2208//*************************************************************************************************
2209
2210
2211//*************************************************************************************************
2223template< typename MT // Type of the dense matrix
2224 , bool SF // Symmetry flag
2225 , typename... CRAs > // Compile time row arguments
2226template< typename MT2 > // Type of the right-hand side dense matrix
2227inline void Rows<MT,true,true,SF,CRAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2228{
2231
2233
2234 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2235 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2236
2237 constexpr size_t block( BLOCK_SIZE );
2238
2239 if( rows() < block && columns() < block )
2240 {
2241 const size_t jpos( prevMultiple( (*rhs).columns(), 2UL ) );
2242 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).columns(), "Invalid end calculation" );
2243
2244 for( size_t i=0UL; i<rows(); ++i ) {
2245 const size_t index( idx(i) );
2246 for( size_t j=0UL; j<jpos; j+=2UL ) {
2247 matrix_(index,j ) = (*rhs)(i,j );
2248 matrix_(index,j+1UL) = (*rhs)(i,j+1UL);
2249 }
2250 if( jpos < (*rhs).columns() ) {
2251 matrix_(index,jpos) = (*rhs)(i,jpos);
2252 }
2253 }
2254 }
2255 else
2256 {
2257 for( size_t ii=0UL; ii<rows(); ii+=block ) {
2258 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2259 for( size_t jj=0UL; jj<columns(); jj+=block ) {
2260 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2261 for( size_t i=ii; i<iend; ++i ) {
2262 const size_t index( idx(i) );
2263 for( size_t j=jj; j<jend; ++j ) {
2264 matrix_(index,j) = (*rhs)(i,j);
2265 }
2266 }
2267 }
2268 }
2269 }
2270}
2272//*************************************************************************************************
2273
2274
2275//*************************************************************************************************
2287template< typename MT // Type of the dense matrix
2288 , bool SF // Symmetry flag
2289 , typename... CRAs > // Compile time row arguments
2290template< typename MT2 > // Type of the right-hand side sparse matrix
2291inline void Rows<MT,true,true,SF,CRAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2292{
2295
2296 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2297 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2298
2299 for( size_t i=0UL; i<rows(); ++i ) {
2300 const size_t index( idx(i) );
2301 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2302 matrix_(index,element->index()) = element->value();
2303 }
2304}
2306//*************************************************************************************************
2307
2308
2309//*************************************************************************************************
2321template< typename MT // Type of the dense matrix
2322 , bool SF // Symmetry flag
2323 , typename... CRAs > // Compile time row arguments
2324template< typename MT2 > // Type of the right-hand side sparse matrix
2325inline void Rows<MT,true,true,SF,CRAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2326{
2329
2331
2332 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2333 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2334
2335 for( size_t j=0UL; j<columns(); ++j ) {
2336 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2337 matrix_(idx(element->index()),j) = element->value();
2338 }
2339}
2341//*************************************************************************************************
2342
2343
2344//*************************************************************************************************
2356template< typename MT // Type of the dense matrix
2357 , bool SF // Symmetry flag
2358 , typename... CRAs > // Compile time row arguments
2359template< typename MT2 > // Type of the right-hand side dense matrix
2360inline auto Rows<MT,true,true,SF,CRAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2361 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
2362{
2365
2366 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2367 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2368
2369 const size_t jpos( prevMultiple( columns(), 2UL ) );
2370 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
2371
2372 for( size_t i=0UL; i<rows(); ++i )
2373 {
2374 const size_t index( idx(i) );
2375 if( IsDiagonal_v<MT2> ) {
2376 matrix_(index,i) += (*rhs)(i,i);
2377 }
2378 else {
2379 for( size_t j=0UL; j<jpos; j+=2UL ) {
2380 matrix_(index,j ) += (*rhs)(i,j );
2381 matrix_(index,j+1UL) += (*rhs)(i,j+1UL);
2382 }
2383 if( jpos < columns() ) {
2384 matrix_(index,jpos) += (*rhs)(i,jpos);
2385 }
2386 }
2387 }
2388}
2390//*************************************************************************************************
2391
2392
2393//*************************************************************************************************
2405template< typename MT // Type of the dense matrix
2406 , bool SF // Symmetry flag
2407 , typename... CRAs > // Compile time row arguments
2408template< typename MT2 > // Type of the right-hand side dense matrix
2409inline auto Rows<MT,true,true,SF,CRAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2410 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
2411{
2414
2416
2417 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2418 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2419
2420 for( size_t i=0UL; i<rows(); ++i )
2421 {
2422 const size_t jbegin( ( IsUpper_v<MT2> )
2423 ?( prevMultiple( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ), SIMDSIZE ) )
2424 :( 0UL ) );
2425 const size_t jend ( ( IsLower_v<MT2> )
2426 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
2427 :( columns() ) );
2428 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2429
2430 const size_t jpos( prevMultiple( jend, SIMDSIZE ) );
2431 BLAZE_INTERNAL_ASSERT( jpos <= jend, "Invalid end calculation" );
2432
2433 size_t j( jbegin );
2434 Iterator left( begin(i) + jbegin );
2435 ConstIterator_t<MT2> right( (*rhs).begin(i) + jbegin );
2436
2437 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2438 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
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 }
2443 for( ; j<jpos; j+=SIMDSIZE ) {
2444 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2445 }
2446 for( ; j<jend; ++j ) {
2447 *left += *right; ++left; ++right;
2448 }
2449 }
2450}
2452//*************************************************************************************************
2453
2454
2455//*************************************************************************************************
2467template< typename MT // Type of the dense matrix
2468 , bool SF // Symmetry flag
2469 , typename... CRAs > // Compile time row arguments
2470template< typename MT2 > // Type of the right-hand side dense matrix
2471inline void Rows<MT,true,true,SF,CRAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2472{
2475
2477
2478 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2479 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2480
2481 constexpr size_t block( BLOCK_SIZE );
2482
2483 if( rows() < block && columns() < block )
2484 {
2485 const size_t jpos( prevMultiple( (*rhs).columns(), 2UL ) );
2486 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).columns(), "Invalid end calculation" );
2487
2488 for( size_t i=0UL; i<rows(); ++i ) {
2489 const size_t index( idx(i) );
2490 for( size_t j=0UL; j<jpos; j+=2UL ) {
2491 matrix_(index,j ) += (*rhs)(i,j );
2492 matrix_(index,j+1UL) += (*rhs)(i,j+1UL);
2493 }
2494 if( jpos < (*rhs).columns() ) {
2495 matrix_(index,jpos) += (*rhs)(i,jpos);
2496 }
2497 }
2498 }
2499 else
2500 {
2501 for( size_t ii=0UL; ii<rows(); ii+=block ) {
2502 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2503 for( size_t jj=0UL; jj<columns(); jj+=block ) {
2504 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2505 for( size_t i=ii; i<iend; ++i ) {
2506 const size_t index( idx(i) );
2507 for( size_t j=jj; j<jend; ++j ) {
2508 matrix_(index,j) += (*rhs)(i,j);
2509 }
2510 }
2511 }
2512 }
2513 }
2514}
2516//*************************************************************************************************
2517
2518
2519//*************************************************************************************************
2531template< typename MT // Type of the dense matrix
2532 , bool SF // Symmetry flag
2533 , typename... CRAs > // Compile time row arguments
2534template< typename MT2 > // Type of the right-hand side sparse matrix
2535inline void Rows<MT,true,true,SF,CRAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
2536{
2539
2540 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2541 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2542
2543 for( size_t i=0UL; i<rows(); ++i ) {
2544 const size_t index( idx(i) );
2545 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2546 matrix_(index,element->index()) += element->value();
2547 }
2548}
2550//*************************************************************************************************
2551
2552
2553//*************************************************************************************************
2565template< typename MT // Type of the dense matrix
2566 , bool SF // Symmetry flag
2567 , typename... CRAs > // Compile time row arguments
2568template< typename MT2 > // Type of the right-hand side sparse matrix
2569inline void Rows<MT,true,true,SF,CRAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
2570{
2573
2575
2576 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2577 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2578
2579 for( size_t j=0UL; j<columns(); ++j ) {
2580 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2581 matrix_(idx(element->index()),j) += element->value();
2582 }
2583}
2585//*************************************************************************************************
2586
2587
2588//*************************************************************************************************
2600template< typename MT // Type of the dense matrix
2601 , bool SF // Symmetry flag
2602 , typename... CRAs > // Compile time row arguments
2603template< typename MT2 > // Type of the right-hand side dense matrix
2604inline auto Rows<MT,true,true,SF,CRAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2605 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
2606{
2609
2610 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2611 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2612
2613 const size_t jpos( prevMultiple( columns(), 2UL ) );
2614 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
2615
2616 for( size_t i=0UL; i<rows(); ++i )
2617 {
2618 const size_t index( idx(i) );
2619
2620 if( IsDiagonal_v<MT2> ) {
2621 matrix_(index,i) -= (*rhs)(i,i);
2622 }
2623 else {
2624 for( size_t j=0UL; j<jpos; j+=2UL ) {
2625 matrix_(index,j ) -= (*rhs)(i,j );
2626 matrix_(index,j+1UL) -= (*rhs)(i,j+1UL);
2627 }
2628 if( jpos < columns() ) {
2629 matrix_(index,jpos) -= (*rhs)(i,jpos);
2630 }
2631 }
2632 }
2633}
2635//*************************************************************************************************
2636
2637
2638//*************************************************************************************************
2650template< typename MT // Type of the dense matrix
2651 , bool SF // Symmetry flag
2652 , typename... CRAs > // Compile time row arguments
2653template< typename MT2 > // Type of the right-hand side dense matrix
2654inline auto Rows<MT,true,true,SF,CRAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2655 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
2656{
2659
2661
2662 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2663 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2664
2665 for( size_t i=0UL; i<rows(); ++i )
2666 {
2667 const size_t jbegin( ( IsUpper_v<MT2> )
2668 ?( prevMultiple( ( IsStrictlyUpper_v<MT2> ? i+1UL : i ), SIMDSIZE ) )
2669 :( 0UL ) );
2670 const size_t jend ( ( IsLower_v<MT2> )
2671 ?( IsStrictlyLower_v<MT2> ? i : i+1UL )
2672 :( columns() ) );
2673 BLAZE_INTERNAL_ASSERT( jbegin <= jend, "Invalid loop indices detected" );
2674
2675 const size_t jpos( prevMultiple( jend, SIMDSIZE ) );
2676 BLAZE_INTERNAL_ASSERT( jpos <= jend, "Invalid end calculation" );
2677
2678 size_t j( jbegin );
2679 Iterator left( begin(i) + jbegin );
2680 ConstIterator_t<MT2> right( (*rhs).begin(i) + jbegin );
2681
2682 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
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 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2687 }
2688 for( ; j<jpos; j+=SIMDSIZE ) {
2689 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2690 }
2691 for( ; j<jend; ++j ) {
2692 *left -= *right; ++left; ++right;
2693 }
2694 }
2695}
2697//*************************************************************************************************
2698
2699
2700//*************************************************************************************************
2712template< typename MT // Type of the dense matrix
2713 , bool SF // Symmetry flag
2714 , typename... CRAs > // Compile time row arguments
2715template< typename MT2 > // Type of the right-hand side dense matrix
2716inline void Rows<MT,true,true,SF,CRAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2717{
2720
2722
2723 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2724 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2725
2726 constexpr size_t block( BLOCK_SIZE );
2727
2728 if( rows() < block && columns() < block )
2729 {
2730 const size_t jpos( prevMultiple( (*rhs).columns(), 2UL ) );
2731 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).columns(), "Invalid end calculation" );
2732
2733 for( size_t i=0UL; i<rows(); ++i ) {
2734 const size_t index( idx(i) );
2735 for( size_t j=0UL; j<jpos; j+=2UL ) {
2736 matrix_(index,j ) -= (*rhs)(i,j );
2737 matrix_(index,j+1UL) -= (*rhs)(i,j+1UL);
2738 }
2739 if( jpos < (*rhs).columns() ) {
2740 matrix_(index,jpos) -= (*rhs)(i,jpos);
2741 }
2742 }
2743 }
2744 else
2745 {
2746 for( size_t ii=0UL; ii<rows(); ii+=block ) {
2747 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2748 for( size_t jj=0UL; jj<columns(); jj+=block ) {
2749 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2750 for( size_t i=ii; i<iend; ++i ) {
2751 const size_t index( idx(i) );
2752 for( size_t j=jj; j<jend; ++j ) {
2753 matrix_(index,j) -= (*rhs)(i,j);
2754 }
2755 }
2756 }
2757 }
2758 }
2759}
2761//*************************************************************************************************
2762
2763
2764//*************************************************************************************************
2776template< typename MT // Type of the dense matrix
2777 , bool SF // Symmetry flag
2778 , typename... CRAs > // Compile time row arguments
2779template< typename MT2 > // Type of the right-hand side sparse matrix
2780inline void Rows<MT,true,true,SF,CRAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
2781{
2784
2785 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2786 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2787
2788 for( size_t i=0UL; i<rows(); ++i ) {
2789 const size_t index( idx(i) );
2790 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2791 matrix_(index,element->index()) -= element->value();
2792 }
2793}
2795//*************************************************************************************************
2796
2797
2798//*************************************************************************************************
2810template< typename MT // Type of the dense matrix
2811 , bool SF // Symmetry flag
2812 , typename... CRAs > // Compile time row arguments
2813template< typename MT2 > // Type of the right-hand side sparse matrix
2814inline void Rows<MT,true,true,SF,CRAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
2815{
2818
2820
2821 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2822 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2823
2824 for( size_t j=0UL; j<columns(); ++j ) {
2825 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2826 matrix_(idx(element->index()),j) -= element->value();
2827 }
2828}
2830//*************************************************************************************************
2831
2832
2833//*************************************************************************************************
2845template< typename MT // Type of the dense matrix
2846 , bool SF // Symmetry flag
2847 , typename... CRAs > // Compile time row arguments
2848template< typename MT2 > // Type of the right-hand side dense matrix
2849inline auto Rows<MT,true,true,SF,CRAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2850 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
2851{
2854
2855 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2856 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2857
2858 const size_t jpos( prevMultiple( columns(), 2UL ) );
2859 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
2860
2861 for( size_t i=0UL; i<rows(); ++i ) {
2862 const size_t index( idx(i) );
2863 for( size_t j=0UL; j<jpos; j+=2UL ) {
2864 matrix_(index,j ) *= (*rhs)(i,j );
2865 matrix_(index,j+1UL) *= (*rhs)(i,j+1UL);
2866 }
2867 if( jpos < columns() ) {
2868 matrix_(index,jpos) *= (*rhs)(i,jpos);
2869 }
2870 }
2871}
2873//*************************************************************************************************
2874
2875
2876//*************************************************************************************************
2888template< typename MT // Type of the dense matrix
2889 , bool SF // Symmetry flag
2890 , typename... CRAs > // Compile time row arguments
2891template< typename MT2 > // Type of the right-hand side dense matrix
2892inline auto Rows<MT,true,true,SF,CRAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2893 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
2894{
2897
2899
2900 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2901 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2902
2903 for( size_t i=0UL; i<rows(); ++i )
2904 {
2905 const size_t jpos( prevMultiple( columns(), SIMDSIZE ) );
2906 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
2907
2908 size_t j( 0UL );
2909 Iterator left( begin(i) );
2910 ConstIterator_t<MT2> right( (*rhs).begin(i) );
2911
2912 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2913 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2914 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2915 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2916 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2917 }
2918 for( ; j<jpos; j+=SIMDSIZE ) {
2919 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2920 }
2921 for( ; j<columns(); ++j ) {
2922 *left *= *right; ++left; ++right;
2923 }
2924 }
2925}
2927//*************************************************************************************************
2928
2929
2930//*************************************************************************************************
2942template< typename MT // Type of the dense matrix
2943 , bool SF // Symmetry flag
2944 , typename... CRAs > // Compile time row arguments
2945template< typename MT2 > // Type of the right-hand side dense matrix
2946inline void Rows<MT,true,true,SF,CRAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2947{
2950
2952
2953 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2954 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2955
2956 constexpr size_t block( BLOCK_SIZE );
2957
2958 if( rows() < block && columns() < block )
2959 {
2960 const size_t jpos( prevMultiple( (*rhs).columns(), 2UL ) );
2961 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).columns(), "Invalid end calculation" );
2962
2963 for( size_t i=0UL; i<rows(); ++i ) {
2964 const size_t index( idx(i) );
2965 for( size_t j=0UL; j<jpos; j+=2UL ) {
2966 matrix_(index,j ) *= (*rhs)(i,j );
2967 matrix_(index,j+1UL) *= (*rhs)(i,j+1UL);
2968 }
2969 if( jpos < (*rhs).columns() ) {
2970 matrix_(index,jpos) *= (*rhs)(i,jpos);
2971 }
2972 }
2973 }
2974 else
2975 {
2976 for( size_t ii=0UL; ii<rows(); ii+=block ) {
2977 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2978 for( size_t jj=0UL; jj<columns(); jj+=block ) {
2979 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2980 for( size_t i=ii; i<iend; ++i ) {
2981 const size_t index( idx(i) );
2982 for( size_t j=jj; j<jend; ++j ) {
2983 matrix_(index,j) *= (*rhs)(i,j);
2984 }
2985 }
2986 }
2987 }
2988 }
2989}
2991//*************************************************************************************************
2992
2993
2994//*************************************************************************************************
3006template< typename MT // Type of the dense matrix
3007 , bool SF // Symmetry flag
3008 , typename... CRAs > // Compile time row arguments
3009template< typename MT2 > // Type of the right-hand side sparse matrix
3010inline void Rows<MT,true,true,SF,CRAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
3011{
3014
3015 using blaze::reset;
3016
3017 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
3018 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
3019
3020 for( size_t i=0UL; i<rows(); ++i )
3021 {
3022 const size_t index( idx(i) );
3023 size_t j( 0UL );
3024
3025 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
3026 for( ; j<element->index(); ++j )
3027 reset( matrix_(index,j) );
3028 matrix_(index,j) *= element->value();
3029 ++j;
3030 }
3031
3032 for( ; j<columns(); ++j ) {
3033 reset( matrix_(index,j) );
3034 }
3035 }
3036}
3038//*************************************************************************************************
3039
3040
3041//*************************************************************************************************
3053template< typename MT // Type of the dense matrix
3054 , bool SF // Symmetry flag
3055 , typename... CRAs > // Compile time row arguments
3056template< typename MT2 > // Type of the right-hand side sparse matrix
3057inline void Rows<MT,true,true,SF,CRAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
3058{
3061
3062 using blaze::reset;
3063
3065
3066 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
3067 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
3068
3069 for( size_t j=0UL; j<columns(); ++j )
3070 {
3071 size_t i( 0UL );
3072
3073 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
3074 for( ; i<element->index(); ++i )
3075 reset( matrix_(idx(i),j) );
3076 matrix_(idx(i),j) *= element->value();
3077 ++i;
3078 }
3079
3080 for( ; i<rows(); ++i ) {
3081 reset( matrix_(idx(i),j) );
3082 }
3083 }
3084}
3086//*************************************************************************************************
3087
3088
3089
3090
3091
3092
3093
3094
3095//=================================================================================================
3096//
3097// CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR DENSE MATRICES
3098//
3099//=================================================================================================
3100
3101//*************************************************************************************************
3109template< typename MT // Type of the dense matrix
3110 , typename... CRAs > // Compile time row arguments
3111class Rows<MT,false,true,false,CRAs...>
3112 : public View< DenseMatrix< Rows<MT,false,true,false,CRAs...>, false > >
3113 , private RowsData<CRAs...>
3114{
3115 private:
3116 //**Type definitions****************************************************************************
3117 using DataType = RowsData<CRAs...>;
3118 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
3119 //**********************************************************************************************
3120
3121 //**Compile time flags**************************************************************************
3122 using DataType::N;
3123 //**********************************************************************************************
3124
3125 //**********************************************************************************************
3127 template< typename MT1, typename MT2 >
3128 static constexpr bool EnforceEvaluation_v =
3129 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
3130 //**********************************************************************************************
3131
3132 public:
3133 //**Type definitions****************************************************************************
3135 using This = Rows<MT,false,true,false,CRAs...>;
3136
3138 using BaseType = View< DenseMatrix<This,false> >;
3139
3140 using ViewedType = MT;
3141 using ResultType = RowsTrait_t<MT,N>;
3142 using OppositeType = OppositeType_t<ResultType>;
3143 using TransposeType = TransposeType_t<ResultType>;
3144 using ElementType = ElementType_t<MT>;
3145 using ReturnType = ReturnType_t<MT>;
3146 using CompositeType = const Rows&;
3147
3149 using ConstReference = ConstReference_t<MT>;
3150
3152 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
3153
3155 using ConstPointer = ConstPointer_t<MT>;
3156
3158 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
3159 //**********************************************************************************************
3160
3161 //**RowsIterator class definition***************************************************************
3164 template< typename MatrixType // Type of the dense matrix
3165 , typename IteratorType > // Type of the dense matrix iterator
3166 class RowsIterator
3167 {
3168 public:
3169 //**Type definitions*************************************************************************
3171 using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
3172
3174 using ValueType = typename std::iterator_traits<IteratorType>::value_type;
3175
3177 using PointerType = typename std::iterator_traits<IteratorType>::pointer;
3178
3180 using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
3181
3183 using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
3184
3185 // STL iterator requirements
3186 using iterator_category = IteratorCategory;
3187 using value_type = ValueType;
3188 using pointer = PointerType;
3189 using reference = ReferenceType;
3190 using difference_type = DifferenceType;
3191 //*******************************************************************************************
3192
3193 //**Constructor******************************************************************************
3196 inline RowsIterator() noexcept
3197 : matrix_( nullptr ) // The dense matrix containing the row
3198 , row_ ( 0UL ) // The current row index
3199 , column_( 0UL ) // The current column index
3200 , pos_ ( ) // Iterator to the current dense element
3201 {}
3202 //*******************************************************************************************
3203
3204 //**Constructor******************************************************************************
3211 inline RowsIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
3212 : matrix_( &matrix ) // The dense matrix containing the selected row
3213 , row_ ( row ) // The current row index
3214 , column_( column ) // The current column index
3215 , pos_ ( ) // Iterator to the current dense element
3216 {
3217 if( column_ != matrix_->columns() )
3218 pos_ = matrix_->begin( column_ ) + row_;
3219 }
3220 //*******************************************************************************************
3221
3222 //**Constructor******************************************************************************
3227 template< typename MatrixType2, typename IteratorType2 >
3228 inline RowsIterator( const RowsIterator<MatrixType2,IteratorType2>& it ) noexcept
3229 : matrix_( it.matrix_ ) // The dense matrix containing the seleted row
3230 , row_ ( it.row_ ) // The current row index
3231 , column_( it.column_ ) // The current column index
3232 , pos_ ( it.pos_ ) // Iterator to the current dense element
3233 {}
3234 //*******************************************************************************************
3235
3236 //**Addition assignment operator*************************************************************
3242 inline RowsIterator& operator+=( size_t inc ) noexcept {
3243 using blaze::reset;
3244 column_ += inc;
3245 if( column_ != matrix_->columns() )
3246 pos_ = matrix_->begin( column_ ) + row_;
3247 else reset( pos_ );
3248 return *this;
3249 }
3250 //*******************************************************************************************
3251
3252 //**Subtraction assignment operator**********************************************************
3258 inline RowsIterator& operator-=( size_t dec ) noexcept {
3259 using blaze::reset;
3260 column_ -= dec;
3261 if( column_ != matrix_->columns() )
3262 pos_ = matrix_->begin( column_ ) + row_;
3263 else reset( pos_ );
3264 return *this;
3265 }
3266 //*******************************************************************************************
3267
3268 //**Prefix increment operator****************************************************************
3273 inline RowsIterator& operator++() noexcept {
3274 using blaze::reset;
3275 ++column_;
3276 if( column_ != matrix_->columns() )
3277 pos_ = matrix_->begin( column_ ) + row_;
3278 else reset( pos_ );
3279 return *this;
3280 }
3281 //*******************************************************************************************
3282
3283 //**Postfix increment operator***************************************************************
3288 inline const RowsIterator operator++( int ) noexcept {
3289 const RowsIterator tmp( *this );
3290 ++(*this);
3291 return tmp;
3292 }
3293 //*******************************************************************************************
3294
3295 //**Prefix decrement operator****************************************************************
3300 inline RowsIterator& operator--() noexcept {
3301 using blaze::reset;
3302 --column_;
3303 if( column_ != matrix_->columns() )
3304 pos_ = matrix_->begin( column_ ) + row_;
3305 else reset( pos_ );
3306 return *this;
3307 }
3308 //*******************************************************************************************
3309
3310 //**Postfix decrement operator***************************************************************
3315 inline const RowsIterator operator--( int ) noexcept {
3316 const RowsIterator tmp( *this );
3317 --(*this);
3318 return tmp;
3319 }
3320 //*******************************************************************************************
3321
3322 //**Subscript operator***********************************************************************
3328 inline ReferenceType operator[]( size_t index ) const {
3329 BLAZE_USER_ASSERT( column_+index < matrix_->columns(), "Invalid access index detected" );
3330 const IteratorType pos( matrix_->begin( column_+index ) + row_ );
3331 return *pos;
3332 }
3333 //*******************************************************************************************
3334
3335 //**Element access operator******************************************************************
3340 inline ReferenceType operator*() const {
3341 return *pos_;
3342 }
3343 //*******************************************************************************************
3344
3345 //**Element access operator******************************************************************
3350 inline PointerType operator->() const {
3351 return pos_;
3352 }
3353 //*******************************************************************************************
3354
3355 //**Equality operator************************************************************************
3361 template< typename MatrixType2, typename IteratorType2 >
3362 inline bool operator==( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3363 return column_ == rhs.column_;
3364 }
3365 //*******************************************************************************************
3366
3367 //**Inequality operator**********************************************************************
3373 template< typename MatrixType2, typename IteratorType2 >
3374 inline bool operator!=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3375 return !( *this == rhs );
3376 }
3377 //*******************************************************************************************
3378
3379 //**Less-than operator***********************************************************************
3385 template< typename MatrixType2, typename IteratorType2 >
3386 inline bool operator<( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3387 return column_ < rhs.column_;
3388 }
3389 //*******************************************************************************************
3390
3391 //**Greater-than operator********************************************************************
3397 template< typename MatrixType2, typename IteratorType2 >
3398 inline bool operator>( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3399 return column_ > rhs.column_;
3400 }
3401 //*******************************************************************************************
3402
3403 //**Less-or-equal-than operator**************************************************************
3409 template< typename MatrixType2, typename IteratorType2 >
3410 inline bool operator<=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3411 return column_ <= rhs.column_;
3412 }
3413 //*******************************************************************************************
3414
3415 //**Greater-or-equal-than operator***********************************************************
3421 template< typename MatrixType2, typename IteratorType2 >
3422 inline bool operator>=( const RowsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3423 return column_ >= rhs.column_;
3424 }
3425 //*******************************************************************************************
3426
3427 //**Subtraction operator*********************************************************************
3433 inline DifferenceType operator-( const RowsIterator& rhs ) const noexcept {
3434 return column_ - rhs.column_;
3435 }
3436 //*******************************************************************************************
3437
3438 //**Addition operator************************************************************************
3445 friend inline const RowsIterator operator+( const RowsIterator& it, size_t inc ) noexcept {
3446 return RowsIterator( *it.matrix_, it.row_, it.column_+inc );
3447 }
3448 //*******************************************************************************************
3449
3450 //**Addition operator************************************************************************
3457 friend inline const RowsIterator operator+( size_t inc, const RowsIterator& it ) noexcept {
3458 return RowsIterator( *it.matrix_, it.row_, it.column_+inc );
3459 }
3460 //*******************************************************************************************
3461
3462 //**Subtraction operator*********************************************************************
3469 friend inline const RowsIterator operator-( const RowsIterator& it, size_t dec ) noexcept {
3470 return RowsIterator( *it.matrix_, it.row_, it.column_-dec );
3471 }
3472 //*******************************************************************************************
3473
3474 private:
3475 //**Member variables*************************************************************************
3476 MatrixType* matrix_;
3477 size_t row_;
3478 size_t column_;
3479 IteratorType pos_;
3480 //*******************************************************************************************
3481
3482 //**Friend declarations**********************************************************************
3483 template< typename MatrixType2, typename IteratorType2 > friend class RowsIterator;
3484 //*******************************************************************************************
3485 };
3486 //**********************************************************************************************
3487
3488 //**Type definitions****************************************************************************
3490 using ConstIterator = RowsIterator< const MT, ConstIterator_t<MT> >;
3491
3493 using Iterator = If_t< IsConst_v<MT>, ConstIterator, RowsIterator< MT, Iterator_t<MT> > >;
3494 //**********************************************************************************************
3495
3496 //**Compilation flags***************************************************************************
3498 static constexpr bool simdEnabled = false;
3499
3501 static constexpr bool smpAssignable = MT::smpAssignable;
3502
3504 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
3505 //**********************************************************************************************
3506
3507 //**Constructors********************************************************************************
3510 template< typename... RRAs >
3511 explicit inline Rows( MT& matrix, RRAs... args );
3512
3513 Rows( const Rows& ) = default;
3514 Rows( Rows&& ) = default;
3516 //**********************************************************************************************
3517
3518 //**Destructor**********************************************************************************
3521 ~Rows() = default;
3523 //**********************************************************************************************
3524
3525 //**Data access functions***********************************************************************
3528 inline Reference operator()( size_t i, size_t j );
3529 inline ConstReference operator()( size_t i, size_t j ) const;
3530 inline Reference at( size_t i, size_t j );
3531 inline ConstReference at( size_t i, size_t j ) const;
3532 inline Pointer data () noexcept;
3533 inline ConstPointer data () const noexcept;
3534 inline Pointer data ( size_t i ) noexcept;
3535 inline ConstPointer data ( size_t i ) const noexcept;
3536 inline Iterator begin ( size_t i );
3537 inline ConstIterator begin ( size_t i ) const;
3538 inline ConstIterator cbegin( size_t i ) const;
3539 inline Iterator end ( size_t i );
3540 inline ConstIterator end ( size_t i ) const;
3541 inline ConstIterator cend ( size_t i ) const;
3543 //**********************************************************************************************
3544
3545 //**Assignment operators************************************************************************
3548 inline Rows& operator=( const ElementType& rhs );
3549 inline Rows& operator=( initializer_list< initializer_list<ElementType> > list );
3550 inline Rows& operator=( const Rows& rhs );
3551
3552 template< typename MT2, bool SO2 >
3553 inline Rows& operator=( const Matrix<MT2,SO2>& rhs );
3554
3555 template< typename MT2, bool SO2 >
3556 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3557 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3558
3559 template< typename MT2, bool SO2 >
3560 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3561 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3562
3563 template< typename MT2, bool SO2 >
3564 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3565 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3566
3567 template< typename MT2, bool SO2 >
3568 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3569 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3570
3571 template< typename MT2, bool SO2 >
3572 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3573 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3574
3575 template< typename MT2, bool SO2 >
3576 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3577 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >;
3579 //**********************************************************************************************
3580
3581 //**Utility functions***************************************************************************
3584 using DataType::idx;
3585 using DataType::idces;
3586 using DataType::rows;
3587
3588 inline MT& operand() noexcept;
3589 inline const MT& operand() const noexcept;
3590
3591 inline size_t columns() const noexcept;
3592 inline size_t spacing() const noexcept;
3593 inline size_t capacity() const noexcept;
3594 inline size_t capacity( size_t i ) const noexcept;
3595 inline size_t nonZeros() const;
3596 inline size_t nonZeros( size_t i ) const;
3597 inline void reset();
3598 inline void reset( size_t i );
3600 //**********************************************************************************************
3601
3602 //**Numeric functions***************************************************************************
3605 inline Rows& transpose();
3606 inline Rows& ctranspose();
3607
3608 template< typename Other > inline Rows& scale( const Other& scalar );
3610 //**********************************************************************************************
3611
3612 //**Expression template evaluation functions****************************************************
3615 template< typename Other >
3616 inline bool canAlias( const Other* alias ) const noexcept;
3617
3618 template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
3619 inline bool canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
3620
3621 template< typename Other >
3622 inline bool isAliased( const Other* alias ) const noexcept;
3623
3624 template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
3625 inline bool isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
3626
3627 inline bool isAligned () const noexcept;
3628 inline bool canSMPAssign() const noexcept;
3629
3630 template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3631 template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
3632 template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3633 template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3634
3635 template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3636 template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
3637 template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3638 template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3639
3640 template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3641 template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
3642 template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3643 template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3644
3645 template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
3646 template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
3647 template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
3648 template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
3650 //**********************************************************************************************
3651
3652 private:
3653 //**Member variables****************************************************************************
3656 Operand matrix_;
3658 //**********************************************************************************************
3659
3660 //**Friend declarations*************************************************************************
3661 template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CRAs2 > friend class Rows;
3662 //**********************************************************************************************
3663
3664 //**Compile time checks*************************************************************************
3674 //**********************************************************************************************
3675};
3677//*************************************************************************************************
3678
3679
3680
3681
3682//=================================================================================================
3683//
3684// CONSTRUCTORS
3685//
3686//=================================================================================================
3687
3688//*************************************************************************************************
3701template< typename MT // Type of the dense matrix
3702 , typename... CRAs > // Compile time row arguments
3703template< typename... RRAs > // Runtime row arguments
3704inline Rows<MT,false,true,false,CRAs...>::Rows( MT& matrix, RRAs... args )
3705 : DataType( args... ) // Base class initialization
3706 , matrix_ ( matrix ) // The matrix containing the rows
3707{
3708 if( isChecked( args... ) ) {
3709 for( size_t i=0UL; i<rows(); ++i ) {
3710 if( matrix_.rows() <= idx(i) ) {
3711 BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
3712 }
3713 }
3714 }
3715}
3717//*************************************************************************************************
3718
3719
3720
3721
3722//=================================================================================================
3723//
3724// DATA ACCESS FUNCTIONS
3725//
3726//=================================================================================================
3727
3728//*************************************************************************************************
3739template< typename MT // Type of the dense matrix
3740 , typename... CRAs > // Compile time row arguments
3741inline typename Rows<MT,false,true,false,CRAs...>::Reference
3742 Rows<MT,false,true,false,CRAs...>::operator()( size_t i, size_t j )
3743{
3744 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3745 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3746
3747 return matrix_(idx(i),j);
3748}
3750//*************************************************************************************************
3751
3752
3753//*************************************************************************************************
3764template< typename MT // Type of the dense matrix
3765 , typename... CRAs > // Compile time row arguments
3766inline typename Rows<MT,false,true,false,CRAs...>::ConstReference
3767 Rows<MT,false,true,false,CRAs...>::operator()( size_t i, size_t j ) const
3768{
3769 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3770 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3771
3772 return const_cast<const MT&>( matrix_ )(idx(i),j);
3773}
3775//*************************************************************************************************
3776
3777
3778//*************************************************************************************************
3790template< typename MT // Type of the dense matrix
3791 , typename... CRAs > // Compile time row arguments
3792inline typename Rows<MT,false,true,false,CRAs...>::Reference
3793 Rows<MT,false,true,false,CRAs...>::at( size_t i, size_t j )
3794{
3795 if( i >= rows() ) {
3796 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3797 }
3798 if( j >= columns() ) {
3799 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3800 }
3801 return (*this)(i,j);
3802}
3804//*************************************************************************************************
3805
3806
3807//*************************************************************************************************
3819template< typename MT // Type of the dense matrix
3820 , typename... CRAs > // Compile time row arguments
3821inline typename Rows<MT,false,true,false,CRAs...>::ConstReference
3822 Rows<MT,false,true,false,CRAs...>::at( size_t i, size_t j ) const
3823{
3824 if( i >= rows() ) {
3825 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3826 }
3827 if( j >= columns() ) {
3828 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3829 }
3830 return (*this)(i,j);
3831}
3833//*************************************************************************************************
3834
3835
3836//*************************************************************************************************
3846template< typename MT // Type of the dense matrix
3847 , typename... CRAs > // Compile time row arguments
3848inline typename Rows<MT,false,true,false,CRAs...>::Pointer
3850{
3851 return matrix_.data() + idx(0UL);
3852}
3854//*************************************************************************************************
3855
3856
3857//*************************************************************************************************
3867template< typename MT // Type of the dense matrix
3868 , typename... CRAs > // Compile time row arguments
3869inline typename Rows<MT,false,true,false,CRAs...>::ConstPointer
3871{
3872 return matrix_.data() + idx(0UL);
3873}
3875//*************************************************************************************************
3876
3877
3878//*************************************************************************************************
3887template< typename MT // Type of the dense matrix
3888 , typename... CRAs > // Compile time row arguments
3889inline typename Rows<MT,false,true,false,CRAs...>::Pointer
3890 Rows<MT,false,true,false,CRAs...>::data( size_t i ) noexcept
3891{
3892 return matrix_.data() + idx(i);
3893}
3895//*************************************************************************************************
3896
3897
3898//*************************************************************************************************
3907template< typename MT // Type of the dense matrix
3908 , typename... CRAs > // Compile time row arguments
3909inline typename Rows<MT,false,true,false,CRAs...>::ConstPointer
3910 Rows<MT,false,true,false,CRAs...>::data( size_t i ) const noexcept
3911{
3912 return matrix_.data() + idx(i);
3913}
3915//*************************************************************************************************
3916
3917
3918//*************************************************************************************************
3927template< typename MT // Type of the dense matrix
3928 , typename... CRAs > // Compile time row arguments
3929inline typename Rows<MT,false,true,false,CRAs...>::Iterator
3931{
3932 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3933 return Iterator( matrix_, idx(i), 0UL );
3934}
3936//*************************************************************************************************
3937
3938
3939//*************************************************************************************************
3948template< typename MT // Type of the dense matrix
3949 , typename... CRAs > // Compile time row arguments
3950inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
3952{
3953 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3954 return ConstIterator( matrix_, idx(i), 0UL );
3955}
3957//*************************************************************************************************
3958
3959
3960//*************************************************************************************************
3969template< typename MT // Type of the dense matrix
3970 , typename... CRAs > // Compile time row arguments
3971inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
3973{
3974 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3975 return ConstIterator( matrix_, idx(i), 0UL );
3976}
3978//*************************************************************************************************
3979
3980
3981//*************************************************************************************************
3990template< typename MT // Type of the dense matrix
3991 , typename... CRAs > // Compile time row arguments
3992inline typename Rows<MT,false,true,false,CRAs...>::Iterator
3994{
3995 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
3996 return Iterator( matrix_, idx(i), columns() );
3997}
3999//*************************************************************************************************
4000
4001
4002//*************************************************************************************************
4011template< typename MT // Type of the dense matrix
4012 , typename... CRAs > // Compile time row arguments
4013inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
4015{
4016 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4017 return ConstIterator( matrix_, idx(i), columns() );
4018}
4020//*************************************************************************************************
4021
4022
4023//*************************************************************************************************
4032template< typename MT // Type of the dense matrix
4033 , typename... CRAs > // Compile time row arguments
4034inline typename Rows<MT,false,true,false,CRAs...>::ConstIterator
4036{
4037 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4038 return ConstIterator( matrix_, idx(i), columns() );
4039}
4041//*************************************************************************************************
4042
4043
4044
4045
4046//=================================================================================================
4047//
4048// ASSIGNMENT OPERATORS
4049//
4050//=================================================================================================
4051
4052//*************************************************************************************************
4063template< typename MT // Type of the dense matrix
4064 , typename... CRAs > // Compile time row arguments
4065inline Rows<MT,false,true,false,CRAs...>&
4066 Rows<MT,false,true,false,CRAs...>::operator=( const ElementType& rhs )
4067{
4068 for( size_t i=0UL; i<rows(); ++i ) {
4069 row( matrix_, idx(i), unchecked ) = rhs;
4070 }
4071
4072 return *this;
4073}
4075//*************************************************************************************************
4076
4077
4078//*************************************************************************************************
4094template< typename MT // Type of the dense matrix
4095 , typename... CRAs > // Compile time row arguments
4096inline Rows<MT,false,true,false,CRAs...>&
4097 Rows<MT,false,true,false,CRAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
4098{
4101
4102 if( list.size() != rows() ) {
4103 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row selection" );
4104 }
4105
4106 if( IsRestricted_v<MT> ) {
4107 size_t i( 0UL );
4108 for( const auto& rowList : list ) {
4109 const InitializerVector<ElementType> tmp( rowList, columns() );
4110 if( !tryAssign( row( matrix_, idx(i), unchecked ), tmp, 0UL ) ){
4111 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4112 }
4113 ++i;
4114 }
4115 }
4116
4117 decltype(auto) left( derestrict( *this ) );
4118 size_t i( 0UL );
4119
4120 for( const auto& rowList : list ) {
4121 std::fill( std::copy( rowList.begin(), rowList.end(), left.begin(i) ), left.end(i), ElementType() );
4122 ++i;
4123 }
4124
4125 return *this;
4126}
4128//*************************************************************************************************
4129
4130
4131//*************************************************************************************************
4146template< typename MT // Type of the dense matrix
4147 , typename... CRAs > // Compile time row arguments
4148inline Rows<MT,false,true,false,CRAs...>&
4149 Rows<MT,false,true,false,CRAs...>::operator=( const Rows& rhs )
4150{
4153
4156
4157 if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
4158 return *this;
4159
4160 if( rows() != rhs.rows() || columns() != rhs.columns() ) {
4161 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4162 }
4163
4164 if( IsRestricted_v<MT> ) {
4165 for( size_t i=0UL; i<rows(); ++i ) {
4166 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( rhs, i, unchecked ), 0UL ) ) {
4167 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4168 }
4169 }
4170 }
4171
4172 decltype(auto) left( derestrict( *this ) );
4173
4174 if( rhs.canAlias( this ) ) {
4175 const ResultType tmp( rhs );
4176 smpAssign( left, tmp );
4177 }
4178 else {
4179 smpAssign( left, rhs );
4180 }
4181
4182 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4183
4184 return *this;
4185}
4187//*************************************************************************************************
4188
4189
4190//*************************************************************************************************
4205template< typename MT // Type of the dense matrix
4206 , typename... CRAs > // Compile time row arguments
4207template< typename MT2 // Type of the right-hand side matrix
4208 , bool SO2 > // Storage order of the right-hand side matrix
4209inline Rows<MT,false,true,false,CRAs...>&
4210 Rows<MT,false,true,false,CRAs...>::operator=( const Matrix<MT2,SO2>& rhs )
4211{
4214
4216
4217 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4218 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4219 }
4220
4221 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
4222 Right right( *rhs );
4223
4224 if( IsRestricted_v<MT> ) {
4225 for( size_t i=0UL; i<rows(); ++i ) {
4226 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( right, i, unchecked ), 0UL ) ) {
4227 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4228 }
4229 }
4230 }
4231
4232 decltype(auto) left( derestrict( *this ) );
4233
4234 if( IsSparseMatrix_v<MT2> ) {
4235 reset();
4236 }
4237
4238 if( IsReference_v<Right> && right.canAlias( this ) ) {
4239 const ResultType_t<MT2> tmp( right );
4240 smpAssign( left, tmp );
4241 }
4242 else {
4243 smpAssign( left, right );
4244 }
4245
4246 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4247
4248 return *this;
4249}
4251//*************************************************************************************************
4252
4253
4254//*************************************************************************************************
4268template< typename MT // Type of the dense matrix
4269 , typename... CRAs > // Compile time row arguments
4270template< typename MT2 // Type of the right-hand side matrix
4271 , bool SO2 > // Storage order of the right-hand side matrix
4272inline auto Rows<MT,false,true,false,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4273 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4274{
4277
4281
4282 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4283
4286
4287 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4288 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4289 }
4290
4291 if( IsRestricted_v<MT> ) {
4292 for( size_t i=0UL; i<rows(); ++i ) {
4293 if( !tryAddAssign( row( matrix_, idx(i), unchecked ), row( *rhs, i, unchecked ), 0UL ) ) {
4294 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4295 }
4296 }
4297 }
4298
4299 decltype(auto) left( derestrict( *this ) );
4300
4301 if( (*rhs).canAlias( this ) ) {
4302 const AddType tmp( *this + (*rhs) );
4303 smpAssign( left, tmp );
4304 }
4305 else {
4306 smpAddAssign( left, *rhs );
4307 }
4308
4309 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4310
4311 return *this;
4312}
4314//*************************************************************************************************
4315
4316
4317//*************************************************************************************************
4331template< typename MT // Type of the dense matrix
4332 , typename... CRAs > // Compile time row arguments
4333template< typename MT2 // Type of the right-hand side matrix
4334 , bool SO2 > // Storage order of the right-hand side matrix
4335inline auto Rows<MT,false,true,false,CRAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4336 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4337{
4340
4344
4345 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4346
4349
4350 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4351 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4352 }
4353
4354 const AddType tmp( *this + (*rhs) );
4355
4356 if( IsRestricted_v<MT> ) {
4357 for( size_t i=0UL; i<rows(); ++i ) {
4358 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
4359 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4360 }
4361 }
4362 }
4363
4364 decltype(auto) left( derestrict( *this ) );
4365
4366 smpAssign( left, tmp );
4367
4368 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4369
4370 return *this;
4371}
4373//*************************************************************************************************
4374
4375
4376//*************************************************************************************************
4390template< typename MT // Type of the dense matrix
4391 , typename... CRAs > // Compile time row arguments
4392template< typename MT2 // Type of the right-hand side matrix
4393 , bool SO2 > // Storage order of the right-hand side matrix
4394inline auto Rows<MT,false,true,false,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4395 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4396{
4399
4403
4404 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4405
4408
4409 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4410 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4411 }
4412
4413 if( IsRestricted_v<MT> ) {
4414 for( size_t i=0UL; i<rows(); ++i ) {
4415 if( !trySubAssign( row( matrix_, idx(i), unchecked ), row( *rhs, i, unchecked ), 0UL ) ) {
4416 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4417 }
4418 }
4419 }
4420
4421 decltype(auto) left( derestrict( *this ) );
4422
4423 if( (*rhs).canAlias( this ) ) {
4424 const SubType tmp( *this - (*rhs ) );
4425 smpAssign( left, tmp );
4426 }
4427 else {
4428 smpSubAssign( left, *rhs );
4429 }
4430
4431 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4432
4433 return *this;
4434}
4436//*************************************************************************************************
4437
4438
4439//*************************************************************************************************
4453template< typename MT // Type of the dense matrix
4454 , typename... CRAs > // Compile time row arguments
4455template< typename MT2 // Type of the right-hand side matrix
4456 , bool SO2 > // Storage order of the right-hand side matrix
4457inline auto Rows<MT,false,true,false,CRAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4458 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4459{
4462
4466
4467 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4468
4471
4472 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4473 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4474 }
4475
4476 const SubType tmp( *this - (*rhs) );
4477
4478 if( IsRestricted_v<MT> ) {
4479 for( size_t i=0UL; i<rows(); ++i ) {
4480 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
4481 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4482 }
4483 }
4484 }
4485
4486 decltype(auto) left( derestrict( *this ) );
4487
4488 smpAssign( left, tmp );
4489
4490 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4491
4492 return *this;
4493}
4495//*************************************************************************************************
4496
4497
4498//*************************************************************************************************
4512template< typename MT // Type of the dense matrix
4513 , typename... CRAs > // Compile time row arguments
4514template< typename MT2 // Type of the right-hand side matrix
4515 , bool SO2 > // Storage order of the right-hand side matrix
4516inline auto Rows<MT,false,true,false,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4517 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4518{
4521
4525
4526 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4527
4529
4530 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4531 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4532 }
4533
4534 if( IsRestricted_v<MT> ) {
4535 for( size_t i=0UL; i<rows(); ++i ) {
4536 if( !tryMultAssign( row( matrix_, idx(i), unchecked ), row( *rhs, i, unchecked ), 0UL ) ) {
4537 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4538 }
4539 }
4540 }
4541
4542 decltype(auto) left( derestrict( *this ) );
4543
4544 if( (*rhs).canAlias( this ) ) {
4545 const SchurType tmp( *this % (*rhs) );
4546 if( IsSparseMatrix_v<SchurType> )
4547 reset();
4548 smpAssign( left, tmp );
4549 }
4550 else {
4551 smpSchurAssign( left, *rhs );
4552 }
4553
4554 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4555
4556 return *this;
4557}
4559//*************************************************************************************************
4560
4561
4562//*************************************************************************************************
4576template< typename MT // Type of the dense matrix
4577 , typename... CRAs > // Compile time row arguments
4578template< typename MT2 // Type of the right-hand side matrix
4579 , bool SO2 > // Storage order of the right-hand side matrix
4580inline auto Rows<MT,false,true,false,CRAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4581 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Rows& >
4582{
4585
4589
4590 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4591
4593
4594 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4595 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4596 }
4597
4598 const SchurType tmp( *this % (*rhs) );
4599
4600 if( IsRestricted_v<MT> ) {
4601 for( size_t i=0UL; i<rows(); ++i ) {
4602 if( !tryAssign( row( matrix_, idx(i), unchecked ), row( tmp, i, unchecked ), 0UL ) ) {
4603 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4604 }
4605 }
4606 }
4607
4608 decltype(auto) left( derestrict( *this ) );
4609
4610 if( IsSparseMatrix_v<SchurType> ) {
4611 reset();
4612 }
4613
4614 smpAssign( left, tmp );
4615
4616 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4617
4618 return *this;
4619}
4621//*************************************************************************************************
4622
4623
4624
4625
4626//=================================================================================================
4627//
4628// UTILITY FUNCTIONS
4629//
4630//=================================================================================================
4631
4632//*************************************************************************************************
4638template< typename MT // Type of the dense matrix
4639 , typename... CRAs > // Compile time row arguments
4640inline MT& Rows<MT,false,true,false,CRAs...>::operand() noexcept
4641{
4642 return matrix_;
4643}
4645//*************************************************************************************************
4646
4647
4648//*************************************************************************************************
4654template< typename MT // Type of the dense matrix
4655 , typename... CRAs > // Compile time row arguments
4656inline const MT& Rows<MT,false,true,false,CRAs...>::operand() const noexcept
4657{
4658 return matrix_;
4659}
4661//*************************************************************************************************
4662
4663
4664//*************************************************************************************************
4670template< typename MT // Type of the dense matrix
4671 , typename... CRAs > // Compile time row arguments
4672inline size_t Rows<MT,false,true,false,CRAs...>::columns() const noexcept
4673{
4674 return matrix_.columns();
4675}
4677//*************************************************************************************************
4678
4679
4680//*************************************************************************************************
4689template< typename MT // Type of the dense matrix
4690 , typename... CRAs > // Compile time row arguments
4691inline size_t Rows<MT,false,true,false,CRAs...>::spacing() const noexcept
4692{
4693 return matrix_.columns();
4694}
4696//*************************************************************************************************
4697
4698
4699//*************************************************************************************************
4705template< typename MT // Type of the dense matrix
4706 , typename... CRAs > // Compile time row arguments
4707inline size_t Rows<MT,false,true,false,CRAs...>::capacity() const noexcept
4708{
4709 return rows() * columns();
4710}
4712//*************************************************************************************************
4713
4714
4715//*************************************************************************************************
4724template< typename MT // Type of the dense matrix
4725 , typename... CRAs > // Compile time row arguments
4726inline size_t Rows<MT,false,true,false,CRAs...>::capacity( size_t i ) const noexcept
4727{
4728 MAYBE_UNUSED( i );
4729
4730 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4731
4732 return columns();
4733}
4735//*************************************************************************************************
4736
4737
4738//*************************************************************************************************
4744template< typename MT // Type of the dense matrix
4745 , typename... CRAs > // Compile time row arguments
4747{
4748 size_t nonzeros( 0UL );
4749
4750 for( size_t i=0UL; i<rows(); ++i ) {
4751 nonzeros += nonZeros( i );
4752 }
4753
4754 return nonzeros;
4755}
4757//*************************************************************************************************
4758
4759
4760//*************************************************************************************************
4769template< typename MT // Type of the dense matrix
4770 , typename... CRAs > // Compile time row arguments
4771inline size_t Rows<MT,false,true,false,CRAs...>::nonZeros( size_t i ) const
4772{
4773 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
4774
4775 size_t nonzeros( 0UL );
4776
4777 const size_t index( idx(i) );
4778 for( size_t j=0UL; j<columns(); ++j ) {
4779 if( !isDefault( matrix_( index, j ) ) )
4780 ++nonzeros;
4781 }
4782
4783 return nonzeros;
4784}
4786//*************************************************************************************************
4787
4788
4789//*************************************************************************************************
4795template< typename MT // Type of the dense matrix
4796 , typename... CRAs > // Compile time row arguments
4798{
4799 for( size_t i=0UL; i<rows(); ++i ) {
4800 reset( i );
4801 }
4802}
4804//*************************************************************************************************
4805
4806
4807//*************************************************************************************************
4816template< typename MT // Type of the dense matrix
4817 , typename... CRAs > // Compile time row arguments
4818inline void Rows<MT,false,true,false,CRAs...>::reset( size_t i )
4819{
4820 using blaze::reset;
4821
4822 const size_t index( idx(i) );
4823 for( size_t j=0UL; j<columns(); ++j ) {
4824 reset( matrix_( index, j ) );
4825 }
4826}
4828//*************************************************************************************************
4829
4830
4831
4832
4833//=================================================================================================
4834//
4835// NUMERIC FUNCTIONS
4836//
4837//=================================================================================================
4838
4839//*************************************************************************************************
4852template< typename MT // Type of the dense matrix
4853 , typename... CRAs > // Compile time row arguments
4854inline Rows<MT,false,true,false,CRAs...>&
4856{
4859
4860 if( rows() != columns() ) {
4861 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4862 }
4863
4864 const ResultType tmp( trans( *this ) );
4865
4866 if( IsRestricted_v<MT> ) {
4867 for( size_t i=0UL; i<rows(); ++i ) {
4868 if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
4869 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4870 }
4871 }
4872 }
4873
4874 decltype(auto) left( derestrict( *this ) );
4875
4876 smpAssign( left, tmp );
4877
4878 return *this;
4879}
4881//*************************************************************************************************
4882
4883
4884//*************************************************************************************************
4897template< typename MT // Type of the dense matrix
4898 , typename... CRAs > // Compile time row arguments
4899inline Rows<MT,false,true,false,CRAs...>&
4901{
4904
4905 if( rows() != columns() ) {
4906 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4907 }
4908
4909 const ResultType tmp( ctrans( *this ) );
4910
4911 if( IsRestricted_v<MT> ) {
4912 for( size_t i=0UL; i<rows(); ++i ) {
4913 if( !tryAssign( matrix_, row( tmp, i ), idx(i), 0UL ) ) {
4914 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4915 }
4916 }
4917 }
4918
4919 decltype(auto) left( derestrict( *this ) );
4920
4921 smpAssign( left, tmp );
4922
4923 return *this;
4924}
4926//*************************************************************************************************
4927
4928
4929//*************************************************************************************************
4942template< typename MT // Type of the dense matrix
4943 , typename... CRAs > // Compile time row arguments
4944template< typename Other > // Data type of the scalar value
4945inline Rows<MT,false,true,false,CRAs...>&
4946 Rows<MT,false,true,false,CRAs...>::scale( const Other& scalar )
4947{
4951
4952 for( size_t i=0UL; i<rows(); ++i )
4953 {
4954 const size_t index ( idx(i) );
4955 const size_t jbegin( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index+1UL : index ) : 0UL );
4956 const size_t jend ( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index : index+1UL ) : columns() );
4957
4958 for( size_t j=jbegin; j<jend; ++j ) {
4959 matrix_(index,j) *= scalar;
4960 }
4961 }
4962
4963 return *this;
4964}
4966//*************************************************************************************************
4967
4968
4969
4970
4971//=================================================================================================
4972//
4973// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4974//
4975//=================================================================================================
4976
4977//*************************************************************************************************
4988template< typename MT // Type of the dense matrix
4989 , typename... CRAs > // Compile time row arguments
4990template< typename Other > // Data type of the foreign expression
4991inline bool Rows<MT,false,true,false,CRAs...>::canAlias( const Other* alias ) const noexcept
4992{
4993 return matrix_.isAliased( &unview( *alias ) );
4994}
4996//*************************************************************************************************
4997
4998
4999//*************************************************************************************************
5011template< typename MT // Type of the dense matrix
5012 , typename... CRAs > // Compile time row arguments
5013template< typename MT2 // Data type of the foreign dense row selection
5014 , bool SO2 // Storage order of the foreign dense row selection
5015 , bool SF2 // Symmetry flag of the foreign dense row selection
5016 , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
5017inline bool
5018 Rows<MT,false,true,false,CRAs...>::canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
5019{
5020 return matrix_.isAliased( &alias->matrix_ );
5021}
5023//*************************************************************************************************
5024
5025
5026//*************************************************************************************************
5037template< typename MT // Type of the dense matrix
5038 , typename... CRAs > // Compile time row arguments
5039template< typename Other > // Data type of the foreign expression
5040inline bool Rows<MT,false,true,false,CRAs...>::isAliased( const Other* alias ) const noexcept
5041{
5042 return matrix_.isAliased( &unview( *alias ) );
5043}
5045//*************************************************************************************************
5046
5047
5048//*************************************************************************************************
5060template< typename MT // Type of the dense matrix
5061 , typename... CRAs > // Compile time row arguments
5062template< typename MT2 // Data type of the foreign dense row selection
5063 , bool SO2 // Storage order of the foreign dense row selection
5064 , bool SF2 // Symmetry flag of the foreign dense row selection
5065 , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
5066inline bool
5067 Rows<MT,false,true,false,CRAs...>::isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
5068{
5069 return matrix_.isAliased( &alias->matrix_ );
5070}
5072//*************************************************************************************************
5073
5074
5075//*************************************************************************************************
5085template< typename MT // Type of the dense matrix
5086 , typename... CRAs > // Compile time row arguments
5087inline bool Rows<MT,false,true,false,CRAs...>::isAligned() const noexcept
5088{
5089 return false;
5090}
5092//*************************************************************************************************
5093
5094
5095//*************************************************************************************************
5106template< typename MT // Type of the dense matrix
5107 , typename... CRAs > // Compile time row arguments
5108inline bool Rows<MT,false,true,false,CRAs...>::canSMPAssign() const noexcept
5109{
5110 return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
5111}
5113//*************************************************************************************************
5114
5115
5116//*************************************************************************************************
5128template< typename MT // Type of the dense matrix
5129 , typename... CRAs > // Compile time row arguments
5130template< typename MT2 > // Type of the right-hand side dense matrix
5131inline void Rows<MT,false,true,false,CRAs...>::assign( const DenseMatrix<MT2,false>& rhs )
5132{
5135
5136 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5137 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5138
5139 const size_t jpos( prevMultiple( columns(), 2UL ) );
5140 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
5141
5142 for( size_t i=0UL; i<rows(); ++i ) {
5143 const size_t index( idx(i) );
5144 for( size_t j=0UL; j<jpos; j+=2UL ) {
5145 matrix_(index,j ) = (*rhs)(i,j );
5146 matrix_(index,j+1UL) = (*rhs)(i,j+1UL);
5147 }
5148 if( jpos < columns() ) {
5149 matrix_(index,jpos) = (*rhs)(i,jpos);
5150 }
5151 }
5152}
5154//*************************************************************************************************
5155
5156
5157//*************************************************************************************************
5169template< typename MT // Type of the dense matrix
5170 , typename... CRAs > // Compile time row arguments
5171template< typename MT2 > // Type of the right-hand side dense matrix
5172inline void Rows<MT,false,true,false,CRAs...>::assign( const DenseMatrix<MT2,true>& rhs )
5173{
5176
5178
5179 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5180 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5181
5182 constexpr size_t block( BLOCK_SIZE );
5183
5184 if( rows() < block && columns() < block )
5185 {
5186 const size_t jpos( prevMultiple( (*rhs).columns(), 2UL ) );
5187 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).columns(), "Invalid end calculation" );
5188
5189 for( size_t i=0UL; i<rows(); ++i ) {
5190 const size_t index( idx(i) );
5191 for( size_t j=0UL; j<jpos; j+=2UL ) {
5192 matrix_(index,j ) = (*rhs)(i,j );
5193 matrix_(index,j+1UL) = (*rhs)(i,j+1UL);
5194 }
5195 if( jpos < (*rhs).columns() )
5196 matrix_(index,jpos) = (*rhs)(i,jpos);
5197 }
5198 }
5199 else
5200 {
5201 for( size_t ii=0UL; ii<rows(); ii+=block ) {
5202 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5203 for( size_t jj=0UL; jj<columns(); jj+=block ) {
5204 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5205 for( size_t i=ii; i<iend; ++i ) {
5206 const size_t index( idx(i) );
5207 for( size_t j=jj; j<jend; ++j ) {
5208 matrix_(index,j) = (*rhs)(i,j);
5209 }
5210 }
5211 }
5212 }
5213 }
5214}
5216//*************************************************************************************************
5217
5218
5219//*************************************************************************************************
5231template< typename MT // Type of the dense matrix
5232 , typename... CRAs > // Compile time row arguments
5233template< typename MT2 > // Type of the right-hand side sparse matrix
5234inline void Rows<MT,false,true,false,CRAs...>::assign( const SparseMatrix<MT2,false>& rhs )
5235{
5238
5239 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5240 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5241
5242 for( size_t i=0UL; i<rows(); ++i ) {
5243 const size_t index( idx(i) );
5244 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5245 matrix_(index,element->index()) = element->value();
5246 }
5247}
5249//*************************************************************************************************
5250
5251
5252//*************************************************************************************************
5264template< typename MT // Type of the dense matrix
5265 , typename... CRAs > // Compile time row arguments
5266template< typename MT2 > // Type of the right-hand side sparse matrix
5267inline void Rows<MT,false,true,false,CRAs...>::assign( const SparseMatrix<MT2,true>& rhs )
5268{
5271
5273
5274 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5275 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5276
5277 for( size_t j=0UL; j<columns(); ++j ) {
5278 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
5279 matrix_(idx(element->index()),j) = element->value();
5280 }
5281}
5283//*************************************************************************************************
5284
5285
5286//*************************************************************************************************
5298template< typename MT // Type of the dense matrix
5299 , typename... CRAs > // Compile time row arguments
5300template< typename MT2 > // Type of the right-hand side dense matrix
5301inline void Rows<MT,false,true,false,CRAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
5302{
5305
5306 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5307 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5308
5309 const size_t jpos( prevMultiple( columns(), 2UL ) );
5310 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
5311
5312 for( size_t i=0UL; i<rows(); ++i )
5313 {
5314 const size_t index( idx(i) );
5315 if( IsDiagonal_v<MT2> ) {
5316 matrix_(index,i) += (*rhs)(i,i);
5317 }
5318 else {
5319 for( size_t j=0UL; j<jpos; j+=2UL ) {
5320 matrix_(index,j ) += (*rhs)(i,j );
5321 matrix_(index,j+1UL) += (*rhs)(i,j+1UL);
5322 }
5323 if( jpos < columns() ) {
5324 matrix_(index,jpos) += (*rhs)(i,jpos);
5325 }
5326 }
5327 }
5328}
5330//*************************************************************************************************
5331
5332
5333//*************************************************************************************************
5345template< typename MT // Type of the dense matrix
5346 , typename... CRAs > // Compile time row arguments
5347template< typename MT2 > // Type of the right-hand side dense matrix
5348inline void Rows<MT,false,true,false,CRAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
5349{
5352
5354
5355 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5356 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5357
5358 constexpr size_t block( BLOCK_SIZE );
5359
5360 if( rows() < block && columns() < block )
5361 {
5362 const size_t jpos( prevMultiple( (*rhs).columns(), 2UL ) );
5363 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).columns(), "Invalid end calculation" );
5364
5365 for( size_t i=0UL; i<rows(); ++i ) {
5366 const size_t index( idx(i) );
5367 for( size_t j=0UL; j<jpos; j+=2UL ) {
5368 matrix_(index,j ) += (*rhs)(i,j );
5369 matrix_(index,j+1UL) += (*rhs)(i,j+1UL);
5370 }
5371 if( jpos < (*rhs).columns() )
5372 matrix_(index,jpos) += (*rhs)(i,jpos);
5373 }
5374 }
5375 else
5376 {
5377 for( size_t ii=0UL; ii<rows(); ii+=block ) {
5378 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5379 for( size_t jj=0UL; jj<columns(); jj+=block ) {
5380 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5381 for( size_t i=ii; i<iend; ++i ) {
5382 const size_t index( idx(i) );
5383 for( size_t j=jj; j<jend; ++j ) {
5384 matrix_(index,j) += (*rhs)(i,j);
5385 }
5386 }
5387 }
5388 }
5389 }
5390}
5392//*************************************************************************************************
5393
5394
5395//*************************************************************************************************
5407template< typename MT // Type of the dense matrix
5408 , typename... CRAs > // Compile time row arguments
5409template< typename MT2 > // Type of the right-hand side sparse matrix
5410inline void Rows<MT,false,true,false,CRAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
5411{
5414
5415 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5416 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5417
5418 for( size_t i=0UL; i<rows(); ++i ) {
5419 const size_t index( idx(i) );
5420 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5421 matrix_(index,element->index()) += element->value();
5422 }
5423}
5425//*************************************************************************************************
5426
5427
5428//*************************************************************************************************
5440template< typename MT // Type of the dense matrix
5441 , typename... CRAs > // Compile time row arguments
5442template< typename MT2 > // Type of the right-hand side sparse matrix
5443inline void Rows<MT,false,true,false,CRAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
5444{
5447
5449
5450 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5451 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5452
5453 for( size_t j=0UL; j<columns(); ++j ) {
5454 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
5455 matrix_(idx(element->index()),j) += element->value();
5456 }
5457}
5459//*************************************************************************************************
5460
5461
5462//*************************************************************************************************
5474template< typename MT // Type of the dense matrix
5475 , typename... CRAs > // Compile time row arguments
5476template< typename MT2 > // Type of the right-hand side dense matrix
5477inline void Rows<MT,false,true,false,CRAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
5478{
5481
5482 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5483 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5484
5485 const size_t jpos( prevMultiple( columns(), 2UL ) );
5486 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
5487
5488 for( size_t i=0UL; i<rows(); ++i )
5489 {
5490 const size_t index( idx(i) );
5491
5492 if( IsDiagonal_v<MT2> ) {
5493 matrix_(index,i) -= (*rhs)(i,i);
5494 }
5495 else {
5496 for( size_t j=0UL; j<jpos; j+=2UL ) {
5497 matrix_(index,j ) -= (*rhs)(i,j );
5498 matrix_(index,j+1UL) -= (*rhs)(i,j+1UL);
5499 }
5500 if( jpos < columns() ) {
5501 matrix_(index,jpos) -= (*rhs)(i,jpos);
5502 }
5503 }
5504 }
5505}
5507//*************************************************************************************************
5508
5509
5510//*************************************************************************************************
5522template< typename MT // Type of the dense matrix
5523 , typename... CRAs > // Compile time row arguments
5524template< typename MT2 > // Type of the right-hand side dense matrix
5525inline void Rows<MT,false,true,false,CRAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
5526{
5529
5531
5532 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5533 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5534
5535 constexpr size_t block( BLOCK_SIZE );
5536
5537 if( rows() < block && columns() < block )
5538 {
5539 const size_t jpos( prevMultiple( (*rhs).columns(), 2UL ) );
5540 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).columns(), "Invalid end calculation" );
5541
5542 for( size_t i=0UL; i<rows(); ++i ) {
5543 const size_t index( idx(i) );
5544 for( size_t j=0UL; j<jpos; j+=2UL ) {
5545 matrix_(index,j ) -= (*rhs)(i,j );
5546 matrix_(index,j+1UL) -= (*rhs)(i,j+1UL);
5547 }
5548 if( jpos < (*rhs).columns() )
5549 matrix_(index,jpos) -= (*rhs)(i,jpos);
5550 }
5551 }
5552 else
5553 {
5554 for( size_t ii=0UL; ii<rows(); ii+=block ) {
5555 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5556 for( size_t jj=0UL; jj<columns(); jj+=block ) {
5557 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5558 for( size_t i=ii; i<iend; ++i ) {
5559 const size_t index( idx(i) );
5560 for( size_t j=jj; j<jend; ++j ) {
5561 matrix_(index,j) -= (*rhs)(i,j);
5562 }
5563 }
5564 }
5565 }
5566 }
5567}
5569//*************************************************************************************************
5570
5571
5572//*************************************************************************************************
5584template< typename MT // Type of the dense matrix
5585 , typename... CRAs > // Compile time row arguments
5586template< typename MT2 > // Type of the right-hand side sparse matrix
5587inline void Rows<MT,false,true,false,CRAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
5588{
5591
5592 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5593 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5594
5595 for( size_t i=0UL; i<rows(); ++i ) {
5596 const size_t index( idx(i) );
5597 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5598 matrix_(index,element->index()) -= element->value();
5599 }
5600}
5602//*************************************************************************************************
5603
5604
5605//*************************************************************************************************
5617template< typename MT // Type of the dense matrix
5618 , typename... CRAs > // Compile time row arguments
5619template< typename MT2 > // Type of the right-hand side sparse matrix
5620inline void Rows<MT,false,true,false,CRAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
5621{
5624
5626
5627 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5628 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5629
5630 for( size_t j=0UL; j<columns(); ++j ) {
5631 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
5632 matrix_(idx(element->index()),j) -= element->value();
5633 }
5634}
5636//*************************************************************************************************
5637
5638
5639//*************************************************************************************************
5651template< typename MT // Type of the dense matrix
5652 , typename... CRAs > // Compile time row arguments
5653template< typename MT2 > // Type of the right-hand side dense matrix
5654inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
5655{
5658
5659 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5660 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5661
5662 const size_t jpos( prevMultiple( columns(), 2UL ) );
5663 BLAZE_INTERNAL_ASSERT( jpos <= columns(), "Invalid end calculation" );
5664
5665 for( size_t i=0UL; i<rows(); ++i ) {
5666 const size_t index( idx(i) );
5667 for( size_t j=0UL; j<jpos; j+=2UL ) {
5668 matrix_(index,j ) *= (*rhs)(i,j );
5669 matrix_(index,j+1UL) *= (*rhs)(i,j+1UL);
5670 }
5671 if( jpos < columns() ) {
5672 matrix_(index,jpos) *= (*rhs)(i,jpos);
5673 }
5674 }
5675}
5677//*************************************************************************************************
5678
5679
5680//*************************************************************************************************
5692template< typename MT // Type of the dense matrix
5693 , typename... CRAs > // Compile time row arguments
5694template< typename MT2 > // Type of the right-hand side dense matrix
5695inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
5696{
5699
5701
5702 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5703 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5704
5705 constexpr size_t block( BLOCK_SIZE );
5706
5707 if( rows() < block && columns() < block )
5708 {
5709 const size_t jpos( prevMultiple( (*rhs).columns(), 2UL ) );
5710 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).columns(), "Invalid end calculation" );
5711
5712 for( size_t i=0UL; i<rows(); ++i ) {
5713 const size_t index( idx(i) );
5714 for( size_t j=0UL; j<jpos; j+=2UL ) {
5715 matrix_(index,j ) *= (*rhs)(i,j );
5716 matrix_(index,j+1UL) *= (*rhs)(i,j+1UL);
5717 }
5718 if( jpos < (*rhs).columns() )
5719 matrix_(index,jpos) *= (*rhs)(i,jpos);
5720 }
5721 }
5722 else
5723 {
5724 for( size_t ii=0UL; ii<rows(); ii+=block ) {
5725 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5726 for( size_t jj=0UL; jj<columns(); jj+=block ) {
5727 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5728 for( size_t i=ii; i<iend; ++i ) {
5729 const size_t index( idx(i) );
5730 for( size_t j=jj; j<jend; ++j ) {
5731 matrix_(index,j) *= (*rhs)(i,j);
5732 }
5733 }
5734 }
5735 }
5736 }
5737}
5739//*************************************************************************************************
5740
5741
5742//*************************************************************************************************
5754template< typename MT // Type of the dense matrix
5755 , typename... CRAs > // Compile time row arguments
5756template< typename MT2 > // Type of the right-hand side sparse matrix
5757inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
5758{
5759 using blaze::reset;
5760
5763
5764 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5765 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5766
5767 for( size_t i=0UL; i<rows(); ++i )
5768 {
5769 const size_t index( idx(i) );
5770 size_t j( 0UL );
5771
5772 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
5773 for( ; j<element->index(); ++j )
5774 reset( matrix_(index,j) );
5775 matrix_(index,j) *= element->value();
5776 ++j;
5777 }
5778
5779 for( ; j<columns(); ++j ) {
5780 reset( matrix_(index,j) );
5781 }
5782 }
5783}
5785//*************************************************************************************************
5786
5787
5788//*************************************************************************************************
5800template< typename MT // Type of the dense matrix
5801 , typename... CRAs > // Compile time row arguments
5802template< typename MT2 > // Type of the right-hand side sparse matrix
5803inline void Rows<MT,false,true,false,CRAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
5804{
5805 using blaze::reset;
5806
5809
5811
5812 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5813 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5814
5815 for( size_t j=0UL; j<columns(); ++j )
5816 {
5817 size_t i( 0UL );
5818
5819 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
5820 for( ; i<element->index(); ++i )
5821 reset( matrix_(idx(i),j) );
5822 matrix_(idx(i),j) *= element->value();
5823 ++i;
5824 }
5825
5826 for( ; i<rows(); ++i ) {
5827 reset( matrix_(idx(i),j) );
5828 }
5829 }
5830}
5832//*************************************************************************************************
5833
5834
5835
5836
5837
5838
5839
5840
5841//=================================================================================================
5842//
5843// CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR DENSE MATRICES
5844//
5845//=================================================================================================
5846
5847//*************************************************************************************************
5855template< typename MT // Type of the dense matrix
5856 , typename... CRAs > // Compile time row arguments
5857class Rows<MT,false,true,true,CRAs...>
5858 : public View< DenseMatrix< Rows<MT,false,true,true,CRAs...>, false > >
5859 , private RowsData<CRAs...>
5860{
5861 private:
5862 //**Type definitions****************************************************************************
5863 using DataType = RowsData<CRAs...>;
5864 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
5865 //**********************************************************************************************
5866
5867 //**Compile time flags**************************************************************************
5868 using DataType::N;
5869 //**********************************************************************************************
5870
5871 public:
5872 //**Type definitions****************************************************************************
5874 using This = Rows<MT,false,true,true,CRAs...>;
5875
5877 using BaseType = View< DenseMatrix<This,false> >;
5878
5879 using ViewedType = MT;
5880 using ResultType = RowsTrait_t<MT,N>;
5881 using OppositeType = OppositeType_t<ResultType>;
5882 using TransposeType = TransposeType_t<ResultType>;
5883 using ElementType = ElementType_t<MT>;
5884 using SIMDType = SIMDTrait_t<ElementType>;
5885 using ReturnType = ReturnType_t<MT>;
5886 using CompositeType = const Rows&;
5887
5889 using ConstReference = ConstReference_t<MT>;
5890
5892 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
5893
5895 using ConstPointer = ConstPointer_t<MT>;
5896
5898 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
5899
5901 using ConstIterator = ConstIterator_t<MT>;
5902
5904 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
5905 //**********************************************************************************************
5906
5907 //**Compilation flags***************************************************************************
5909 static constexpr bool simdEnabled = MT::simdEnabled;
5910
5912 static constexpr bool smpAssignable = MT::smpAssignable;
5913
5915 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
5916 //**********************************************************************************************
5917
5918 //**Constructors********************************************************************************
5921 template< typename... RRAs >
5922 explicit inline Rows( MT& matrix, RRAs... args );
5923
5924 Rows( const Rows& ) = default;
5925 Rows( Rows&& ) = default;
5927 //**********************************************************************************************
5928
5929 //**Destructor**********************************************************************************
5932 ~Rows() = default;
5934 //**********************************************************************************************
5935
5936 //**Data access functions***********************************************************************
5939 inline Reference operator()( size_t i, size_t j );
5940 inline ConstReference operator()( size_t i, size_t j ) const;
5941 inline Reference at( size_t i, size_t j );
5942 inline ConstReference at( size_t i, size_t j ) const;
5943 inline Pointer data () noexcept;
5944 inline ConstPointer data () const noexcept;
5945 inline Pointer data ( size_t i ) noexcept;
5946 inline ConstPointer data ( size_t i ) const noexcept;
5947 inline Iterator begin ( size_t i );
5948 inline ConstIterator begin ( size_t i ) const;
5949 inline ConstIterator cbegin( size_t i ) const;
5950 inline Iterator end ( size_t i );
5951 inline ConstIterator end ( size_t i ) const;
5952 inline ConstIterator cend ( size_t i ) const;
5954 //**********************************************************************************************
5955
5956 //**Assignment operators************************************************************************
5959 inline Rows& operator=( const ElementType& rhs );
5960
5961 Rows& operator=( const Rows& ) = delete;
5963 //**********************************************************************************************
5964
5965 //**Utility functions***************************************************************************
5968 using DataType::idx;
5969 using DataType::idces;
5970 using DataType::rows;
5971
5972 inline MT& operand() noexcept;
5973 inline const MT& operand() const noexcept;
5974
5975 inline size_t columns() const noexcept;
5976 inline size_t spacing() const noexcept;
5977 inline size_t capacity() const noexcept;
5978 inline size_t capacity( size_t i ) const noexcept;
5979 inline size_t nonZeros() const;
5980 inline size_t nonZeros( size_t i ) const;
5981 inline void reset();
5982 inline void reset( size_t i );
5984 //**********************************************************************************************
5985
5986 //**Expression template evaluation functions****************************************************
5989 template< typename Other >
5990 inline bool canAlias( const Other* alias ) const noexcept;
5991
5992 template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
5993 inline bool canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
5994
5995 template< typename Other >
5996 inline bool isAliased( const Other* alias ) const noexcept;
5997
5998 template< typename MT2, bool SO2, bool SF2, typename... CRAs2 >
5999 inline bool isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
6000
6001 inline bool isAligned () const noexcept;
6002 inline bool canSMPAssign() const noexcept;
6003
6004 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
6005 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
6006 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
6008 //**********************************************************************************************
6009
6010 private:
6011 //**Member variables****************************************************************************
6014 Operand matrix_;
6016 //**********************************************************************************************
6017
6018 //**Friend declarations*************************************************************************
6019 template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CRAs2 > friend class Rows;
6020 //**********************************************************************************************
6021
6022 //**Compile time checks*************************************************************************
6032 //**********************************************************************************************
6033};
6035//*************************************************************************************************
6036
6037
6038
6039
6040//=================================================================================================
6041//
6042// CONSTRUCTORS
6043//
6044//=================================================================================================
6045
6046//*************************************************************************************************
6059template< typename MT // Type of the dense matrix
6060 , typename... CRAs > // Compile time row arguments
6061template< typename... RRAs > // Runtime row arguments
6062inline Rows<MT,false,true,true,CRAs...>::Rows( MT& matrix, RRAs... args )
6063 : DataType( args... ) // Base class initialization
6064 , matrix_ ( matrix ) // The matrix containing the rows
6065{
6066 if( isChecked( args... ) ) {
6067 for( size_t i=0UL; i<rows(); ++i ) {
6068 if( matrix_.rows() <= idx(i) ) {
6069 BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
6070 }
6071 }
6072 }
6073}
6075//*************************************************************************************************
6076
6077
6078
6079
6080//=================================================================================================
6081//
6082// DATA ACCESS FUNCTIONS
6083//
6084//=================================================================================================
6085
6086//*************************************************************************************************
6097template< typename MT // Type of the dense matrix
6098 , typename... CRAs > // Compile time row arguments
6099inline typename Rows<MT,false,true,true,CRAs...>::Reference
6100 Rows<MT,false,true,true,CRAs...>::operator()( size_t i, size_t j )
6101{
6102 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6103 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6104
6105 return matrix_(j,idx(i));
6106}
6108//*************************************************************************************************
6109
6110
6111//*************************************************************************************************
6122template< typename MT // Type of the dense matrix
6123 , typename... CRAs > // Compile time row arguments
6124inline typename Rows<MT,false,true,true,CRAs...>::ConstReference
6125 Rows<MT,false,true,true,CRAs...>::operator()( size_t i, size_t j ) const
6126{
6127 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6128 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6129
6130 return const_cast<const MT&>( matrix_ )(j,idx(i));
6131}
6133//*************************************************************************************************
6134
6135
6136//*************************************************************************************************
6148template< typename MT // Type of the dense matrix
6149 , typename... CRAs > // Compile time row arguments
6150inline typename Rows<MT,false,true,true,CRAs...>::Reference
6151 Rows<MT,false,true,true,CRAs...>::at( size_t i, size_t j )
6152{
6153 if( i >= rows() ) {
6154 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6155 }
6156 if( j >= columns() ) {
6157 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6158 }
6159 return (*this)(i,j);
6160}
6162//*************************************************************************************************
6163
6164
6165//*************************************************************************************************
6177template< typename MT // Type of the dense matrix
6178 , typename... CRAs > // Compile time row arguments
6179inline typename Rows<MT,false,true,true,CRAs...>::ConstReference
6180 Rows<MT,false,true,true,CRAs...>::at( size_t i, size_t j ) const
6181{
6182 if( i >= rows() ) {
6183 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6184 }
6185 if( j >= columns() ) {
6186 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6187 }
6188 return (*this)(i,j);
6189}
6191//*************************************************************************************************
6192
6193
6194//*************************************************************************************************
6204template< typename MT // Type of the dense matrix
6205 , typename... CRAs > // Compile time row arguments
6206inline typename Rows<MT,false,true,true,CRAs...>::Pointer
6208{
6209 return matrix_.data( idx(0UL) );
6210}
6212//*************************************************************************************************
6213
6214
6215//*************************************************************************************************
6225template< typename MT // Type of the dense matrix
6226 , typename... CRAs > // Compile time row arguments
6227inline typename Rows<MT,false,true,true,CRAs...>::ConstPointer
6229{
6230 return matrix_.data( idx(0UL) );
6231}
6233//*************************************************************************************************
6234
6235
6236//*************************************************************************************************
6245template< typename MT // Type of the dense matrix
6246 , typename... CRAs > // Compile time row arguments
6247inline typename Rows<MT,false,true,true,CRAs...>::Pointer
6248 Rows<MT,false,true,true,CRAs...>::data( size_t i ) noexcept
6249{
6250 return matrix_.data( idx(i) );
6251}
6253//*************************************************************************************************
6254
6255
6256//*************************************************************************************************
6265template< typename MT // Type of the dense matrix
6266 , typename... CRAs > // Compile time row arguments
6267inline typename Rows<MT,false,true,true,CRAs...>::ConstPointer
6268 Rows<MT,false,true,true,CRAs...>::data( size_t i ) const noexcept
6269{
6270 return matrix_.data( idx(i) );
6271}
6273//*************************************************************************************************
6274
6275
6276//*************************************************************************************************
6285template< typename MT // Type of the dense matrix
6286 , typename... CRAs > // Compile time row arguments
6287inline typename Rows<MT,false,true,true,CRAs...>::Iterator
6289{
6290 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6291 return matrix_.begin( idx(i) );
6292}
6294//*************************************************************************************************
6295
6296
6297//*************************************************************************************************
6306template< typename MT // Type of the dense matrix
6307 , typename... CRAs > // Compile time row arguments
6308inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6310{
6311 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6312 return matrix_.cbegin( idx(i) );
6313}
6315//*************************************************************************************************
6316
6317
6318//*************************************************************************************************
6327template< typename MT // Type of the dense matrix
6328 , typename... CRAs > // Compile time row arguments
6329inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6331{
6332 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6333 return matrix_.cbegin( idx(i) );
6334}
6336//*************************************************************************************************
6337
6338
6339//*************************************************************************************************
6348template< typename MT // Type of the dense matrix
6349 , typename... CRAs > // Compile time row arguments
6350inline typename Rows<MT,false,true,true,CRAs...>::Iterator
6352{
6353 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6354 return matrix_.end( idx(i) );
6355}
6357//*************************************************************************************************
6358
6359
6360//*************************************************************************************************
6369template< typename MT // Type of the dense matrix
6370 , typename... CRAs > // Compile time row arguments
6371inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6373{
6374 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6375 return matrix_.cend( idx(i) );
6376}
6378//*************************************************************************************************
6379
6380
6381//*************************************************************************************************
6390template< typename MT // Type of the dense matrix
6391 , typename... CRAs > // Compile time row arguments
6392inline typename Rows<MT,false,true,true,CRAs...>::ConstIterator
6394{
6395 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6396 return matrix_.cend( idx(i) );
6397}
6399//*************************************************************************************************
6400
6401
6402
6403
6404//=================================================================================================
6405//
6406// ASSIGNMENT OPERATORS
6407//
6408//=================================================================================================
6409
6410//*************************************************************************************************
6421template< typename MT // Type of the dense matrix
6422 , typename... CRAs > // Compile time row arguments
6423inline Rows<MT,false,true,true,CRAs...>&
6424 Rows<MT,false,true,true,CRAs...>::operator=( const ElementType& rhs )
6425{
6426 for( size_t i=0UL; i<rows(); ++i ) {
6427 column( matrix_, idx(i), unchecked ) = rhs;
6428 }
6429
6430 return *this;
6431}
6433//*************************************************************************************************
6434
6435
6436
6437
6438//=================================================================================================
6439//
6440// UTILITY FUNCTIONS
6441//
6442//=================================================================================================
6443
6444//*************************************************************************************************
6450template< typename MT // Type of the dense matrix
6451 , typename... CRAs > // Compile time row arguments
6452inline MT& Rows<MT,false,true,true,CRAs...>::operand() noexcept
6453{
6454 return matrix_;
6455}
6457//*************************************************************************************************
6458
6459
6460//*************************************************************************************************
6466template< typename MT // Type of the dense matrix
6467 , typename... CRAs > // Compile time row arguments
6468inline const MT& Rows<MT,false,true,true,CRAs...>::operand() const noexcept
6469{
6470 return matrix_;
6471}
6473//*************************************************************************************************
6474
6475
6476//*************************************************************************************************
6482template< typename MT // Type of the dense matrix
6483 , typename... CRAs > // Compile time row arguments
6484inline size_t Rows<MT,false,true,true,CRAs...>::columns() const noexcept
6485{
6486 return matrix_.columns();
6487}
6489//*************************************************************************************************
6490
6491
6492//*************************************************************************************************
6501template< typename MT // Type of the dense matrix
6502 , typename... CRAs > // Compile time row arguments
6503inline size_t Rows<MT,false,true,true,CRAs...>::spacing() const noexcept
6504{
6505 return matrix_.spacing();
6506}
6508//*************************************************************************************************
6509
6510
6511//*************************************************************************************************
6517template< typename MT // Type of the dense matrix
6518 , typename... CRAs > // Compile time row arguments
6519inline size_t Rows<MT,false,true,true,CRAs...>::capacity() const noexcept
6520{
6521 return rows() * columns();
6522}
6524//*************************************************************************************************
6525
6526
6527//*************************************************************************************************
6536template< typename MT // Type of the dense matrix
6537 , typename... CRAs > // Compile time row arguments
6538inline size_t Rows<MT,false,true,true,CRAs...>::capacity( size_t i ) const noexcept
6539{
6540 MAYBE_UNUSED( i );
6541
6542 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6543
6544 return columns();
6545}
6547//*************************************************************************************************
6548
6549
6550//*************************************************************************************************
6556template< typename MT // Type of the dense matrix
6557 , typename... CRAs > // Compile time row arguments
6559{
6560 size_t nonzeros( 0UL );
6561
6562 for( size_t i=0UL; i<rows(); ++i ) {
6563 nonzeros += matrix_.nonZeros( idx(i) );
6564 }
6565
6566 return nonzeros;
6567}
6569//*************************************************************************************************
6570
6571
6572//*************************************************************************************************
6581template< typename MT // Type of the dense matrix
6582 , typename... CRAs > // Compile time row arguments
6583inline size_t Rows<MT,false,true,true,CRAs...>::nonZeros( size_t i ) const
6584{
6585 BLAZE_USER_ASSERT( i < rows(), "Invalid row access index" );
6586
6587 return matrix_.nonZeros( idx(i) );
6588}
6590//*************************************************************************************************
6591
6592
6593//*************************************************************************************************
6599template< typename MT // Type of the dense matrix
6600 , typename... CRAs > // Compile time row arguments
6602{
6603 for( size_t i=0UL; i<rows(); ++i ) {
6604 matrix_.reset( idx(i) );
6605 }
6606}
6608//*************************************************************************************************
6609
6610
6611//*************************************************************************************************
6620template< typename MT // Type of the dense matrix
6621 , typename... CRAs > // Compile time row arguments
6622inline void Rows<MT,false,true,true,CRAs...>::reset( size_t i )
6623{
6624 matrix_.reset( idx(i) );
6625}
6627//*************************************************************************************************
6628
6629
6630
6631
6632//=================================================================================================
6633//
6634// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6635//
6636//=================================================================================================
6637
6638//*************************************************************************************************
6649template< typename MT // Type of the dense matrix
6650 , typename... CRAs > // Compile time row arguments
6651template< typename Other > // Data type of the foreign expression
6652inline bool Rows<MT,false,true,true,CRAs...>::canAlias( const Other* alias ) const noexcept
6653{
6654 return matrix_.isAliased( &unview( *alias ) );
6655}
6657//*************************************************************************************************
6658
6659
6660//*************************************************************************************************
6672template< typename MT // Type of the dense matrix
6673 , typename... CRAs > // Compile time row arguments
6674template< typename MT2 // Data type of the foreign dense row selection
6675 , bool SO2 // Storage order of the foreign dense row selection
6676 , bool SF2 // Symmetry flag of the foreign dense row selection
6677 , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
6678inline bool
6679 Rows<MT,false,true,true,CRAs...>::canAlias( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
6680{
6681 return matrix_.isAliased( &alias->matrix_ );
6682}
6684//*************************************************************************************************
6685
6686
6687//*************************************************************************************************
6698template< typename MT // Type of the dense matrix
6699 , typename... CRAs > // Compile time row arguments
6700template< typename Other > // Data type of the foreign expression
6701inline bool Rows<MT,false,true,true,CRAs...>::isAliased( const Other* alias ) const noexcept
6702{
6703 return matrix_.isAliased( &unview( *alias ) );
6704}
6706//*************************************************************************************************
6707
6708
6709//*************************************************************************************************
6721template< typename MT // Type of the dense matrix
6722 , typename... CRAs > // Compile time row arguments
6723template< typename MT2 // Data type of the foreign dense row selection
6724 , bool SO2 // Storage order of the foreign dense row selection
6725 , bool SF2 // Symmetry flag of the foreign dense row selection
6726 , typename... CRAs2 > // Compile time row arguments of the foreign dense row selection
6727inline bool
6728 Rows<MT,false,true,true,CRAs...>::isAliased( const Rows<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
6729{
6730 return matrix_.isAliased( &alias->matrix_ );
6731}
6733//*************************************************************************************************
6734
6735
6736//*************************************************************************************************
6746template< typename MT // Type of the dense matrix
6747 , typename... CRAs > // Compile time row arguments
6748inline bool Rows<MT,false,true,true,CRAs...>::isAligned() const noexcept
6749{
6750 return matrix_.isAligned();
6751}
6753//*************************************************************************************************
6754
6755
6756//*************************************************************************************************
6767template< typename MT // Type of the dense matrix
6768 , typename... CRAs > // Compile time row arguments
6769inline bool Rows<MT,false,true,true,CRAs...>::canSMPAssign() const noexcept
6770{
6771 return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
6772}
6774//*************************************************************************************************
6775
6776
6777//*************************************************************************************************
6792template< typename MT // Type of the dense matrix
6793 , typename... CRAs > // Compile time row arguments
6794BLAZE_ALWAYS_INLINE typename Rows<MT,false,true,true,CRAs...>::SIMDType
6795 Rows<MT,false,true,true,CRAs...>::load( size_t i, size_t j ) const noexcept
6796{
6797 return matrix_.load( j, idx(i) );
6798}
6800//*************************************************************************************************
6801
6802
6803//*************************************************************************************************
6818template< typename MT // Type of the dense matrix
6819 , typename... CRAs > // Compile time row arguments
6820BLAZE_ALWAYS_INLINE typename Rows<MT,false,true,true,CRAs...>::SIMDType
6821 Rows<MT,false,true,true,CRAs...>::loada( size_t i, size_t j ) const noexcept
6822{
6823 return matrix_.loada( j, idx(i) );
6824}
6826//*************************************************************************************************
6827
6828
6829//*************************************************************************************************
6844template< typename MT // Type of the dense matrix
6845 , typename... CRAs > // Compile time row arguments
6846BLAZE_ALWAYS_INLINE typename Rows<MT,false,true,true,CRAs...>::SIMDType
6847 Rows<MT,false,true,true,CRAs...>::loadu( size_t i, size_t j ) const noexcept
6848{
6849 return matrix_.loadu( j, idx(i) );
6850}
6852//*************************************************************************************************
6853
6854} // namespace blaze
6855
6856#endif
Header file for the addition trait.
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
Header file for kernel specific block sizes.
Header file for the blaze::checked and blaze::unchecked instances.
Constraints on the storage order of matrix types.
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:751
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:719
Header file for the EnableIf class template.
Header file for the HasMutableDataAccess type trait.
Header file for the HasSIMDAdd type trait.
Header file for the HasSIMDMult type trait.
Header file for the HasSIMDSub type trait.
Constraint on the data type.
Header file for the If class template.
Header file for the IsConst type trait.
Header file for the IsDiagonal type trait.
Header file for the IsExpression type trait class.
Header file for the IsLower type trait.
Header file for the IsReference type trait.
Header file for the IsRestricted type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseMatrix type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsUpper type trait.
Header file for the MAYBE_UNUSED function template.
Constraint on the data type.
Header file for the prevMultiple shim.
Constraint on the data type.
Constraints on the storage order of matrix types.
Header file for the implementation of the RowsData class template.
Header file for the rows trait.
Header file for all SIMD functionality.
Header file for the Schur product trait.
Header file for the subtraction trait.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Initializer list type of the Blaze library.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the implementation of a vector representation of an initializer list.
Header file for the DenseMatrix base class.
Header file for the View base class.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:137
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.
Definition: Vectorizable.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1501
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:182
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:386
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:265
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:9640
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:448
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
bool isDefault(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the given diagonal matrix is in default state.
Definition: DiagonalMatrix.h:169
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Hermitian.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.
Definition: TransExpr.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.
Definition: Submatrix.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:60
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: DenseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_ROWS_TYPE(T)
Constraint on the data type.
Definition: Rows.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: UniTriangular.h:81
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.
Definition: HasSIMDSub.h:187
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.
Definition: IsSIMDCombinable.h:137
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.
Definition: IsDiagonal.h:148
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.
Definition: HasSIMDAdd.h:187
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.
Definition: HasSIMDMult.h:188
BLAZE_ALWAYS_INLINE constexpr auto prevMultiple(T1 value, T2 factor) noexcept
Rounds down an integral value to the previous multiple of a given factor.
Definition: PrevMultiple.h:68
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 > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:332
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
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
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:408
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:628
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:730
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:562
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:692
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
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:584
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:1221
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:1195
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:137
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
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
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
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
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
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
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
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
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
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
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.
Definition: Exception.h:187
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
constexpr bool isChecked(const Ts &... args)
Extracting blaze::Check arguments from a given list of arguments.
Definition: Check.h:225
constexpr Unchecked unchecked
Global Unchecked instance.
Definition: Check.h:146
Header file for the exception macros of the math module.
Header file for the extended initializer_list functionality.
Header file for the reset shim.
Header file for the cache size of the target architecture.
System settings for the inline keywords.
System settings for performance optimizations.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for the RequiresEvaluation type trait.
Header file for basic type definitions.
Header file for the implementation of the Rows base template.