Blaze 3.9
Dense.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_VIEWS_ROW_DENSE_H_
36#define _BLAZE_MATH_VIEWS_ROW_DENSE_H_
37
38
39//*************************************************************************************************
40// Includes
41//*************************************************************************************************
42
43#include <algorithm>
44#include <iterator>
45#include <blaze/math/Aliases.h>
66#include <blaze/math/SIMD.h>
90#include <blaze/system/Inline.h>
93#include <blaze/util/Assert.h>
97#include <blaze/util/EnableIf.h>
98#include <blaze/util/mpl/If.h>
99#include <blaze/util/Types.h>
102
103
104namespace blaze {
105
106//=================================================================================================
107//
108// CLASS TEMPLATE SPECIALIZATION FOR ROW-MAJOR DENSE MATRICES
109//
110//=================================================================================================
111
112//*************************************************************************************************
120template< typename MT // Type of the dense matrix
121 , bool SF // Symmetry flag
122 , size_t... CRAs > // Compile time row arguments
123class Row<MT,true,true,SF,CRAs...>
124 : public View< DenseVector< Row<MT,true,true,SF,CRAs...>, true > >
125 , private RowData<CRAs...>
126{
127 private:
128 //**Type definitions****************************************************************************
129 using DataType = RowData<CRAs...>;
130 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
131 //**********************************************************************************************
132
133 public:
134 //**Type definitions****************************************************************************
136 using This = Row<MT,true,true,SF,CRAs...>;
137
139 using BaseType = View< DenseVector<This,true> >;
140
141 using ViewedType = MT;
142 using ResultType = RowTrait_t<MT,CRAs...>;
143 using TransposeType = TransposeType_t<ResultType>;
144 using ElementType = ElementType_t<MT>;
145 using SIMDType = SIMDTrait_t<ElementType>;
146 using ReturnType = ReturnType_t<MT>;
147 using CompositeType = const Row&;
148
150 using ConstReference = ConstReference_t<MT>;
151
153 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
154
156 using ConstPointer = ConstPointer_t<MT>;
157
159 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
160
162 using ConstIterator = ConstIterator_t<MT>;
163
165 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
166 //**********************************************************************************************
167
168 //**Compilation flags***************************************************************************
170 static constexpr bool simdEnabled = MT::simdEnabled;
171
173 static constexpr bool smpAssignable = MT::smpAssignable;
174
176 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
177 //**********************************************************************************************
178
179 //**Constructors********************************************************************************
182 template< typename... RRAs >
183 explicit inline Row( MT& matrix, RRAs... args );
184
185 Row( const Row& ) = default;
187 //**********************************************************************************************
188
189 //**Destructor**********************************************************************************
192 ~Row() = default;
194 //**********************************************************************************************
195
196 //**Data access functions***********************************************************************
199 inline Reference operator[]( size_t index );
200 inline ConstReference operator[]( size_t index ) const;
201 inline Reference at( size_t index );
202 inline ConstReference at( size_t index ) const;
203 inline Pointer data () noexcept;
204 inline ConstPointer data () const noexcept;
205 inline Iterator begin ();
206 inline ConstIterator begin () const;
207 inline ConstIterator cbegin() const;
208 inline Iterator end ();
209 inline ConstIterator end () const;
210 inline ConstIterator cend () const;
212 //**********************************************************************************************
213
214 //**Assignment operators************************************************************************
217 inline Row& operator=( const ElementType& rhs );
218 inline Row& operator=( initializer_list<ElementType> list );
219 inline Row& operator=( const Row& rhs );
220
221 template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
222 template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
223 template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
224 template< typename VT > inline Row& operator*=( const Vector<VT,true>& rhs );
225 template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
226 template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
228 //**********************************************************************************************
229
230 //**Utility functions***************************************************************************
233 using DataType::row;
234
235 inline MT& operand() noexcept;
236 inline const MT& operand() const noexcept;
237
238 inline size_t size() const noexcept;
239 inline size_t spacing() const noexcept;
240 inline size_t capacity() const noexcept;
241 inline size_t nonZeros() const;
242 inline void reset();
244 //**********************************************************************************************
245
246 //**Numeric functions***************************************************************************
249 template< typename Other > inline Row& scale( const Other& scalar );
251 //**********************************************************************************************
252
253 private:
254 //**********************************************************************************************
256 template< typename VT >
257 static constexpr bool VectorizedAssign_v =
258 ( useOptimizedKernels &&
259 simdEnabled && VT::simdEnabled &&
260 IsSIMDCombinable_v< ElementType, ElementType_t<VT> > );
261 //**********************************************************************************************
262
263 //**********************************************************************************************
265 template< typename VT >
266 static constexpr bool VectorizedAddAssign_v =
267 ( VectorizedAssign_v<VT> &&
268 HasSIMDAdd_v< ElementType, ElementType_t<VT> > );
269 //**********************************************************************************************
270
271 //**********************************************************************************************
273 template< typename VT >
274 static constexpr bool VectorizedSubAssign_v =
275 ( VectorizedAssign_v<VT> &&
276 HasSIMDSub_v< ElementType, ElementType_t<VT> > );
277 //**********************************************************************************************
278
279 //**********************************************************************************************
281 template< typename VT >
282 static constexpr bool VectorizedMultAssign_v =
283 ( VectorizedAssign_v<VT> &&
284 HasSIMDMult_v< ElementType, ElementType_t<VT> > );
285 //**********************************************************************************************
286
287 //**********************************************************************************************
289 template< typename VT >
290 static constexpr bool VectorizedDivAssign_v =
291 ( VectorizedAssign_v<VT> &&
292 HasSIMDDiv_v< ElementType, ElementType_t<VT> > );
293 //**********************************************************************************************
294
295 //**SIMD properties*****************************************************************************
297 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
298 //**********************************************************************************************
299
300 public:
301 //**Expression template evaluation functions****************************************************
304 template< typename Other >
305 inline bool canAlias( const Other* alias ) const noexcept;
306
307 template< typename MT2, bool SO2, bool SF2, size_t... CRAs2 >
308 inline bool canAlias( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
309
310 template< typename Other >
311 inline bool isAliased( const Other* alias ) const noexcept;
312
313 template< typename MT2, bool SO2, bool SF2, size_t... CRAs2 >
314 inline bool isAliased( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
315
316 inline bool isAligned () const noexcept;
317 inline bool canSMPAssign() const noexcept;
318
319 BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
320 BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
321 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
322
323 BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
324 BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
325 BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
326 BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
327
328 template< typename VT >
329 inline auto assign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
330
331 template< typename VT >
332 inline auto assign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
333
334 template< typename VT > inline void assign( const SparseVector<VT,true>& rhs );
335
336 template< typename VT >
337 inline auto addAssign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
338
339 template< typename VT >
340 inline auto addAssign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
341
342 template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
343
344 template< typename VT >
345 inline auto subAssign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
346
347 template< typename VT >
348 inline auto subAssign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
349
350 template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
351
352 template< typename VT >
353 inline auto multAssign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
354
355 template< typename VT >
356 inline auto multAssign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
357
358 template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
359
360 template< typename VT >
361 inline auto divAssign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
362
363 template< typename VT >
364 inline auto divAssign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT> >;
366 //**********************************************************************************************
367
368 private:
369 //**Member variables****************************************************************************
372 Operand matrix_;
374 //**********************************************************************************************
375
376 //**Friend declarations*************************************************************************
377 template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CRAs2 > friend class Row;
378 //**********************************************************************************************
379
380 //**Compile time checks*************************************************************************
388 //**********************************************************************************************
389};
391//*************************************************************************************************
392
393
394
395
396//=================================================================================================
397//
398// CONSTRUCTORS
399//
400//=================================================================================================
401
402//*************************************************************************************************
415template< typename MT // Type of the dense matrix
416 , bool SF // Symmetry flag
417 , size_t... CRAs > // Compile time row arguments
418template< typename... RRAs > // Runtime row arguments
419inline Row<MT,true,true,SF,CRAs...>::Row( MT& matrix, RRAs... args )
420 : DataType( args... ) // Base class initialization
421 , matrix_ ( matrix ) // The matrix containing the row
422{
423 if( isChecked( args... ) ) {
424 if( matrix_.rows() <= row() ) {
425 BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
426 }
427 }
428 else {
429 BLAZE_USER_ASSERT( row() < matrix_.rows(), "Invalid row access index" );
430 }
431}
433//*************************************************************************************************
434
435
436
437
438//=================================================================================================
439//
440// DATA ACCESS FUNCTIONS
441//
442//=================================================================================================
443
444//*************************************************************************************************
454template< typename MT // Type of the dense matrix
455 , bool SF // Symmetry flag
456 , size_t... CRAs > // Compile time row arguments
457inline typename Row<MT,true,true,SF,CRAs...>::Reference
458 Row<MT,true,true,SF,CRAs...>::operator[]( size_t index )
459{
460 BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
461 return matrix_(row(),index);
462}
464//*************************************************************************************************
465
466
467//*************************************************************************************************
477template< typename MT // Type of the dense matrix
478 , bool SF // Symmetry flag
479 , size_t... CRAs > // Compile time row arguments
480inline typename Row<MT,true,true,SF,CRAs...>::ConstReference
481 Row<MT,true,true,SF,CRAs...>::operator[]( size_t index ) const
482{
483 BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
484 return const_cast<const MT&>( matrix_ )(row(),index);
485}
487//*************************************************************************************************
488
489
490//*************************************************************************************************
501template< typename MT // Type of the dense matrix
502 , bool SF // Symmetry flag
503 , size_t... CRAs > // Compile time row arguments
504inline typename Row<MT,true,true,SF,CRAs...>::Reference
505 Row<MT,true,true,SF,CRAs...>::at( size_t index )
506{
507 if( index >= size() ) {
508 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
509 }
510 return (*this)[index];
511}
513//*************************************************************************************************
514
515
516//*************************************************************************************************
527template< typename MT // Type of the dense matrix
528 , bool SF // Symmetry flag
529 , size_t... CRAs > // Compile time row arguments
530inline typename Row<MT,true,true,SF,CRAs...>::ConstReference
531 Row<MT,true,true,SF,CRAs...>::at( size_t index ) const
532{
533 if( index >= size() ) {
534 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
535 }
536 return (*this)[index];
537}
539//*************************************************************************************************
540
541
542//*************************************************************************************************
551template< typename MT // Type of the dense matrix
552 , bool SF // Symmetry flag
553 , size_t... CRAs > // Compile time row arguments
554inline typename Row<MT,true,true,SF,CRAs...>::Pointer
556{
557 return matrix_.data( row() );
558}
560//*************************************************************************************************
561
562
563//*************************************************************************************************
572template< typename MT // Type of the dense matrix
573 , bool SF // Symmetry flag
574 , size_t... CRAs > // Compile time row arguments
575inline typename Row<MT,true,true,SF,CRAs...>::ConstPointer
577{
578 return matrix_.data( row() );
579}
581//*************************************************************************************************
582
583
584//*************************************************************************************************
592template< typename MT // Type of the dense matrix
593 , bool SF // Symmetry flag
594 , size_t... CRAs > // Compile time row arguments
595inline typename Row<MT,true,true,SF,CRAs...>::Iterator
597{
598 return matrix_.begin( row() );
599}
601//*************************************************************************************************
602
603
604//*************************************************************************************************
612template< typename MT // Type of the dense matrix
613 , bool SF // Symmetry flag
614 , size_t... CRAs > // Compile time row arguments
615inline typename Row<MT,true,true,SF,CRAs...>::ConstIterator
617{
618 return matrix_.cbegin( row() );
619}
621//*************************************************************************************************
622
623
624//*************************************************************************************************
632template< typename MT // Type of the dense matrix
633 , bool SF // Symmetry flag
634 , size_t... CRAs > // Compile time row arguments
635inline typename Row<MT,true,true,SF,CRAs...>::ConstIterator
637{
638 return matrix_.cbegin( row() );
639}
641//*************************************************************************************************
642
643
644//*************************************************************************************************
652template< typename MT // Type of the dense matrix
653 , bool SF // Symmetry flag
654 , size_t... CRAs > // Compile time row arguments
655inline typename Row<MT,true,true,SF,CRAs...>::Iterator
657{
658 return matrix_.end( row() );
659}
661//*************************************************************************************************
662
663
664//*************************************************************************************************
672template< typename MT // Type of the dense matrix
673 , bool SF // Symmetry flag
674 , size_t... CRAs > // Compile time row arguments
675inline typename Row<MT,true,true,SF,CRAs...>::ConstIterator
677{
678 return matrix_.cend( row() );
679}
681//*************************************************************************************************
682
683
684//*************************************************************************************************
692template< typename MT // Type of the dense matrix
693 , bool SF // Symmetry flag
694 , size_t... CRAs > // Compile time row arguments
695inline typename Row<MT,true,true,SF,CRAs...>::ConstIterator
697{
698 return matrix_.cend( row() );
699}
701//*************************************************************************************************
702
703
704
705
706//=================================================================================================
707//
708// ASSIGNMENT OPERATORS
709//
710//=================================================================================================
711
712//*************************************************************************************************
723template< typename MT // Type of the dense matrix
724 , bool SF // Symmetry flag
725 , size_t... CRAs > // Compile time row arguments
726inline Row<MT,true,true,SF,CRAs...>&
727 Row<MT,true,true,SF,CRAs...>::operator=( const ElementType& rhs )
728{
729 decltype(auto) left( derestrict( matrix_ ) );
730
731 const size_t jbegin( ( IsUpper_v<MT> )
732 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
733 ?( row()+1UL )
734 :( row() ) )
735 :( 0UL ) );
736 const size_t jend ( ( IsLower_v<MT> )
737 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
738 ?( row() )
739 :( row()+1UL ) )
740 :( size() ) );
741
742 for( size_t j=jbegin; j<jend; ++j ) {
743 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, row(), j, rhs ) )
744 left(row(),j) = rhs;
745 }
746
747 return *this;
748}
750//*************************************************************************************************
751
752
753//*************************************************************************************************
768template< typename MT // Type of the dense matrix
769 , bool SF // Symmetry flag
770 , size_t... CRAs > // Compile time row arguments
771inline Row<MT,true,true,SF,CRAs...>&
772 Row<MT,true,true,SF,CRAs...>::operator=( initializer_list<ElementType> list )
773{
774 if( list.size() > size() ) {
775 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
776 }
777
778 if( IsRestricted_v<MT> ) {
779 const InitializerVector<ElementType,true> tmp( list, size() );
780 if( !tryAssign( matrix_, tmp, row(), 0UL ) ) {
781 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
782 }
783 }
784
785 decltype(auto) left( derestrict( *this ) );
786
787 std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
788
789 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
790
791 return *this;
792}
794//*************************************************************************************************
795
796
797//*************************************************************************************************
811template< typename MT // Type of the dense matrix
812 , bool SF // Symmetry flag
813 , size_t... CRAs > // Compile time row arguments
814inline Row<MT,true,true,SF,CRAs...>&
815 Row<MT,true,true,SF,CRAs...>::operator=( const Row& rhs )
816{
817 if( &rhs == this ) return *this;
818
819 if( size() != rhs.size() ) {
820 BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
821 }
822
823 if( !tryAssign( matrix_, rhs, row(), 0UL ) ) {
824 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
825 }
826
827 decltype(auto) left( derestrict( *this ) );
828
829 if( IsExpression_v<MT> && rhs.canAlias( this ) ) {
830 const ResultType tmp( rhs );
831 smpAssign( left, tmp );
832 }
833 else {
834 smpAssign( left, rhs );
835 }
836
837 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
838
839 return *this;
840}
842//*************************************************************************************************
843
844
845//*************************************************************************************************
859template< typename MT // Type of the dense matrix
860 , bool SF // Symmetry flag
861 , size_t... CRAs > // Compile time row arguments
862template< typename VT > // Type of the right-hand side vector
863inline Row<MT,true,true,SF,CRAs...>&
864 Row<MT,true,true,SF,CRAs...>::operator=( const Vector<VT,true>& rhs )
865{
866 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
868
869 if( size() != (*rhs).size() ) {
870 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
871 }
872
873 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
874 Right right( *rhs );
875
876 if( !tryAssign( matrix_, right, row(), 0UL ) ) {
877 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
878 }
879
880 decltype(auto) left( derestrict( *this ) );
881
882 if( IsReference_v<Right> && right.canAlias( this ) ) {
883 const ResultType_t<VT> tmp( right );
884 smpAssign( left, tmp );
885 }
886 else {
887 if( IsSparseVector_v<VT> )
888 reset();
889 smpAssign( left, right );
890 }
891
892 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
893
894 return *this;
895}
897//*************************************************************************************************
898
899
900//*************************************************************************************************
914template< typename MT // Type of the dense matrix
915 , bool SF // Symmetry flag
916 , size_t... CRAs > // Compile time row arguments
917template< typename VT > // Type of the right-hand side vector
918inline Row<MT,true,true,SF,CRAs...>&
919 Row<MT,true,true,SF,CRAs...>::operator+=( const Vector<VT,true>& rhs )
920{
921 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
923
924 if( size() != (*rhs).size() ) {
925 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
926 }
927
928 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
929 Right right( *rhs );
930
931 if( !tryAddAssign( matrix_, right, row(), 0UL ) ) {
932 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
933 }
934
935 decltype(auto) left( derestrict( *this ) );
936
937 if( IsReference_v<Right> && right.canAlias( this ) ) {
938 const ResultType_t<VT> tmp( right );
939 smpAddAssign( left, tmp );
940 }
941 else {
942 smpAddAssign( left, right );
943 }
944
945 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
946
947 return *this;
948}
950//*************************************************************************************************
951
952
953//*************************************************************************************************
967template< typename MT // Type of the dense matrix
968 , bool SF // Symmetry flag
969 , size_t... CRAs > // Compile time row arguments
970template< typename VT > // Type of the right-hand side vector
971inline Row<MT,true,true,SF,CRAs...>&
972 Row<MT,true,true,SF,CRAs...>::operator-=( const Vector<VT,true>& rhs )
973{
974 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
976
977 if( size() != (*rhs).size() ) {
978 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
979 }
980
981 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
982 Right right( *rhs );
983
984 if( !trySubAssign( matrix_, right, row(), 0UL ) ) {
985 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
986 }
987
988 decltype(auto) left( derestrict( *this ) );
989
990 if( IsReference_v<Right> && right.canAlias( this ) ) {
991 const ResultType_t<VT> tmp( right );
992 smpSubAssign( left, tmp );
993 }
994 else {
995 smpSubAssign( left, right );
996 }
997
998 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
999
1000 return *this;
1001}
1003//*************************************************************************************************
1004
1005
1006//*************************************************************************************************
1019template< typename MT // Type of the dense matrix
1020 , bool SF // Symmetry flag
1021 , size_t... CRAs > // Compile time row arguments
1022template< typename VT > // Type of the right-hand side vector
1023inline Row<MT,true,true,SF,CRAs...>&
1024 Row<MT,true,true,SF,CRAs...>::operator*=( const Vector<VT,true>& rhs )
1025{
1026 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
1028
1029 if( size() != (*rhs).size() ) {
1030 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1031 }
1032
1033 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
1034 Right right( *rhs );
1035
1036 if( !tryMultAssign( matrix_, right, row(), 0UL ) ) {
1037 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1038 }
1039
1040 decltype(auto) left( derestrict( *this ) );
1041
1042 if( IsReference_v<Right> && right.canAlias( this ) ) {
1043 const ResultType_t<VT> tmp( right );
1044 smpMultAssign( left, tmp );
1045 }
1046 else {
1047 smpMultAssign( left, right );
1048 }
1049
1050 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1051
1052 return *this;
1053}
1055//*************************************************************************************************
1056
1057
1058//*************************************************************************************************
1070template< typename MT // Type of the dense matrix
1071 , bool SF // Symmetry flag
1072 , size_t... CRAs > // Compile time row arguments
1073template< typename VT > // Type of the right-hand side dense vector
1074inline Row<MT,true,true,SF,CRAs...>&
1075 Row<MT,true,true,SF,CRAs...>::operator/=( const DenseVector<VT,true>& rhs )
1076{
1077 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
1079
1080 if( size() != (*rhs).size() ) {
1081 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1082 }
1083
1084 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
1085 Right right( *rhs );
1086
1087 if( !tryDivAssign( matrix_, right, row(), 0UL ) ) {
1088 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1089 }
1090
1091 decltype(auto) left( derestrict( *this ) );
1092
1093 if( IsReference_v<Right> && right.canAlias( this ) ) {
1094 const ResultType_t<VT> tmp( right );
1095 smpDivAssign( left, tmp );
1096 }
1097 else {
1098 smpDivAssign( left, right );
1099 }
1100
1101 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1102
1103 return *this;
1104}
1106//*************************************************************************************************
1107
1108
1109//*************************************************************************************************
1122template< typename MT // Type of the dense matrix
1123 , bool SF // Symmetry flag
1124 , size_t... CRAs > // Compile time row arguments
1125template< typename VT > // Type of the right-hand side vector
1126inline Row<MT,true,true,SF,CRAs...>&
1127 Row<MT,true,true,SF,CRAs...>::operator%=( const Vector<VT,true>& rhs )
1128{
1129 using blaze::assign;
1130
1131 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
1133
1134 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
1135
1139
1140 if( size() != 3UL || (*rhs).size() != 3UL ) {
1141 BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1142 }
1143
1144 const CrossType right( *this % (*rhs) );
1145
1146 if( !tryAssign( matrix_, right, row(), 0UL ) ) {
1147 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1148 }
1149
1150 decltype(auto) left( derestrict( *this ) );
1151
1152 assign( left, right );
1153
1154 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1155
1156 return *this;
1157}
1159//*************************************************************************************************
1160
1161
1162
1163
1164//=================================================================================================
1165//
1166// UTILITY FUNCTIONS
1167//
1168//=================================================================================================
1169
1170//*************************************************************************************************
1176template< typename MT // Type of the dense matrix
1177 , bool SF // Symmetry flag
1178 , size_t... CRAs > // Compile time row arguments
1179inline MT& Row<MT,true,true,SF,CRAs...>::operand() noexcept
1180{
1181 return matrix_;
1182}
1184//*************************************************************************************************
1185
1186
1187//*************************************************************************************************
1193template< typename MT // Type of the dense matrix
1194 , bool SF // Symmetry flag
1195 , size_t... CRAs > // Compile time row arguments
1196inline const MT& Row<MT,true,true,SF,CRAs...>::operand() const noexcept
1197{
1198 return matrix_;
1199}
1201//*************************************************************************************************
1202
1203
1204//*************************************************************************************************
1210template< typename MT // Type of the dense matrix
1211 , bool SF // Symmetry flag
1212 , size_t... CRAs > // Compile time row arguments
1213inline size_t Row<MT,true,true,SF,CRAs...>::size() const noexcept
1214{
1215 return matrix_.columns();
1216}
1218//*************************************************************************************************
1219
1220
1221//*************************************************************************************************
1230template< typename MT // Type of the dense matrix
1231 , bool SF // Symmetry flag
1232 , size_t... CRAs > // Compile time row arguments
1233inline size_t Row<MT,true,true,SF,CRAs...>::spacing() const noexcept
1234{
1235 return matrix_.spacing();
1236}
1238//*************************************************************************************************
1239
1240
1241//*************************************************************************************************
1247template< typename MT // Type of the dense matrix
1248 , bool SF // Symmetry flag
1249 , size_t... CRAs > // Compile time row arguments
1250inline size_t Row<MT,true,true,SF,CRAs...>::capacity() const noexcept
1251{
1252 return matrix_.capacity( row() );
1253}
1255//*************************************************************************************************
1256
1257
1258//*************************************************************************************************
1267template< typename MT // Type of the dense matrix
1268 , bool SF // Symmetry flag
1269 , size_t... CRAs > // Compile time row arguments
1270inline size_t Row<MT,true,true,SF,CRAs...>::nonZeros() const
1271{
1272 return matrix_.nonZeros( row() );
1273}
1275//*************************************************************************************************
1276
1277
1278//*************************************************************************************************
1284template< typename MT // Type of the dense matrix
1285 , bool SF // Symmetry flag
1286 , size_t... CRAs > // Compile time row arguments
1288{
1289 matrix_.reset( row() );
1290}
1292//*************************************************************************************************
1293
1294
1295
1296
1297//=================================================================================================
1298//
1299// NUMERIC FUNCTIONS
1300//
1301//=================================================================================================
1302
1303//*************************************************************************************************
1316template< typename MT // Type of the dense matrix
1317 , bool SF // Symmetry flag
1318 , size_t... CRAs > // Compile time row arguments
1319template< typename Other > // Data type of the scalar value
1320inline Row<MT,true,true,SF,CRAs...>&
1321 Row<MT,true,true,SF,CRAs...>::scale( const Other& scalar )
1322{
1324
1325 const size_t jbegin( ( IsUpper_v<MT> )
1326 ?( ( IsStrictlyUpper_v<MT> )
1327 ?( row()+1UL )
1328 :( row() ) )
1329 :( 0UL ) );
1330 const size_t jend ( ( IsLower_v<MT> )
1331 ?( ( IsStrictlyLower_v<MT> )
1332 ?( row() )
1333 :( row()+1UL ) )
1334 :( size() ) );
1335
1336 for( size_t j=jbegin; j<jend; ++j ) {
1337 matrix_(row(),j) *= scalar;
1338 }
1339
1340 return *this;
1341}
1343//*************************************************************************************************
1344
1345
1346
1347
1348//=================================================================================================
1349//
1350// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1351//
1352//=================================================================================================
1353
1354//*************************************************************************************************
1365template< typename MT // Type of the dense matrix
1366 , bool SF // Symmetry flag
1367 , size_t... CRAs > // Compile time row arguments
1368template< typename Other > // Data type of the foreign expression
1369inline bool Row<MT,true,true,SF,CRAs...>::canAlias( const Other* alias ) const noexcept
1370{
1371 return matrix_.isAliased( &unview( *alias ) );
1372}
1374//*************************************************************************************************
1375
1376
1377//*************************************************************************************************
1388template< typename MT // Type of the dense matrix
1389 , bool SF // Symmetry flag
1390 , size_t... CRAs > // Compile time row arguments
1391template< typename MT2 // Data type of the foreign dense row
1392 , bool SO2 // Storage order of the foreign dense row
1393 , bool SF2 // Symmetry flag of the foreign dense row
1394 , size_t... CRAs2 > // Compile time row arguments of the foreign dense row
1395inline bool
1396 Row<MT,true,true,SF,CRAs...>::canAlias( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
1397{
1398 return matrix_.isAliased( &alias->matrix_ ) && ( row() == alias->row() );
1399}
1401//*************************************************************************************************
1402
1403
1404//*************************************************************************************************
1415template< typename MT // Type of the dense matrix
1416 , bool SF // Symmetry flag
1417 , size_t... CRAs > // Compile time row arguments
1418template< typename Other > // Data type of the foreign expression
1419inline bool Row<MT,true,true,SF,CRAs...>::isAliased( const Other* alias ) const noexcept
1420{
1421 return matrix_.isAliased( &unview( *alias ) );
1422}
1424//*************************************************************************************************
1425
1426
1427//*************************************************************************************************
1438template< typename MT // Type of the dense matrix
1439 , bool SF // Symmetry flag
1440 , size_t... CRAs > // Compile time row arguments
1441template< typename MT2 // Data type of the foreign dense row
1442 , bool SO2 // Storage order of the foreign dense row
1443 , bool SF2 // Symmetry flag of the foreign dense row
1444 , size_t... CRAs2 > // Compile time row arguments of the foreign dense row
1445inline bool
1446 Row<MT,true,true,SF,CRAs...>::isAliased( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
1447{
1448 return matrix_.isAliased( &alias->matrix_ ) && ( row() == alias->row() );
1449}
1451//*************************************************************************************************
1452
1453
1454//*************************************************************************************************
1464template< typename MT // Type of the dense matrix
1465 , bool SF // Symmetry flag
1466 , size_t... CRAs > // Compile time row arguments
1467inline bool Row<MT,true,true,SF,CRAs...>::isAligned() const noexcept
1468{
1469 return matrix_.isAligned();
1470}
1472//*************************************************************************************************
1473
1474
1475//*************************************************************************************************
1486template< typename MT // Type of the dense matrix
1487 , bool SF // Symmetry flag
1488 , size_t... CRAs > // Compile time row arguments
1489inline bool Row<MT,true,true,SF,CRAs...>::canSMPAssign() const noexcept
1490{
1491 return ( size() > SMP_DVECASSIGN_THRESHOLD );
1492}
1494//*************************************************************************************************
1495
1496
1497//*************************************************************************************************
1510template< typename MT // Type of the dense matrix
1511 , bool SF // Symmetry flag
1512 , size_t... CRAs > // Compile time row arguments
1513BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF,CRAs...>::SIMDType
1514 Row<MT,true,true,SF,CRAs...>::load( size_t index ) const noexcept
1515{
1516 return matrix_.load( row(), index );
1517}
1519//*************************************************************************************************
1520
1521
1522//*************************************************************************************************
1535template< typename MT // Type of the dense matrix
1536 , bool SF // Symmetry flag
1537 , size_t... CRAs > // Compile time row arguments
1538BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF,CRAs...>::SIMDType
1539 Row<MT,true,true,SF,CRAs...>::loada( size_t index ) const noexcept
1540{
1541 return matrix_.loada( row(), index );
1542}
1544//*************************************************************************************************
1545
1546
1547//*************************************************************************************************
1560template< typename MT // Type of the dense matrix
1561 , bool SF // Symmetry flag
1562 , size_t... CRAs > // Compile time row arguments
1563BLAZE_ALWAYS_INLINE typename Row<MT,true,true,SF,CRAs...>::SIMDType
1564 Row<MT,true,true,SF,CRAs...>::loadu( size_t index ) const noexcept
1565{
1566 return matrix_.loadu( row(), index );
1567}
1569//*************************************************************************************************
1570
1571
1572//*************************************************************************************************
1586template< typename MT // Type of the dense matrix
1587 , bool SF // Symmetry flag
1588 , size_t... CRAs > // Compile time row arguments
1590 Row<MT,true,true,SF,CRAs...>::store( size_t index, const SIMDType& value ) noexcept
1591{
1592 matrix_.store( row(), index, value );
1593}
1595//*************************************************************************************************
1596
1597
1598//*************************************************************************************************
1612template< typename MT // Type of the dense matrix
1613 , bool SF // Symmetry flag
1614 , size_t... CRAs > // Compile time row arguments
1616 Row<MT,true,true,SF,CRAs...>::storea( size_t index, const SIMDType& value ) noexcept
1617{
1618 matrix_.storea( row(), index, value );
1619}
1621//*************************************************************************************************
1622
1623
1624//*************************************************************************************************
1638template< typename MT // Type of the dense matrix
1639 , bool SF // Symmetry flag
1640 , size_t... CRAs > // Compile time row arguments
1642 Row<MT,true,true,SF,CRAs...>::storeu( size_t index, const SIMDType& value ) noexcept
1643{
1644 matrix_.storeu( row(), index, value );
1645}
1647//*************************************************************************************************
1648
1649
1650//*************************************************************************************************
1664template< typename MT // Type of the dense matrix
1665 , bool SF // Symmetry flag
1666 , size_t... CRAs > // Compile time row arguments
1668 Row<MT,true,true,SF,CRAs...>::stream( size_t index, const SIMDType& value ) noexcept
1669{
1670 matrix_.stream( row(), index, value );
1671}
1673//*************************************************************************************************
1674
1675
1676//*************************************************************************************************
1688template< typename MT // Type of the dense matrix
1689 , bool SF // Symmetry flag
1690 , size_t... CRAs > // Compile time row arguments
1691template< typename VT > // Type of the right-hand side dense vector
1692inline auto Row<MT,true,true,SF,CRAs...>::assign( const DenseVector<VT,true>& rhs )
1693 -> DisableIf_t< VectorizedAssign_v<VT> >
1694{
1695 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1696
1697 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
1698 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
1699
1700 for( size_t j=0UL; j<jpos; j+=2UL ) {
1701 matrix_(row(),j ) = (*rhs)[j ];
1702 matrix_(row(),j+1UL) = (*rhs)[j+1UL];
1703 }
1704 if( jpos < (*rhs).size() )
1705 matrix_(row(),jpos) = (*rhs)[jpos];
1706}
1708//*************************************************************************************************
1709
1710
1711//*************************************************************************************************
1723template< typename MT // Type of the dense matrix
1724 , bool SF // Symmetry flag
1725 , size_t... CRAs > // Compile time row arguments
1726template< typename VT > // Type of the right-hand side dense vector
1727inline auto Row<MT,true,true,SF,CRAs...>::assign( const DenseVector<VT,true>& rhs )
1728 -> EnableIf_t< VectorizedAssign_v<VT> >
1729{
1731
1732 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1733
1734 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1735
1736 const size_t columns( size() );
1737
1738 const size_t jpos( remainder ? prevMultiple( columns, SIMDSIZE ) : columns );
1739 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
1740
1741 size_t j( 0UL );
1742 Iterator left( begin() );
1743 ConstIterator_t<VT> right( (*rhs).begin() );
1744
1745 if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(*rhs).isAliased( this ) )
1746 {
1747 for( ; j<jpos; j+=SIMDSIZE ) {
1748 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1749 }
1750 for( ; remainder && j<columns; ++j ) {
1751 *left = *right; ++left; ++right;
1752 }
1753 }
1754 else
1755 {
1756 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1757 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1758 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1759 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1760 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1761 }
1762 for( ; j<jpos; j+=SIMDSIZE ) {
1763 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1764 }
1765 for( ; remainder && j<columns; ++j ) {
1766 *left = *right; ++left; ++right;
1767 }
1768 }
1769}
1771//*************************************************************************************************
1772
1773
1774//*************************************************************************************************
1786template< typename MT // Type of the dense matrix
1787 , bool SF // Symmetry flag
1788 , size_t... CRAs > // Compile time row arguments
1789template< typename VT > // Type of the right-hand side sparse vector
1790inline void Row<MT,true,true,SF,CRAs...>::assign( const SparseVector<VT,true>& rhs )
1791{
1792 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1793
1794 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
1795 matrix_(row(),element->index()) = element->value();
1796}
1798//*************************************************************************************************
1799
1800
1801//*************************************************************************************************
1813template< typename MT // Type of the dense matrix
1814 , bool SF // Symmetry flag
1815 , size_t... CRAs > // Compile time row arguments
1816template< typename VT > // Type of the right-hand side dense vector
1817inline auto Row<MT,true,true,SF,CRAs...>::addAssign( const DenseVector<VT,true>& rhs )
1818 -> DisableIf_t< VectorizedAddAssign_v<VT> >
1819{
1820 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1821
1822 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
1823 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
1824
1825 for( size_t j=0UL; j<jpos; j+=2UL ) {
1826 matrix_(row(),j ) += (*rhs)[j ];
1827 matrix_(row(),j+1UL) += (*rhs)[j+1UL];
1828 }
1829 if( jpos < (*rhs).size() )
1830 matrix_(row(),jpos) += (*rhs)[jpos];
1831}
1833//*************************************************************************************************
1834
1835
1836//*************************************************************************************************
1848template< typename MT // Type of the dense matrix
1849 , bool SF // Symmetry flag
1850 , size_t... CRAs > // Compile time row arguments
1851template< typename VT > // Type of the right-hand side dense vector
1852inline auto Row<MT,true,true,SF,CRAs...>::addAssign( const DenseVector<VT,true>& rhs )
1853 -> EnableIf_t< VectorizedAddAssign_v<VT> >
1854{
1856
1857 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1858
1859 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1860
1861 const size_t columns( size() );
1862
1863 const size_t jpos( remainder ? prevMultiple( columns, SIMDSIZE ) : columns );
1864 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
1865
1866 size_t j( 0UL );
1867 Iterator left( begin() );
1868 ConstIterator_t<VT> right( (*rhs).begin() );
1869
1870 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1871 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1872 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1873 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1874 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1875 }
1876 for( ; j<jpos; j+=SIMDSIZE ) {
1877 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1878 }
1879 for( ; remainder && j<columns; ++j ) {
1880 *left += *right; ++left; ++right;
1881 }
1882}
1884//*************************************************************************************************
1885
1886
1887//*************************************************************************************************
1899template< typename MT // Type of the dense matrix
1900 , bool SF // Symmetry flag
1901 , size_t... CRAs > // Compile time row arguments
1902template< typename VT > // Type of the right-hand side sparse vector
1903inline void Row<MT,true,true,SF,CRAs...>::addAssign( const SparseVector<VT,true>& rhs )
1904{
1905 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1906
1907 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
1908 matrix_(row(),element->index()) += element->value();
1909}
1911//*************************************************************************************************
1912
1913
1914//*************************************************************************************************
1926template< typename MT // Type of the dense matrix
1927 , bool SF // Symmetry flag
1928 , size_t... CRAs > // Compile time row arguments
1929template< typename VT > // Type of the right-hand side dense vector
1930inline auto Row<MT,true,true,SF,CRAs...>::subAssign( const DenseVector<VT,true>& rhs )
1931 -> DisableIf_t< VectorizedSubAssign_v<VT> >
1932{
1933 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1934
1935 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
1936 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
1937
1938 for( size_t j=0UL; j<jpos; j+=2UL ) {
1939 matrix_(row(),j ) -= (*rhs)[j ];
1940 matrix_(row(),j+1UL) -= (*rhs)[j+1UL];
1941 }
1942 if( jpos < (*rhs).size() )
1943 matrix_(row(),jpos) -= (*rhs)[jpos];
1944}
1946//*************************************************************************************************
1947
1948
1949//*************************************************************************************************
1961template< typename MT // Type of the dense matrix
1962 , bool SF // Symmetry flag
1963 , size_t... CRAs > // Compile time row arguments
1964template< typename VT > // Type of the right-hand side dense vector
1965inline auto Row<MT,true,true,SF,CRAs...>::subAssign( const DenseVector<VT,true>& rhs )
1966 -> EnableIf_t< VectorizedSubAssign_v<VT> >
1967{
1969
1970 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1971
1972 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1973
1974 const size_t columns( size() );
1975
1976 const size_t jpos( remainder ? prevMultiple( columns, SIMDSIZE ) : columns );
1977 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
1978
1979 size_t j( 0UL );
1980 Iterator left( begin() );
1981 ConstIterator_t<VT> right( (*rhs).begin() );
1982
1983 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
1984 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1985 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1986 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1987 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1988 }
1989 for( ; j<jpos; j+=SIMDSIZE ) {
1990 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1991 }
1992 for( ; remainder && j<columns; ++j ) {
1993 *left -= *right; ++left; ++right;
1994 }
1995}
1997//*************************************************************************************************
1998
1999
2000//*************************************************************************************************
2012template< typename MT // Type of the dense matrix
2013 , bool SF // Symmetry flag
2014 , size_t... CRAs > // Compile time row arguments
2015template< typename VT > // Type of the right-hand side sparse vector
2016inline void Row<MT,true,true,SF,CRAs...>::subAssign( const SparseVector<VT,true>& rhs )
2017{
2018 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2019
2020 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2021 matrix_(row(),element->index()) -= element->value();
2022}
2024//*************************************************************************************************
2025
2026
2027//*************************************************************************************************
2039template< typename MT // Type of the dense matrix
2040 , bool SF // Symmetry flag
2041 , size_t... CRAs > // Compile time row arguments
2042template< typename VT > // Type of the right-hand side dense vector
2043inline auto Row<MT,true,true,SF,CRAs...>::multAssign( const DenseVector<VT,true>& rhs )
2044 -> DisableIf_t< VectorizedMultAssign_v<VT> >
2045{
2046 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2047
2048 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
2049 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
2050
2051 for( size_t j=0UL; j<jpos; j+=2UL ) {
2052 matrix_(row(),j ) *= (*rhs)[j ];
2053 matrix_(row(),j+1UL) *= (*rhs)[j+1UL];
2054 }
2055 if( jpos < (*rhs).size() )
2056 matrix_(row(),jpos) *= (*rhs)[jpos];
2057}
2059//*************************************************************************************************
2060
2061
2062//*************************************************************************************************
2074template< typename MT // Type of the dense matrix
2075 , bool SF // Symmetry flag
2076 , size_t... CRAs > // Compile time row arguments
2077template< typename VT > // Type of the right-hand side dense vector
2078inline auto Row<MT,true,true,SF,CRAs...>::multAssign( const DenseVector<VT,true>& rhs )
2079 -> EnableIf_t< VectorizedMultAssign_v<VT> >
2080{
2082
2083 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2084
2085 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
2086
2087 const size_t columns( size() );
2088
2089 const size_t jpos( remainder ? prevMultiple( columns, SIMDSIZE ) : columns );
2090 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
2091
2092 size_t j( 0UL );
2093 Iterator left( begin() );
2094 ConstIterator_t<VT> right( (*rhs).begin() );
2095
2096 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2097 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2098 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2099 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2100 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2101 }
2102 for( ; j<jpos; j+=SIMDSIZE ) {
2103 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2104 }
2105 for( ; remainder && j<columns; ++j ) {
2106 *left *= *right; ++left; ++right;
2107 }
2108}
2110//*************************************************************************************************
2111
2112
2113//*************************************************************************************************
2125template< typename MT // Type of the dense matrix
2126 , bool SF // Symmetry flag
2127 , size_t... CRAs > // Compile time row arguments
2128template< typename VT > // Type of the right-hand side sparse vector
2129inline void Row<MT,true,true,SF,CRAs...>::multAssign( const SparseVector<VT,true>& rhs )
2130{
2131 using blaze::reset;
2132
2133 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2134
2135 size_t j( 0UL );
2136
2137 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
2138 const size_t index( element->index() );
2139 for( ; j<index; ++j )
2140 reset( matrix_(row(),j) );
2141 matrix_(row(),j) *= element->value();
2142 ++j;
2143 }
2144
2145 for( ; j<size(); ++j ) {
2146 reset( matrix_(row(),j) );
2147 }
2148}
2150//*************************************************************************************************
2151
2152
2153//*************************************************************************************************
2165template< typename MT // Type of the dense matrix
2166 , bool SF // Symmetry flag
2167 , size_t... CRAs > // Compile time row arguments
2168template< typename VT > // Type of the right-hand side dense vector
2169inline auto Row<MT,true,true,SF,CRAs...>::divAssign( const DenseVector<VT,true>& rhs )
2170 -> DisableIf_t< VectorizedDivAssign_v<VT> >
2171{
2172 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2173
2174 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
2175 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
2176
2177 for( size_t j=0UL; j<jpos; j+=2UL ) {
2178 matrix_(row(),j ) /= (*rhs)[j ];
2179 matrix_(row(),j+1UL) /= (*rhs)[j+1UL];
2180 }
2181 if( jpos < (*rhs).size() )
2182 matrix_(row(),jpos) /= (*rhs)[jpos];
2183}
2185//*************************************************************************************************
2186
2187
2188//*************************************************************************************************
2200template< typename MT // Type of the dense matrix
2201 , bool SF // Symmetry flag
2202 , size_t... CRAs > // Compile time row arguments
2203template< typename VT > // Type of the right-hand side dense vector
2204inline auto Row<MT,true,true,SF,CRAs...>::divAssign( const DenseVector<VT,true>& rhs )
2205 -> EnableIf_t< VectorizedDivAssign_v<VT> >
2206{
2208
2209 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2210
2211 const size_t columns( size() );
2212
2213 const size_t jpos( prevMultiple( columns, SIMDSIZE ) );
2214 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
2215
2216 size_t j( 0UL );
2217 Iterator left( begin() );
2218 ConstIterator_t<VT> right( (*rhs).begin() );
2219
2220 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
2221 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2222 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2223 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2224 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2225 }
2226 for( ; j<jpos; j+=SIMDSIZE ) {
2227 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2228 }
2229 for( ; j<columns; ++j ) {
2230 *left /= *right; ++left; ++right;
2231 }
2232}
2234//*************************************************************************************************
2235
2236
2237
2238
2239
2240
2241
2242
2243//=================================================================================================
2244//
2245// CLASS TEMPLATE SPECIALIZATION FOR GENERAL COLUMN-MAJOR MATRICES
2246//
2247//=================================================================================================
2248
2249//*************************************************************************************************
2257template< typename MT // Type of the dense matrix
2258 , size_t... CRAs > // Compile time row arguments
2259class Row<MT,false,true,false,CRAs...>
2260 : public View< DenseVector< Row<MT,false,true,false,CRAs...>, true > >
2261 , private RowData<CRAs...>
2262{
2263 private:
2264 //**Type definitions****************************************************************************
2265 using DataType = RowData<CRAs...>;
2266 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
2267 //**********************************************************************************************
2268
2269 public:
2270 //**Type definitions****************************************************************************
2272 using This = Row<MT,false,true,false,CRAs...>;
2273
2275 using BaseType = View< DenseVector<This,true> >;
2276
2277 using ViewedType = MT;
2278 using ResultType = RowTrait_t<MT,CRAs...>;
2279 using TransposeType = TransposeType_t<ResultType>;
2280 using ElementType = ElementType_t<MT>;
2281 using ReturnType = ElementType_t<MT>;
2282 using CompositeType = const Row&;
2283
2285 using ConstReference = ConstReference_t<MT>;
2286
2288 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
2289
2291 using ConstPointer = ConstPointer_t<MT>;
2292
2294 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
2295 //**********************************************************************************************
2296
2297 //**RowIterator class definition****************************************************************
2300 template< typename MatrixType // Type of the dense matrix
2301 , typename IteratorType > // Type of the dense matrix iterator
2302 class RowIterator
2303 {
2304 public:
2305 //**Type definitions*************************************************************************
2307 using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
2308
2310 using ValueType = typename std::iterator_traits<IteratorType>::value_type;
2311
2313 using PointerType = typename std::iterator_traits<IteratorType>::pointer;
2314
2316 using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
2317
2319 using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
2320
2321 // STL iterator requirements
2322 using iterator_category = IteratorCategory;
2323 using value_type = ValueType;
2324 using pointer = PointerType;
2325 using reference = ReferenceType;
2326 using difference_type = DifferenceType;
2327 //*******************************************************************************************
2328
2329 //**Constructor******************************************************************************
2332 inline RowIterator() noexcept
2333 : matrix_( nullptr ) // The dense matrix containing the row
2334 , row_ ( 0UL ) // The current row index
2335 , column_( 0UL ) // The current column index
2336 , pos_ ( ) // Iterator to the current dense element
2337 {}
2338 //*******************************************************************************************
2339
2340 //**Constructor******************************************************************************
2347 inline RowIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2348 : matrix_( &matrix ) // The dense matrix containing the row
2349 , row_ ( row ) // The current row index
2350 , column_( column ) // The current column index
2351 , pos_ ( ) // Iterator to the current dense element
2352 {
2353 if( column_ != matrix_->columns() )
2354 pos_ = matrix_->begin( column_ ) + row_;
2355 }
2356 //*******************************************************************************************
2357
2358 //**Constructor******************************************************************************
2363 template< typename MatrixType2, typename IteratorType2 >
2364 inline RowIterator( const RowIterator<MatrixType2,IteratorType2>& it ) noexcept
2365 : matrix_( it.matrix_ ) // The dense matrix containing the row
2366 , row_ ( it.row_ ) // The current row index
2367 , column_( it.column_ ) // The current column index
2368 , pos_ ( it.pos_ ) // Iterator to the current dense element
2369 {}
2370 //*******************************************************************************************
2371
2372 //**Addition assignment operator*************************************************************
2378 inline RowIterator& operator+=( size_t inc ) noexcept {
2379 using blaze::reset;
2380 column_ += inc;
2381 if( column_ != matrix_->columns() )
2382 pos_ = matrix_->begin( column_ ) + row_;
2383 else reset( pos_ );
2384 return *this;
2385 }
2386 //*******************************************************************************************
2387
2388 //**Subtraction assignment operator**********************************************************
2394 inline RowIterator& operator-=( size_t dec ) noexcept {
2395 using blaze::reset;
2396 column_ -= dec;
2397 if( column_ != matrix_->columns() )
2398 pos_ = matrix_->begin( column_ ) + row_;
2399 else reset( pos_ );
2400 return *this;
2401 }
2402 //*******************************************************************************************
2403
2404 //**Prefix increment operator****************************************************************
2409 inline RowIterator& operator++() noexcept {
2410 using blaze::reset;
2411 ++column_;
2412 if( column_ != matrix_->columns() )
2413 pos_ = matrix_->begin( column_ ) + row_;
2414 else reset( pos_ );
2415 return *this;
2416 }
2417 //*******************************************************************************************
2418
2419 //**Postfix increment operator***************************************************************
2424 inline const RowIterator operator++( int ) noexcept {
2425 const RowIterator tmp( *this );
2426 ++(*this);
2427 return tmp;
2428 }
2429 //*******************************************************************************************
2430
2431 //**Prefix decrement operator****************************************************************
2436 inline RowIterator& operator--() noexcept {
2437 using blaze::reset;
2438 --column_;
2439 if( column_ != matrix_->columns() )
2440 pos_ = matrix_->begin( column_ ) + row_;
2441 else reset( pos_ );
2442 return *this;
2443 }
2444 //*******************************************************************************************
2445
2446 //**Postfix decrement operator***************************************************************
2451 inline const RowIterator operator--( int ) noexcept {
2452 const RowIterator tmp( *this );
2453 --(*this);
2454 return tmp;
2455 }
2456 //*******************************************************************************************
2457
2458 //**Subscript operator***********************************************************************
2464 inline ReferenceType operator[]( size_t index ) const {
2465 BLAZE_USER_ASSERT( column_+index < matrix_->columns(), "Invalid access index detected" );
2466 const IteratorType pos( matrix_->begin( column_+index ) + row_ );
2467 return *pos;
2468 }
2469 //*******************************************************************************************
2470
2471 //**Element access operator******************************************************************
2476 inline ReferenceType operator*() const {
2477 return *pos_;
2478 }
2479 //*******************************************************************************************
2480
2481 //**Element access operator******************************************************************
2486 inline PointerType operator->() const {
2487 return pos_;
2488 }
2489 //*******************************************************************************************
2490
2491 //**Equality operator************************************************************************
2497 template< typename MatrixType2, typename IteratorType2 >
2498 inline bool operator==( const RowIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2499 return column_ == rhs.column_;
2500 }
2501 //*******************************************************************************************
2502
2503 //**Inequality operator**********************************************************************
2509 template< typename MatrixType2, typename IteratorType2 >
2510 inline bool operator!=( const RowIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2511 return !( *this == rhs );
2512 }
2513 //*******************************************************************************************
2514
2515 //**Less-than operator***********************************************************************
2521 template< typename MatrixType2, typename IteratorType2 >
2522 inline bool operator<( const RowIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2523 return column_ < rhs.column_;
2524 }
2525 //*******************************************************************************************
2526
2527 //**Greater-than operator********************************************************************
2533 template< typename MatrixType2, typename IteratorType2 >
2534 inline bool operator>( const RowIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2535 return column_ > rhs.column_;
2536 }
2537 //*******************************************************************************************
2538
2539 //**Less-or-equal-than operator**************************************************************
2545 template< typename MatrixType2, typename IteratorType2 >
2546 inline bool operator<=( const RowIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2547 return column_ <= rhs.column_;
2548 }
2549 //*******************************************************************************************
2550
2551 //**Greater-or-equal-than operator***********************************************************
2557 template< typename MatrixType2, typename IteratorType2 >
2558 inline bool operator>=( const RowIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2559 return column_ >= rhs.column_;
2560 }
2561 //*******************************************************************************************
2562
2563 //**Subtraction operator*********************************************************************
2569 inline DifferenceType operator-( const RowIterator& rhs ) const noexcept {
2570 return column_ - rhs.column_;
2571 }
2572 //*******************************************************************************************
2573
2574 //**Addition operator************************************************************************
2581 friend inline const RowIterator operator+( const RowIterator& it, size_t inc ) noexcept {
2582 return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2583 }
2584 //*******************************************************************************************
2585
2586 //**Addition operator************************************************************************
2593 friend inline const RowIterator operator+( size_t inc, const RowIterator& it ) noexcept {
2594 return RowIterator( *it.matrix_, it.row_, it.column_+inc );
2595 }
2596 //*******************************************************************************************
2597
2598 //**Subtraction operator*********************************************************************
2605 friend inline const RowIterator operator-( const RowIterator& it, size_t dec ) noexcept {
2606 return RowIterator( *it.matrix_, it.row_, it.column_-dec );
2607 }
2608 //*******************************************************************************************
2609
2610 private:
2611 //**Member variables*************************************************************************
2612 MatrixType* matrix_;
2613 size_t row_;
2614 size_t column_;
2615 IteratorType pos_;
2616 //*******************************************************************************************
2617
2618 //**Friend declarations**********************************************************************
2619 template< typename MatrixType2, typename IteratorType2 > friend class RowIterator;
2620 //*******************************************************************************************
2621 };
2622 //**********************************************************************************************
2623
2624 //**Type definitions****************************************************************************
2626 using ConstIterator = RowIterator< const MT, ConstIterator_t<MT> >;
2627
2629 using Iterator = If_t< IsConst_v<MT>, ConstIterator, RowIterator< MT, Iterator_t<MT> > >;
2630 //**********************************************************************************************
2631
2632 //**Compilation flags***************************************************************************
2634 static constexpr bool simdEnabled = false;
2635
2637 static constexpr bool smpAssignable = MT::smpAssignable;
2638
2640 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2641 //**********************************************************************************************
2642
2643 //**Constructors********************************************************************************
2646 template< typename... RRAs >
2647 explicit inline Row( MT& matrix, RRAs... args );
2648
2649 Row( const Row& ) = default;
2651 //**********************************************************************************************
2652
2653 //**Destructor**********************************************************************************
2656 ~Row() = default;
2658 //**********************************************************************************************
2659
2660 //**Data access functions***********************************************************************
2663 inline Reference operator[]( size_t index );
2664 inline ConstReference operator[]( size_t index ) const;
2665 inline Reference at( size_t index );
2666 inline ConstReference at( size_t index ) const;
2667 inline Pointer data () noexcept;
2668 inline ConstPointer data () const noexcept;
2669 inline Iterator begin ();
2670 inline ConstIterator begin () const;
2671 inline ConstIterator cbegin() const;
2672 inline Iterator end ();
2673 inline ConstIterator end () const;
2674 inline ConstIterator cend () const;
2676 //**********************************************************************************************
2677
2678 //**Assignment operators************************************************************************
2681 inline Row& operator=( const ElementType& rhs );
2682 inline Row& operator=( initializer_list<ElementType> list );
2683 inline Row& operator=( const Row& rhs );
2684
2685 template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
2686 template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
2687 template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
2688 template< typename VT > inline Row& operator*=( const Vector<VT,true>& rhs );
2689 template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
2690 template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
2692 //**********************************************************************************************
2693
2694 //**Utility functions***************************************************************************
2697 using DataType::row;
2698
2699 inline MT& operand() noexcept;
2700 inline const MT& operand() const noexcept;
2701
2702 inline size_t size() const noexcept;
2703 inline size_t spacing() const noexcept;
2704 inline size_t capacity() const noexcept;
2705 inline size_t nonZeros() const;
2706 inline void reset();
2708 //**********************************************************************************************
2709
2710 //**Numeric functions***************************************************************************
2713 template< typename Other > inline Row& scale( const Other& scalar );
2715 //**********************************************************************************************
2716
2717 //**Expression template evaluation functions****************************************************
2720 template< typename Other >
2721 inline bool canAlias( const Other* alias ) const noexcept;
2722
2723 template< typename MT2, bool SO2, bool SF2, size_t... CRAs2 >
2724 inline bool canAlias( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
2725
2726 template< typename Other >
2727 inline bool isAliased( const Other* alias ) const noexcept;
2728
2729 template< typename MT2, bool SO2, bool SF2, size_t... CRAs2 >
2730 inline bool isAliased( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
2731
2732 inline bool isAligned () const noexcept;
2733 inline bool canSMPAssign() const noexcept;
2734
2735 template< typename VT > inline void assign ( const DenseVector <VT,true>& rhs );
2736 template< typename VT > inline void assign ( const SparseVector<VT,true>& rhs );
2737 template< typename VT > inline void addAssign ( const DenseVector <VT,true>& rhs );
2738 template< typename VT > inline void addAssign ( const SparseVector<VT,true>& rhs );
2739 template< typename VT > inline void subAssign ( const DenseVector <VT,true>& rhs );
2740 template< typename VT > inline void subAssign ( const SparseVector<VT,true>& rhs );
2741 template< typename VT > inline void multAssign( const DenseVector <VT,true>& rhs );
2742 template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
2743 template< typename VT > inline void divAssign ( const DenseVector <VT,true>& rhs );
2745 //**********************************************************************************************
2746
2747 private:
2748 //**Member variables****************************************************************************
2751 Operand matrix_;
2753 //**********************************************************************************************
2754
2755 //**Friend declarations*************************************************************************
2756 template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CRAs2 > friend class Row;
2757 //**********************************************************************************************
2758
2759 //**Compile time checks*************************************************************************
2768 //**********************************************************************************************
2769};
2771//*************************************************************************************************
2772
2773
2774
2775
2776//=================================================================================================
2777//
2778// CONSTRUCTORS
2779//
2780//=================================================================================================
2781
2782//*************************************************************************************************
2795template< typename MT // Type of the dense matrix
2796 , size_t... CRAs > // Compile time row arguments
2797template< typename... RRAs > // Runtime row arguments
2798inline Row<MT,false,true,false,CRAs...>::Row( MT& matrix, RRAs... args )
2799 : DataType( args... ) // Base class initialization
2800 , matrix_ ( matrix ) // The matrix containing the row
2801{
2802 if( isChecked( args... ) ) {
2803 if( matrix_.rows() <= row() ) {
2804 BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
2805 }
2806 }
2807 else {
2808 BLAZE_USER_ASSERT( row() < matrix_.rows(), "Invalid row access index" );
2809 }
2810}
2812//*************************************************************************************************
2813
2814
2815
2816
2817//=================================================================================================
2818//
2819// DATA ACCESS FUNCTIONS
2820//
2821//=================================================================================================
2822
2823//*************************************************************************************************
2833template< typename MT // Type of the dense matrix
2834 , size_t... CRAs > // Compile time row arguments
2835inline typename Row<MT,false,true,false,CRAs...>::Reference
2836 Row<MT,false,true,false,CRAs...>::operator[]( size_t index )
2837{
2838 BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2839 return matrix_(row(),index);
2840}
2842//*************************************************************************************************
2843
2844
2845//*************************************************************************************************
2855template< typename MT // Type of the dense matrix
2856 , size_t... CRAs > // Compile time row arguments
2857inline typename Row<MT,false,true,false,CRAs...>::ConstReference
2858 Row<MT,false,true,false,CRAs...>::operator[]( size_t index ) const
2859{
2860 BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
2861 return const_cast<const MT&>( matrix_ )(row(),index);
2862}
2864//*************************************************************************************************
2865
2866
2867//*************************************************************************************************
2878template< typename MT // Type of the dense matrix
2879 , size_t... CRAs > // Compile time row arguments
2880inline typename Row<MT,false,true,false,CRAs...>::Reference
2881 Row<MT,false,true,false,CRAs...>::at( size_t index )
2882{
2883 if( index >= size() ) {
2884 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2885 }
2886 return (*this)[index];
2887}
2889//*************************************************************************************************
2890
2891
2892//*************************************************************************************************
2903template< typename MT // Type of the dense matrix
2904 , size_t... CRAs > // Compile time row arguments
2905inline typename Row<MT,false,true,false,CRAs...>::ConstReference
2906 Row<MT,false,true,false,CRAs...>::at( size_t index ) const
2907{
2908 if( index >= size() ) {
2909 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
2910 }
2911 return (*this)[index];
2912}
2914//*************************************************************************************************
2915
2916
2917//*************************************************************************************************
2926template< typename MT // Type of the dense matrix
2927 , size_t... CRAs > // Compile time row arguments
2928inline typename Row<MT,false,true,false,CRAs...>::Pointer
2930{
2931 return matrix_.data() + row();
2932}
2934//*************************************************************************************************
2935
2936
2937//*************************************************************************************************
2946template< typename MT // Type of the dense matrix
2947 , size_t... CRAs > // Compile time row arguments
2948inline typename Row<MT,false,true,false,CRAs...>::ConstPointer
2950{
2951 return matrix_.data() + row();
2952}
2954//*************************************************************************************************
2955
2956
2957//*************************************************************************************************
2965template< typename MT // Type of the dense matrix
2966 , size_t... CRAs > // Compile time row arguments
2967inline typename Row<MT,false,true,false,CRAs...>::Iterator
2969{
2970 return Iterator( matrix_, row(), 0UL );
2971}
2973//*************************************************************************************************
2974
2975
2976//*************************************************************************************************
2984template< typename MT // Type of the dense matrix
2985 , size_t... CRAs > // Compile time row arguments
2986inline typename Row<MT,false,true,false,CRAs...>::ConstIterator
2988{
2989 return ConstIterator( matrix_, row(), 0UL );
2990}
2992//*************************************************************************************************
2993
2994
2995//*************************************************************************************************
3003template< typename MT // Type of the dense matrix
3004 , size_t... CRAs > // Compile time row arguments
3005inline typename Row<MT,false,true,false,CRAs...>::ConstIterator
3007{
3008 return ConstIterator( matrix_, row(), 0UL );
3009}
3011//*************************************************************************************************
3012
3013
3014//*************************************************************************************************
3022template< typename MT // Type of the dense matrix
3023 , size_t... CRAs > // Compile time row arguments
3024inline typename Row<MT,false,true,false,CRAs...>::Iterator
3026{
3027 return Iterator( matrix_, row(), size() );
3028}
3030//*************************************************************************************************
3031
3032
3033//*************************************************************************************************
3041template< typename MT // Type of the dense matrix
3042 , size_t... CRAs > // Compile time row arguments
3043inline typename Row<MT,false,true,false,CRAs...>::ConstIterator
3045{
3046 return ConstIterator( matrix_, row(), size() );
3047}
3049//*************************************************************************************************
3050
3051
3052//*************************************************************************************************
3060template< typename MT // Type of the dense matrix
3061 , size_t... CRAs > // Compile time row arguments
3062inline typename Row<MT,false,true,false,CRAs...>::ConstIterator
3064{
3065 return ConstIterator( matrix_, row(), size() );
3066}
3068//*************************************************************************************************
3069
3070
3071
3072
3073//=================================================================================================
3074//
3075// ASSIGNMENT OPERATORS
3076//
3077//=================================================================================================
3078
3079//*************************************************************************************************
3090template< typename MT // Type of the dense matrix
3091 , size_t... CRAs > // Compile time row arguments
3092inline Row<MT,false,true,false,CRAs...>&
3093 Row<MT,false,true,false,CRAs...>::operator=( const ElementType& rhs )
3094{
3095 decltype(auto) left( derestrict( matrix_ ) );
3096
3097 const size_t jbegin( ( IsUpper_v<MT> )
3098 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3099 ?( row()+1UL )
3100 :( row() ) )
3101 :( 0UL ) );
3102 const size_t jend ( ( IsLower_v<MT> )
3103 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3104 ?( row() )
3105 :( row()+1UL ) )
3106 :( size() ) );
3107
3108 for( size_t j=jbegin; j<jend; ++j ) {
3109 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, row(), j, rhs ) )
3110 left(row(),j) = rhs;
3111 }
3112
3113 return *this;
3114}
3116//*************************************************************************************************
3117
3118
3119//*************************************************************************************************
3134template< typename MT // Type of the dense matrix
3135 , size_t... CRAs > // Compile time row arguments
3136inline Row<MT,false,true,false,CRAs...>&
3137 Row<MT,false,true,false,CRAs...>::operator=( initializer_list<ElementType> list )
3138{
3139 if( list.size() > size() ) {
3140 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
3141 }
3142
3143 if( IsRestricted_v<MT> ) {
3144 const InitializerVector<ElementType,true> tmp( list, size() );
3145 if( !tryAssign( matrix_, tmp, row(), 0UL ) ) {
3146 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3147 }
3148 }
3149
3150 decltype(auto) left( derestrict( *this ) );
3151
3152 std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
3153
3154 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3155
3156 return *this;
3157}
3159//*************************************************************************************************
3160
3161
3162//*************************************************************************************************
3176template< typename MT // Type of the dense matrix
3177 , size_t... CRAs > // Compile time row arguments
3178inline Row<MT,false,true,false,CRAs...>&
3179 Row<MT,false,true,false,CRAs...>::operator=( const Row& rhs )
3180{
3181 if( &rhs == this ) return *this;
3182
3183 if( size() != rhs.size() ) {
3184 BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
3185 }
3186
3187 if( !tryAssign( matrix_, rhs, row(), 0UL ) ) {
3188 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3189 }
3190
3191 decltype(auto) left( derestrict( *this ) );
3192
3193 if( IsExpression_v<MT> && rhs.canAlias( this ) ) {
3194 const ResultType tmp( rhs );
3195 smpAssign( left, tmp );
3196 }
3197 else {
3198 smpAssign( left, rhs );
3199 }
3200
3201 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3202
3203 return *this;
3204}
3206//*************************************************************************************************
3207
3208
3209//*************************************************************************************************
3223template< typename MT // Type of the dense matrix
3224 , size_t... CRAs > // Compile time row arguments
3225template< typename VT > // Type of the right-hand side vector
3226inline Row<MT,false,true,false,CRAs...>&
3227 Row<MT,false,true,false,CRAs...>::operator=( const Vector<VT,true>& rhs )
3228{
3232
3233 if( size() != (*rhs).size() ) {
3234 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3235 }
3236
3237 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3238 Right right( *rhs );
3239
3240 if( !tryAssign( matrix_, right, row(), 0UL ) ) {
3241 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3242 }
3243
3244 decltype(auto) left( derestrict( *this ) );
3245
3246 if( IsReference_v<Right> && right.canAlias( this ) ) {
3247 const ResultType tmp( right );
3248 smpAssign( left, tmp );
3249 }
3250 else {
3251 if( IsSparseVector_v<VT> )
3252 reset();
3253 smpAssign( left, right );
3254 }
3255
3256 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3257
3258 return *this;
3259}
3261//*************************************************************************************************
3262
3263
3264//*************************************************************************************************
3278template< typename MT // Type of the dense matrix
3279 , size_t... CRAs > // Compile time row arguments
3280template< typename VT > // Type of the right-hand side vector
3281inline Row<MT,false,true,false,CRAs...>&
3282 Row<MT,false,true,false,CRAs...>::operator+=( const Vector<VT,true>& rhs )
3283{
3284 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
3286
3287 if( size() != (*rhs).size() ) {
3288 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3289 }
3290
3291 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3292 Right right( *rhs );
3293
3294 if( !tryAddAssign( matrix_, right, row(), 0UL ) ) {
3295 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3296 }
3297
3298 decltype(auto) left( derestrict( *this ) );
3299
3300 if( IsReference_v<Right> && right.canAlias( this ) ) {
3301 const ResultType_t<VT> tmp( right );
3302 smpAddAssign( left, tmp );
3303 }
3304 else {
3305 smpAddAssign( left, right );
3306 }
3307
3308 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3309
3310 return *this;
3311}
3313//*************************************************************************************************
3314
3315
3316//*************************************************************************************************
3330template< typename MT // Type of the dense matrix
3331 , size_t... CRAs > // Compile time row arguments
3332template< typename VT > // Type of the right-hand side vector
3333inline Row<MT,false,true,false,CRAs...>&
3334 Row<MT,false,true,false,CRAs...>::operator-=( const Vector<VT,true>& rhs )
3335{
3336 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
3338
3339 if( size() != (*rhs).size() ) {
3340 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3341 }
3342
3343 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3344 Right right( *rhs );
3345
3346 if( !trySubAssign( matrix_, right, row(), 0UL ) ) {
3347 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3348 }
3349
3350 decltype(auto) left( derestrict( *this ) );
3351
3352 if( IsReference_v<Right> && right.canAlias( this ) ) {
3353 const ResultType_t<VT> tmp( right );
3354 smpSubAssign( left, tmp );
3355 }
3356 else {
3357 smpSubAssign( left, right );
3358 }
3359
3360 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3361
3362 return *this;
3363}
3365//*************************************************************************************************
3366
3367
3368//*************************************************************************************************
3381template< typename MT // Type of the dense matrix
3382 , size_t... CRAs > // Compile time row arguments
3383template< typename VT > // Type of the right-hand side vector
3384inline Row<MT,false,true,false,CRAs...>&
3385 Row<MT,false,true,false,CRAs...>::operator*=( const Vector<VT,true>& rhs )
3386{
3387 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
3389
3390 if( size() != (*rhs).size() ) {
3391 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3392 }
3393
3394 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3395 Right right( *rhs );
3396
3397 if( !tryMultAssign( matrix_, right, row(), 0UL ) ) {
3398 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3399 }
3400
3401 decltype(auto) left( derestrict( *this ) );
3402
3403 if( IsReference_v<Right> && right.canAlias( this ) ) {
3404 const ResultType_t<VT> tmp( right );
3405 smpMultAssign( left, tmp );
3406 }
3407 else {
3408 smpMultAssign( left, right );
3409 }
3410
3411 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3412
3413 return *this;
3414}
3416//*************************************************************************************************
3417
3418
3419//*************************************************************************************************
3431template< typename MT // Type of the dense matrix
3432 , size_t... CRAs > // Compile time row arguments
3433template< typename VT > // Type of the right-hand side dense vector
3434inline Row<MT,false,true,false,CRAs...>&
3435 Row<MT,false,true,false,CRAs...>::operator/=( const DenseVector<VT,true>& rhs )
3436{
3437 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
3439
3440 if( size() != (*rhs).size() ) {
3441 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3442 }
3443
3444 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3445 Right right( *rhs );
3446
3447 if( !tryDivAssign( matrix_, right, row(), 0UL ) ) {
3448 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3449 }
3450
3451 decltype(auto) left( derestrict( *this ) );
3452
3453 if( IsReference_v<Right> && right.canAlias( this ) ) {
3454 const ResultType_t<VT> tmp( right );
3455 smpDivAssign( left, tmp );
3456 }
3457 else {
3458 smpDivAssign( left, right );
3459 }
3460
3461 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3462
3463 return *this;
3464}
3466//*************************************************************************************************
3467
3468
3469//*************************************************************************************************
3482template< typename MT // Type of the dense matrix
3483 , size_t... CRAs > // Compile time row arguments
3484template< typename VT > // Type of the right-hand side vector
3485inline Row<MT,false,true,false,CRAs...>&
3486 Row<MT,false,true,false,CRAs...>::operator%=( const Vector<VT,true>& rhs )
3487{
3488 using blaze::assign;
3489
3490 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
3492
3493 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
3494
3498
3499 if( size() != 3UL || (*rhs).size() != 3UL ) {
3500 BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3501 }
3502
3503 const CrossType right( *this % (*rhs) );
3504
3505 if( !tryAssign( matrix_, right, row(), 0UL ) ) {
3506 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3507 }
3508
3509 decltype(auto) left( derestrict( *this ) );
3510
3511 assign( left, right );
3512
3513 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3514
3515 return *this;
3516}
3518//*************************************************************************************************
3519
3520
3521
3522
3523//=================================================================================================
3524//
3525// UTILITY FUNCTIONS
3526//
3527//=================================================================================================
3528
3529//*************************************************************************************************
3535template< typename MT // Type of the dense matrix
3536 , size_t... CRAs > // Compile time row arguments
3537inline MT& Row<MT,false,true,false,CRAs...>::operand() noexcept
3538{
3539 return matrix_;
3540}
3542//*************************************************************************************************
3543
3544
3545//*************************************************************************************************
3551template< typename MT // Type of the dense matrix
3552 , size_t... CRAs > // Compile time row arguments
3553inline const MT& Row<MT,false,true,false,CRAs...>::operand() const noexcept
3554{
3555 return matrix_;
3556}
3558//*************************************************************************************************
3559
3560
3561//*************************************************************************************************
3567template< typename MT // Type of the dense matrix
3568 , size_t... CRAs > // Compile time row arguments
3569inline size_t Row<MT,false,true,false,CRAs...>::size() const noexcept
3570{
3571 return matrix_.columns();
3572}
3574//*************************************************************************************************
3575
3576
3577//*************************************************************************************************
3586template< typename MT // Type of the dense matrix
3587 , size_t... CRAs > // Compile time row arguments
3588inline size_t Row<MT,false,true,false,CRAs...>::spacing() const noexcept
3589{
3590 return matrix_.spacing();
3591}
3593//*************************************************************************************************
3594
3595
3596//*************************************************************************************************
3602template< typename MT // Type of the dense matrix
3603 , size_t... CRAs > // Compile time row arguments
3604inline size_t Row<MT,false,true,false,CRAs...>::capacity() const noexcept
3605{
3606 return matrix_.columns();
3607}
3609//*************************************************************************************************
3610
3611
3612//*************************************************************************************************
3621template< typename MT // Type of the dense matrix
3622 , size_t... CRAs > // Compile time row arguments
3624{
3625 const size_t columns( size() );
3626 size_t nonzeros( 0UL );
3627
3628 for( size_t j=0UL; j<columns; ++j )
3629 if( !isDefault( matrix_(row(),j) ) )
3630 ++nonzeros;
3631
3632 return nonzeros;
3633}
3635//*************************************************************************************************
3636
3637
3638//*************************************************************************************************
3644template< typename MT // Type of the dense matrix
3645 , size_t... CRAs > // Compile time row arguments
3647{
3648 using blaze::clear;
3649
3650 const size_t jbegin( ( IsUpper_v<MT> )
3651 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3652 ?( row()+1UL )
3653 :( row() ) )
3654 :( 0UL ) );
3655 const size_t jend ( ( IsLower_v<MT> )
3656 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3657 ?( row() )
3658 :( row()+1UL ) )
3659 :( size() ) );
3660
3661 for( size_t j=jbegin; j<jend; ++j )
3662 clear( matrix_(row(),j) );
3663}
3665//*************************************************************************************************
3666
3667
3668
3669
3670//=================================================================================================
3671//
3672// NUMERIC FUNCTIONS
3673//
3674//=================================================================================================
3675
3676//*************************************************************************************************
3689template< typename MT // Type of the dense matrix
3690 , size_t... CRAs > // Compile time row arguments
3691template< typename Other > // Data type of the scalar value
3692inline Row<MT,false,true,false,CRAs...>&
3693 Row<MT,false,true,false,CRAs...>::scale( const Other& scalar )
3694{
3696
3697 const size_t jbegin( ( IsUpper_v<MT> )
3698 ?( ( IsStrictlyUpper_v<MT> )
3699 ?( row()+1UL )
3700 :( row() ) )
3701 :( 0UL ) );
3702 const size_t jend ( ( IsLower_v<MT> )
3703 ?( ( IsStrictlyLower_v<MT> )
3704 ?( row() )
3705 :( row()+1UL ) )
3706 :( size() ) );
3707
3708 for( size_t j=jbegin; j<jend; ++j ) {
3709 matrix_(row(),j) *= scalar;
3710 }
3711
3712 return *this;
3713}
3715//*************************************************************************************************
3716
3717
3718
3719
3720//=================================================================================================
3721//
3722// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3723//
3724//=================================================================================================
3725
3726//*************************************************************************************************
3737template< typename MT // Type of the dense matrix
3738 , size_t... CRAs > // Compile time row arguments
3739template< typename Other > // Data type of the foreign expression
3740inline bool Row<MT,false,true,false,CRAs...>::canAlias( const Other* alias ) const noexcept
3741{
3742 return matrix_.isAliased( &unview( *alias ) );
3743}
3745//*************************************************************************************************
3746
3747
3748//*************************************************************************************************
3759template< typename MT // Type of the dense matrix
3760 , size_t... CRAs > // Compile time row arguments
3761template< typename MT2 // Data type of the foreign dense row
3762 , bool SO2 // Storage order of the foreign dense row
3763 , bool SF2 // Symmetry flag of the foreign dense row
3764 , size_t... CRAs2 > // Compile time row arguments of the foreign dense row
3765inline bool
3766 Row<MT,false,true,false,CRAs...>::canAlias( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
3767{
3768 return matrix_.isAliased( &alias->matrix_ ) && ( row() == alias->row() );
3769}
3771//*************************************************************************************************
3772
3773
3774//*************************************************************************************************
3785template< typename MT // Type of the dense matrix
3786 , size_t... CRAs > // Compile time row arguments
3787template< typename Other > // Data type of the foreign expression
3788inline bool Row<MT,false,true,false,CRAs...>::isAliased( const Other* alias ) const noexcept
3789{
3790 return matrix_.isAliased( &unview( *alias ) );
3791}
3793//*************************************************************************************************
3794
3795
3796//*************************************************************************************************
3807template< typename MT // Type of the dense matrix
3808 , size_t... CRAs > // Compile time row arguments
3809template< typename MT2 // Data type of the foreign dense row
3810 , bool SO2 // Storage order of the foreign dense row
3811 , bool SF2 // Symmetry flag of the foreign dense row
3812 , size_t... CRAs2 > // Compile time row arguments of the foreign dense row
3813inline bool
3814 Row<MT,false,true,false,CRAs...>::isAliased( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
3815{
3816 return matrix_.isAliased( &alias->matrix_ ) && ( row() == alias->row() );
3817}
3819//*************************************************************************************************
3820
3821
3822//*************************************************************************************************
3832template< typename MT // Type of the dense matrix
3833 , size_t... CRAs > // Compile time row arguments
3834inline bool Row<MT,false,true,false,CRAs...>::isAligned() const noexcept
3835{
3836 return false;
3837}
3839//*************************************************************************************************
3840
3841
3842//*************************************************************************************************
3853template< typename MT // Type of the dense matrix
3854 , size_t... CRAs > // Compile time row arguments
3855inline bool Row<MT,false,true,false,CRAs...>::canSMPAssign() const noexcept
3856{
3857 return ( size() > SMP_DVECASSIGN_THRESHOLD );
3858}
3860//*************************************************************************************************
3861
3862
3863//*************************************************************************************************
3875template< typename MT // Type of the dense matrix
3876 , size_t... CRAs > // Compile time row arguments
3877template< typename VT > // Type of the right-hand side dense vector
3878inline void Row<MT,false,true,false,CRAs...>::assign( const DenseVector<VT,true>& rhs )
3879{
3880 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3881
3882 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
3883 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
3884
3885 for( size_t j=0UL; j<jpos; j+=2UL ) {
3886 matrix_(row(),j ) = (*rhs)[j ];
3887 matrix_(row(),j+1UL) = (*rhs)[j+1UL];
3888 }
3889 if( jpos < (*rhs).size() )
3890 matrix_(row(),jpos) = (*rhs)[jpos];
3891}
3893//*************************************************************************************************
3894
3895
3896//*************************************************************************************************
3908template< typename MT // Type of the dense matrix
3909 , size_t... CRAs > // Compile time row arguments
3910template< typename VT > // Type of the right-hand side sparse vector
3911inline void Row<MT,false,true,false,CRAs...>::assign( const SparseVector<VT,true>& rhs )
3912{
3913 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3914
3915 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
3916 matrix_(row(),element->index()) = element->value();
3917}
3919//*************************************************************************************************
3920
3921
3922//*************************************************************************************************
3934template< typename MT // Type of the dense matrix
3935 , size_t... CRAs > // Compile time row arguments
3936template< typename VT > // Type of the right-hand side dense vector
3937inline void Row<MT,false,true,false,CRAs...>::addAssign( const DenseVector<VT,true>& rhs )
3938{
3939 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3940
3941 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
3942 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
3943
3944 for( size_t j=0UL; j<jpos; j+=2UL ) {
3945 matrix_(row(),j ) += (*rhs)[j ];
3946 matrix_(row(),j+1UL) += (*rhs)[j+1UL];
3947 }
3948 if( jpos < (*rhs).size() )
3949 matrix_(row(),jpos) += (*rhs)[jpos];
3950}
3952//*************************************************************************************************
3953
3954
3955//*************************************************************************************************
3967template< typename MT // Type of the dense matrix
3968 , size_t... CRAs > // Compile time row arguments
3969template< typename VT > // Type of the right-hand side sparse vector
3970inline void Row<MT,false,true,false,CRAs...>::addAssign( const SparseVector<VT,true>& rhs )
3971{
3972 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3973
3974 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
3975 matrix_(row(),element->index()) += element->value();
3976}
3978//*************************************************************************************************
3979
3980
3981//*************************************************************************************************
3993template< typename MT // Type of the dense matrix
3994 , size_t... CRAs > // Compile time row arguments
3995template< typename VT > // Type of the right-hand side dense vector
3996inline void Row<MT,false,true,false,CRAs...>::subAssign( const DenseVector<VT,true>& rhs )
3997{
3998 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3999
4000 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
4001 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
4002
4003 for( size_t j=0UL; j<jpos; j+=2UL ) {
4004 matrix_(row(),j ) -= (*rhs)[j ];
4005 matrix_(row(),j+1UL) -= (*rhs)[j+1UL];
4006 }
4007 if( jpos < (*rhs).size() )
4008 matrix_(row(),jpos) -= (*rhs)[jpos];
4009}
4011//*************************************************************************************************
4012
4013
4014//*************************************************************************************************
4026template< typename MT // Type of the dense matrix
4027 , size_t... CRAs > // Compile time row arguments
4028template< typename VT > // Type of the right-hand side sparse vector
4029inline void Row<MT,false,true,false,CRAs...>::subAssign( const SparseVector<VT,true>& rhs )
4030{
4031 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4032
4033 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
4034 matrix_(row(),element->index()) -= element->value();
4035}
4037//*************************************************************************************************
4038
4039
4040//*************************************************************************************************
4052template< typename MT // Type of the dense matrix
4053 , size_t... CRAs > // Compile time row arguments
4054template< typename VT > // Type of the right-hand side dense vector
4055inline void Row<MT,false,true,false,CRAs...>::multAssign( const DenseVector<VT,true>& rhs )
4056{
4057 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4058
4059 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
4060 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
4061
4062 for( size_t j=0UL; j<jpos; j+=2UL ) {
4063 matrix_(row(),j ) *= (*rhs)[j ];
4064 matrix_(row(),j+1UL) *= (*rhs)[j+1UL];
4065 }
4066 if( jpos < (*rhs).size() )
4067 matrix_(row(),jpos) *= (*rhs)[jpos];
4068}
4070//*************************************************************************************************
4071
4072
4073//*************************************************************************************************
4085template< typename MT // Type of the dense matrix
4086 , size_t... CRAs > // Compile time row arguments
4087template< typename VT > // Type of the right-hand side sparse vector
4088inline void Row<MT,false,true,false,CRAs...>::multAssign( const SparseVector<VT,true>& rhs )
4089{
4090 using blaze::reset;
4091
4092 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4093
4094 size_t j( 0UL );
4095
4096 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
4097 const size_t index( element->index() );
4098 for( ; j<index; ++j )
4099 reset( matrix_(row(),j) );
4100 matrix_(row(),j) *= element->value();
4101 ++j;
4102 }
4103
4104 for( ; j<size(); ++j ) {
4105 reset( matrix_(row(),j) );
4106 }
4107}
4109//*************************************************************************************************
4110
4111
4112//*************************************************************************************************
4124template< typename MT // Type of the dense matrix
4125 , size_t... CRAs > // Compile time row arguments
4126template< typename VT > // Type of the right-hand side dense vector
4127inline void Row<MT,false,true,false,CRAs...>::divAssign( const DenseVector<VT,true>& rhs )
4128{
4129 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4130
4131 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
4132 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
4133
4134 for( size_t j=0UL; j<jpos; j+=2UL ) {
4135 matrix_(row(),j ) /= (*rhs)[j ];
4136 matrix_(row(),j+1UL) /= (*rhs)[j+1UL];
4137 }
4138 if( jpos < (*rhs).size() )
4139 matrix_(row(),jpos) /= (*rhs)[jpos];
4140}
4142//*************************************************************************************************
4143
4144
4145
4146
4147
4148
4149
4150
4151//=================================================================================================
4152//
4153// CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC COLUMN-MAJOR DENSE MATRICES
4154//
4155//=================================================================================================
4156
4157//*************************************************************************************************
4165template< typename MT // Type of the dense matrix
4166 , size_t... CRAs > // Compile time row arguments
4167class Row<MT,false,true,true,CRAs...>
4168 : public View< DenseVector< Row<MT,false,true,true,CRAs...>, true > >
4169 , private RowData<CRAs...>
4170{
4171 private:
4172 //**Type definitions****************************************************************************
4173 using DataType = RowData<CRAs...>;
4174 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
4175 //**********************************************************************************************
4176
4177 public:
4178 //**Type definitions****************************************************************************
4180 using This = Row<MT,false,true,true,CRAs...>;
4181
4183 using BaseType = View< DenseVector<This,true> >;
4184
4185 using ViewedType = MT;
4186 using ResultType = RowTrait_t<MT,CRAs...>;
4187 using TransposeType = TransposeType_t<ResultType>;
4188 using ElementType = ElementType_t<MT>;
4189 using SIMDType = SIMDTrait_t<ElementType>;
4190 using ReturnType = ElementType_t<MT>;
4191 using CompositeType = const Row&;
4192
4194 using ConstReference = ConstReference_t<MT>;
4195
4197 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
4198
4200 using ConstPointer = ConstPointer_t<MT>;
4201
4203 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
4204
4206 using ConstIterator = ConstIterator_t<MT>;
4207
4209 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
4210 //**********************************************************************************************
4211
4212 //**Compilation flags***************************************************************************
4214 static constexpr bool simdEnabled = MT::simdEnabled;
4215
4217 static constexpr bool smpAssignable = MT::smpAssignable;
4218
4220 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4221 //**********************************************************************************************
4222
4223 //**Constructors********************************************************************************
4226 template< typename... RRAs >
4227 explicit inline Row( MT& matrix, RRAs... args );
4228
4229 Row( const Row& ) = default;
4231 //**********************************************************************************************
4232
4233 //**Destructor**********************************************************************************
4236 ~Row() = default;
4238 //**********************************************************************************************
4239
4240 //**Data access functions***********************************************************************
4243 inline Reference operator[]( size_t index );
4244 inline ConstReference operator[]( size_t index ) const;
4245 inline Reference at( size_t index );
4246 inline ConstReference at( size_t index ) const;
4247 inline Pointer data () noexcept;
4248 inline ConstPointer data () const noexcept;
4249 inline Iterator begin ();
4250 inline ConstIterator begin () const;
4251 inline ConstIterator cbegin() const;
4252 inline Iterator end ();
4253 inline ConstIterator end () const;
4254 inline ConstIterator cend () const;
4256 //**********************************************************************************************
4257
4258 //**Assignment operators************************************************************************
4261 inline Row& operator=( const ElementType& rhs );
4262 inline Row& operator=( initializer_list<ElementType> list );
4263 inline Row& operator=( const Row& rhs );
4264
4265 template< typename VT > inline Row& operator= ( const Vector<VT,true>& rhs );
4266 template< typename VT > inline Row& operator+=( const Vector<VT,true>& rhs );
4267 template< typename VT > inline Row& operator-=( const Vector<VT,true>& rhs );
4268 template< typename VT > inline Row& operator*=( const Vector<VT,true>& rhs );
4269 template< typename VT > inline Row& operator/=( const DenseVector<VT,true>& rhs );
4270 template< typename VT > inline Row& operator%=( const Vector<VT,true>& rhs );
4272 //**********************************************************************************************
4273
4274 //**Utility functions***************************************************************************
4277 using DataType::row;
4278
4279 inline MT& operand() noexcept;
4280 inline const MT& operand() const noexcept;
4281
4282 inline size_t size() const noexcept;
4283 inline size_t spacing() const noexcept;
4284 inline size_t capacity() const noexcept;
4285 inline size_t nonZeros() const;
4286 inline void reset();
4288 //**********************************************************************************************
4289
4290 //**Numeric functions***************************************************************************
4293 template< typename Other > inline Row& scale( const Other& scalar );
4295 //**********************************************************************************************
4296
4297 private:
4298 //**********************************************************************************************
4300 template< typename VT >
4301 static constexpr bool VectorizedAssign_v =
4302 ( useOptimizedKernels &&
4303 simdEnabled && VT::simdEnabled &&
4304 IsSIMDCombinable_v< ElementType, ElementType_t<VT> > );
4305 //**********************************************************************************************
4306
4307 //**********************************************************************************************
4309 template< typename VT >
4310 static constexpr bool VectorizedAddAssign_v =
4311 ( VectorizedAssign_v<VT> &&
4312 HasSIMDAdd_v< ElementType, ElementType_t<VT> > );
4313 //**********************************************************************************************
4314
4315 //**********************************************************************************************
4317 template< typename VT >
4318 static constexpr bool VectorizedSubAssign_v =
4319 ( VectorizedAssign_v<VT> &&
4320 HasSIMDSub_v< ElementType, ElementType_t<VT> > );
4321 //**********************************************************************************************
4322
4323 //**********************************************************************************************
4325 template< typename VT >
4326 static constexpr bool VectorizedMultAssign_v =
4327 ( VectorizedAssign_v<VT> &&
4328 HasSIMDMult_v< ElementType, ElementType_t<VT> > );
4329 //**********************************************************************************************
4330
4331 //**********************************************************************************************
4333 template< typename VT >
4334 static constexpr bool VectorizedDivAssign_v =
4335 ( VectorizedAssign_v<VT> &&
4336 HasSIMDDiv_v< ElementType, ElementType_t<VT> > );
4337 //**********************************************************************************************
4338
4339 //**SIMD properties*****************************************************************************
4341 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
4342 //**********************************************************************************************
4343
4344 public:
4345 //**Expression template evaluation functions****************************************************
4348 template< typename Other >
4349 inline bool canAlias( const Other* alias ) const noexcept;
4350
4351 template< typename MT2, bool SO2, bool SF2, size_t... CRAs2 >
4352 inline bool canAlias( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
4353
4354 template< typename Other >
4355 inline bool isAliased( const Other* alias ) const noexcept;
4356
4357 template< typename MT2, bool SO2, bool SF2, size_t... CRAs2 >
4358 inline bool isAliased( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept;
4359
4360 inline bool isAligned () const noexcept;
4361 inline bool canSMPAssign() const noexcept;
4362
4363 BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4364 BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4365 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4366
4367 BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4368 BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4369 BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4370 BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4371
4372 template< typename VT >
4373 inline auto assign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
4374
4375 template< typename VT >
4376 inline auto assign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
4377
4378 template< typename VT > inline void assign( const SparseVector<VT,true>& rhs );
4379
4380 template< typename VT >
4381 inline auto addAssign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
4382
4383 template< typename VT >
4384 inline auto addAssign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
4385
4386 template< typename VT > inline void addAssign( const SparseVector<VT,true>& rhs );
4387
4388 template< typename VT >
4389 inline auto subAssign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
4390
4391 template< typename VT >
4392 inline auto subAssign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
4393
4394 template< typename VT > inline void subAssign( const SparseVector<VT,true>& rhs );
4395
4396 template< typename VT >
4397 inline auto multAssign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
4398
4399 template< typename VT >
4400 inline auto multAssign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
4401
4402 template< typename VT > inline void multAssign( const SparseVector<VT,true>& rhs );
4403
4404 template< typename VT >
4405 inline auto divAssign( const DenseVector<VT,true>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
4406
4407 template< typename VT >
4408 inline auto divAssign( const DenseVector<VT,true>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT> >;
4410 //**********************************************************************************************
4411
4412 private:
4413 //**Member variables****************************************************************************
4416 Operand matrix_;
4418 //**********************************************************************************************
4419
4420 //**Friend declarations*************************************************************************
4421 template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CRAs2 > friend class Row;
4422 //**********************************************************************************************
4423
4424 //**Compile time checks*************************************************************************
4433 //**********************************************************************************************
4434};
4436//*************************************************************************************************
4437
4438
4439
4440
4441//=================================================================================================
4442//
4443// CONSTRUCTORS
4444//
4445//=================================================================================================
4446
4447//*************************************************************************************************
4460template< typename MT // Type of the dense matrix
4461 , size_t... CRAs > // Compile time row arguments
4462template< typename... RRAs > // Runtime row arguments
4463inline Row<MT,false,true,true,CRAs...>::Row( MT& matrix, RRAs... args )
4464 : DataType( args... ) // Base class initialization
4465 , matrix_ ( matrix ) // The matrix containing the row
4466{
4467 if( isChecked( args... ) ) {
4468 if( matrix_.rows() <= row() ) {
4469 BLAZE_THROW_INVALID_ARGUMENT( "Invalid row access index" );
4470 }
4471 }
4472 else {
4473 BLAZE_USER_ASSERT( row() < matrix_.rows(), "Invalid row access index" );
4474 }
4475}
4477//*************************************************************************************************
4478
4479
4480
4481
4482//=================================================================================================
4483//
4484// DATA ACCESS FUNCTIONS
4485//
4486//=================================================================================================
4487
4488//*************************************************************************************************
4498template< typename MT // Type of the dense matrix
4499 , size_t... CRAs > // Compile time row arguments
4500inline typename Row<MT,false,true,true,CRAs...>::Reference
4501 Row<MT,false,true,true,CRAs...>::operator[]( size_t index )
4502{
4503 BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4504 return matrix_(index,row());
4505}
4507//*************************************************************************************************
4508
4509
4510//*************************************************************************************************
4520template< typename MT // Type of the dense matrix
4521 , size_t... CRAs > // Compile time row arguments
4522inline typename Row<MT,false,true,true,CRAs...>::ConstReference
4523 Row<MT,false,true,true,CRAs...>::operator[]( size_t index ) const
4524{
4525 BLAZE_USER_ASSERT( index < size(), "Invalid row access index" );
4526 return const_cast<const MT&>( matrix_ )(index,row());
4527}
4529//*************************************************************************************************
4530
4531
4532//*************************************************************************************************
4543template< typename MT // Type of the dense matrix
4544 , size_t... CRAs > // Compile time row arguments
4545inline typename Row<MT,false,true,true,CRAs...>::Reference
4546 Row<MT,false,true,true,CRAs...>::at( size_t index )
4547{
4548 if( index >= size() ) {
4549 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4550 }
4551 return (*this)[index];
4552}
4554//*************************************************************************************************
4555
4556
4557//*************************************************************************************************
4568template< typename MT // Type of the dense matrix
4569 , size_t... CRAs > // Compile time row arguments
4570inline typename Row<MT,false,true,true,CRAs...>::ConstReference
4571 Row<MT,false,true,true,CRAs...>::at( size_t index ) const
4572{
4573 if( index >= size() ) {
4574 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
4575 }
4576 return (*this)[index];
4577}
4579//*************************************************************************************************
4580
4581
4582//*************************************************************************************************
4591template< typename MT // Type of the dense matrix
4592 , size_t... CRAs > // Compile time row arguments
4593inline typename Row<MT,false,true,true,CRAs...>::Pointer
4595{
4596 return matrix_.data( row() );
4597}
4599//*************************************************************************************************
4600
4601
4602//*************************************************************************************************
4611template< typename MT // Type of the dense matrix
4612 , size_t... CRAs > // Compile time row arguments
4613inline typename Row<MT,false,true,true,CRAs...>::ConstPointer
4615{
4616 return matrix_.data( row() );
4617}
4619//*************************************************************************************************
4620
4621
4622//*************************************************************************************************
4630template< typename MT // Type of the dense matrix
4631 , size_t... CRAs > // Compile time row arguments
4632inline typename Row<MT,false,true,true,CRAs...>::Iterator
4634{
4635 return matrix_.begin( row() );
4636}
4638//*************************************************************************************************
4639
4640
4641//*************************************************************************************************
4649template< typename MT // Type of the dense matrix
4650 , size_t... CRAs > // Compile time row arguments
4651inline typename Row<MT,false,true,true,CRAs...>::ConstIterator
4653{
4654 return matrix_.cbegin( row() );
4655}
4657//*************************************************************************************************
4658
4659
4660//*************************************************************************************************
4668template< typename MT // Type of the dense matrix
4669 , size_t... CRAs > // Compile time row arguments
4670inline typename Row<MT,false,true,true,CRAs...>::ConstIterator
4672{
4673 return matrix_.cbegin( row() );
4674}
4676//*************************************************************************************************
4677
4678
4679//*************************************************************************************************
4687template< typename MT // Type of the dense matrix
4688 , size_t... CRAs > // Compile time row arguments
4689inline typename Row<MT,false,true,true,CRAs...>::Iterator
4691{
4692 return matrix_.end( row() );
4693}
4695//*************************************************************************************************
4696
4697
4698//*************************************************************************************************
4706template< typename MT // Type of the dense matrix
4707 , size_t... CRAs > // Compile time row arguments
4708inline typename Row<MT,false,true,true,CRAs...>::ConstIterator
4710{
4711 return matrix_.cend( row() );
4712}
4714//*************************************************************************************************
4715
4716
4717//*************************************************************************************************
4725template< typename MT // Type of the dense matrix
4726 , size_t... CRAs > // Compile time row arguments
4727inline typename Row<MT,false,true,true,CRAs...>::ConstIterator
4729{
4730 return matrix_.cend( row() );
4731}
4733//*************************************************************************************************
4734
4735
4736
4737
4738//=================================================================================================
4739//
4740// ASSIGNMENT OPERATORS
4741//
4742//=================================================================================================
4743
4744//*************************************************************************************************
4751template< typename MT // Type of the dense matrix
4752 , size_t... CRAs > // Compile time row arguments
4753inline Row<MT,false,true,true,CRAs...>&
4754 Row<MT,false,true,true,CRAs...>::operator=( const ElementType& rhs )
4755{
4756 decltype(auto) left( derestrict( matrix_ ) );
4757
4758 const size_t ibegin( ( IsLower_v<MT> )
4759 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
4760 ?( row()+1UL )
4761 :( row() ) )
4762 :( 0UL ) );
4763 const size_t iend ( ( IsUpper_v<MT> )
4764 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
4765 ?( row() )
4766 :( row()+1UL ) )
4767 :( size() ) );
4768
4769 for( size_t i=ibegin; i<iend; ++i ) {
4770 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, row(), rhs ) )
4771 left(i,row()) = rhs;
4772 }
4773
4774 return *this;
4775}
4777//*************************************************************************************************
4778
4779
4780//*************************************************************************************************
4795template< typename MT // Type of the dense matrix
4796 , size_t... CRAs > // Compile time row arguments
4797inline Row<MT,false,true,true,CRAs...>&
4798 Row<MT,false,true,true,CRAs...>::operator=( initializer_list<ElementType> list )
4799{
4800 if( list.size() > size() ) {
4801 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to row" );
4802 }
4803
4804 if( IsRestricted_v<MT> ) {
4805 const InitializerVector<ElementType,true> tmp( list, size() );
4806 if( !tryAssign( matrix_, tmp, row(), 0UL ) ) {
4807 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4808 }
4809 }
4810
4811 decltype(auto) left( derestrict( *this ) );
4812
4813 std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
4814
4815 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4816
4817 return *this;
4818}
4820//*************************************************************************************************
4821
4822
4823//*************************************************************************************************
4837template< typename MT // Type of the dense matrix
4838 , size_t... CRAs > // Compile time row arguments
4839inline Row<MT,false,true,true,CRAs...>&
4840 Row<MT,false,true,true,CRAs...>::operator=( const Row& rhs )
4841{
4842 if( &rhs == this ) return *this;
4843
4844 if( size() != rhs.size() ) {
4845 BLAZE_THROW_INVALID_ARGUMENT( "Row sizes do not match" );
4846 }
4847
4848 if( !tryAssign( matrix_, rhs, row(), 0UL ) ) {
4849 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4850 }
4851
4852 decltype(auto) left( derestrict( *this ) );
4853
4854 if( IsExpression_v<MT> && rhs.canAlias( this ) ) {
4855 const ResultType tmp( rhs );
4856 smpAssign( left, tmp );
4857 }
4858 else {
4859 smpAssign( left, rhs );
4860 }
4861
4862 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4863
4864 return *this;
4865}
4867//*************************************************************************************************
4868
4869
4870//*************************************************************************************************
4884template< typename MT // Type of the dense matrix
4885 , size_t... CRAs > // Compile time row arguments
4886template< typename VT > // Type of the right-hand side vector
4887inline Row<MT,false,true,true,CRAs...>&
4888 Row<MT,false,true,true,CRAs...>::operator=( const Vector<VT,true>& rhs )
4889{
4890 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
4892
4893 if( size() != (*rhs).size() ) {
4894 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4895 }
4896
4897 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
4898 Right right( *rhs );
4899
4900 if( !tryAssign( matrix_, right, row(), 0UL ) ) {
4901 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4902 }
4903
4904 decltype(auto) left( derestrict( *this ) );
4905
4906 if( IsReference_v<Right> && right.canAlias( this ) ) {
4907 const ResultType_t<VT> tmp( right );
4908 smpAssign( left, tmp );
4909 }
4910 else {
4911 if( IsSparseVector_v<VT> )
4912 reset();
4913 smpAssign( left, right );
4914 }
4915
4916 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4917
4918 return *this;
4919}
4921//*************************************************************************************************
4922
4923
4924//*************************************************************************************************
4938template< typename MT // Type of the dense matrix
4939 , size_t... CRAs > // Compile time row arguments
4940template< typename VT > // Type of the right-hand side vector
4941inline Row<MT,false,true,true,CRAs...>&
4942 Row<MT,false,true,true,CRAs...>::operator+=( const Vector<VT,true>& rhs )
4943{
4944 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
4946
4947 if( size() != (*rhs).size() ) {
4948 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4949 }
4950
4951 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
4952 Right right( *rhs );
4953
4954 if( !tryAddAssign( matrix_, right, row(), 0UL ) ) {
4955 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4956 }
4957
4958 decltype(auto) left( derestrict( *this ) );
4959
4960 if( IsReference_v<Right> && right.canAlias( this ) ) {
4961 const ResultType_t<VT> tmp( right );
4962 smpAddAssign( left, tmp );
4963 }
4964 else {
4965 smpAddAssign( left, right );
4966 }
4967
4968 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4969
4970 return *this;
4971}
4973//*************************************************************************************************
4974
4975
4976//*************************************************************************************************
4990template< typename MT // Type of the dense matrix
4991 , size_t... CRAs > // Compile time row arguments
4992template< typename VT > // Type of the right-hand side vector
4993inline Row<MT,false,true,true,CRAs...>&
4994 Row<MT,false,true,true,CRAs...>::operator-=( const Vector<VT,true>& rhs )
4995{
4996 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
4998
4999 if( size() != (*rhs).size() ) {
5000 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5001 }
5002
5003 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
5004 Right right( *rhs );
5005
5006 if( !trySubAssign( matrix_, right, row(), 0UL ) ) {
5007 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5008 }
5009
5010 decltype(auto) left( derestrict( *this ) );
5011
5012 if( IsReference_v<Right> && right.canAlias( this ) ) {
5013 const ResultType_t<VT> tmp( right );
5014 smpSubAssign( left, tmp );
5015 }
5016 else {
5017 smpSubAssign( left, right );
5018 }
5019
5020 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5021
5022 return *this;
5023}
5025//*************************************************************************************************
5026
5027
5028//*************************************************************************************************
5041template< typename MT // Type of the dense matrix
5042 , size_t... CRAs > // Compile time row arguments
5043template< typename VT > // Type of the right-hand side vector
5044inline Row<MT,false,true,true,CRAs...>&
5045 Row<MT,false,true,true,CRAs...>::operator*=( const Vector<VT,true>& rhs )
5046{
5047 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
5049
5050 if( size() != (*rhs).size() ) {
5051 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5052 }
5053
5054 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
5055 Right right( *rhs );
5056
5057 if( !tryMultAssign( matrix_, right, row(), 0UL ) ) {
5058 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5059 }
5060
5061 decltype(auto) left( derestrict( *this ) );
5062
5063 if( IsReference_v<Right> && right.canAlias( this ) ) {
5064 const ResultType_t<VT> tmp( right );
5065 smpMultAssign( left, tmp );
5066 }
5067 else {
5068 smpMultAssign( left, right );
5069 }
5070
5071 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5072
5073 return *this;
5074}
5076//*************************************************************************************************
5077
5078
5079//*************************************************************************************************
5091template< typename MT // Type of the dense matrix
5092 , size_t... CRAs > // Compile time row arguments
5093template< typename VT > // Type of the right-hand side dense vector
5094inline Row<MT,false,true,true,CRAs...>&
5095 Row<MT,false,true,true,CRAs...>::operator/=( const DenseVector<VT,true>& rhs )
5096{
5097 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
5099
5100 if( size() != (*rhs).size() ) {
5101 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5102 }
5103
5104 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
5105 Right right( *rhs );
5106
5107 if( !tryDivAssign( matrix_, right, row(), 0UL ) ) {
5108 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5109 }
5110
5111 decltype(auto) left( derestrict( *this ) );
5112
5113 if( IsReference_v<Right> && right.canAlias( this ) ) {
5114 const ResultType_t<VT> tmp( right );
5115 smpDivAssign( left, tmp );
5116 }
5117 else {
5118 smpDivAssign( left, right );
5119 }
5120
5121 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5122
5123 return *this;
5124}
5126//*************************************************************************************************
5127
5128
5129//*************************************************************************************************
5142template< typename MT // Type of the dense matrix
5143 , size_t... CRAs > // Compile time row arguments
5144template< typename VT > // Type of the right-hand side vector
5145inline Row<MT,false,true,true,CRAs...>&
5146 Row<MT,false,true,true,CRAs...>::operator%=( const Vector<VT,true>& rhs )
5147{
5148 using blaze::assign;
5149
5150 BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE ( ResultType_t<VT> );
5152
5153 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
5154
5158
5159 if( size() != 3UL || (*rhs).size() != 3UL ) {
5160 BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
5161 }
5162
5163 const CrossType right( *this % (*rhs) );
5164
5165 if( !tryAssign( matrix_, right, row(), 0UL ) ) {
5166 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5167 }
5168
5169 decltype(auto) left( derestrict( *this ) );
5170
5171 assign( left, right );
5172
5173 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5174
5175 return *this;
5176}
5178//*************************************************************************************************
5179
5180
5181
5182
5183//=================================================================================================
5184//
5185// UTILITY FUNCTIONS
5186//
5187//=================================================================================================
5188
5189//*************************************************************************************************
5195template< typename MT // Type of the dense matrix
5196 , size_t... CRAs > // Compile time row arguments
5197inline MT& Row<MT,false,true,true,CRAs...>::operand() noexcept
5198{
5199 return matrix_;
5200}
5202//*************************************************************************************************
5203
5204
5205//*************************************************************************************************
5211template< typename MT // Type of the dense matrix
5212 , size_t... CRAs > // Compile time row arguments
5213inline const MT& Row<MT,false,true,true,CRAs...>::operand() const noexcept
5214{
5215 return matrix_;
5216}
5218//*************************************************************************************************
5219
5220
5221//*************************************************************************************************
5227template< typename MT // Type of the dense matrix
5228 , size_t... CRAs > // Compile time row arguments
5229inline size_t Row<MT,false,true,true,CRAs...>::size() const noexcept
5230{
5231 return matrix_.columns();
5232}
5234//*************************************************************************************************
5235
5236
5237//*************************************************************************************************
5246template< typename MT // Type of the dense matrix
5247 , size_t... CRAs > // Compile time row arguments
5248inline size_t Row<MT,false,true,true,CRAs...>::spacing() const noexcept
5249{
5250 return matrix_.spacing();
5251}
5253//*************************************************************************************************
5254
5255
5256//*************************************************************************************************
5262template< typename MT // Type of the dense matrix
5263 , size_t... CRAs > // Compile time row arguments
5264inline size_t Row<MT,false,true,true,CRAs...>::capacity() const noexcept
5265{
5266 return matrix_.capacity( row() );
5267}
5269//*************************************************************************************************
5270
5271
5272//*************************************************************************************************
5281template< typename MT // Type of the dense matrix
5282 , size_t... CRAs > // Compile time row arguments
5284{
5285 return matrix_.nonZeros( row() );
5286}
5288//*************************************************************************************************
5289
5290
5291//*************************************************************************************************
5297template< typename MT // Type of the dense matrix
5298 , size_t... CRAs > // Compile time row arguments
5300{
5301 matrix_.reset( row() );
5302}
5304//*************************************************************************************************
5305
5306
5307
5308
5309//=================================================================================================
5310//
5311// NUMERIC FUNCTIONS
5312//
5313//=================================================================================================
5314
5315//*************************************************************************************************
5328template< typename MT // Type of the dense matrix
5329 , size_t... CRAs > // Compile time row arguments
5330template< typename Other > // Data type of the scalar value
5331inline Row<MT,false,true,true,CRAs...>&
5332 Row<MT,false,true,true,CRAs...>::scale( const Other& scalar )
5333{
5335
5336 const size_t ibegin( ( IsLower_v<MT> )
5337 ?( ( IsStrictlyLower_v<MT> )
5338 ?( row()+1UL )
5339 :( row() ) )
5340 :( 0UL ) );
5341 const size_t iend ( ( IsUpper_v<MT> )
5342 ?( ( IsStrictlyUpper_v<MT> )
5343 ?( row() )
5344 :( row()+1UL ) )
5345 :( size() ) );
5346
5347 for( size_t i=ibegin; i<iend; ++i ) {
5348 matrix_(i,row()) *= scalar;
5349 }
5350
5351 return *this;
5352}
5354//*************************************************************************************************
5355
5356
5357
5358
5359//=================================================================================================
5360//
5361// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5362//
5363//=================================================================================================
5364
5365//*************************************************************************************************
5376template< typename MT // Type of the dense matrix
5377 , size_t... CRAs > // Compile time row arguments
5378template< typename Other > // Data type of the foreign expression
5379inline bool Row<MT,false,true,true,CRAs...>::canAlias( const Other* alias ) const noexcept
5380{
5381 return matrix_.isAliased( &unview( *alias ) );
5382}
5384//*************************************************************************************************
5385
5386
5387//*************************************************************************************************
5398template< typename MT // Type of the dense matrix
5399 , size_t... CRAs > // Compile time row arguments
5400template< typename MT2 // Data type of the foreign dense row
5401 , bool SO2 // Storage order of the foreign dense row
5402 , bool SF2 // Symmetry flag of the foreign dense row
5403 , size_t... CRAs2 > // Compile time row arguments of the foreign dense row
5404inline bool
5405 Row<MT,false,true,true,CRAs...>::canAlias( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
5406{
5407 return matrix_.isAliased( &alias->matrix_ ) && ( row() == alias->row() );
5408}
5410//*************************************************************************************************
5411
5412
5413//*************************************************************************************************
5424template< typename MT // Type of the dense matrix
5425 , size_t... CRAs > // Compile time row arguments
5426template< typename Other > // Data type of the foreign expression
5427inline bool Row<MT,false,true,true,CRAs...>::isAliased( const Other* alias ) const noexcept
5428{
5429 return matrix_.isAliased( &unview( *alias ) );
5430}
5432//*************************************************************************************************
5433
5434
5435//*************************************************************************************************
5446template< typename MT // Type of the dense matrix
5447 , size_t... CRAs > // Compile time row arguments
5448template< typename MT2 // Data type of the foreign dense row
5449 , bool SO2 // Storage order of the foreign dense row
5450 , bool SF2 // Symmetry flag of the foreign dense row
5451 , size_t... CRAs2 > // Compile time row arguments of the foreign dense row
5452inline bool
5453 Row<MT,false,true,true,CRAs...>::isAliased( const Row<MT2,SO2,true,SF2,CRAs2...>* alias ) const noexcept
5454{
5455 return matrix_.isAliased( &alias->matrix_ ) && ( row() == alias->row() );
5456}
5458//*************************************************************************************************
5459
5460
5461//*************************************************************************************************
5471template< typename MT // Type of the dense matrix
5472 , size_t... CRAs > // Compile time row arguments
5473inline bool Row<MT,false,true,true,CRAs...>::isAligned() const noexcept
5474{
5475 return matrix_.isAligned();
5476}
5478//*************************************************************************************************
5479
5480
5481//*************************************************************************************************
5492template< typename MT // Type of the dense matrix
5493 , size_t... CRAs > // Compile time row arguments
5494inline bool Row<MT,false,true,true,CRAs...>::canSMPAssign() const noexcept
5495{
5496 return ( size() > SMP_DVECASSIGN_THRESHOLD );
5497}
5499//*************************************************************************************************
5500
5501
5502//*************************************************************************************************
5515template< typename MT // Type of the dense matrix
5516 , size_t... CRAs > // Compile time row arguments
5517BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true,CRAs...>::SIMDType
5518 Row<MT,false,true,true,CRAs...>::load( size_t index ) const noexcept
5519{
5520 return matrix_.load( index, row() );
5521}
5523//*************************************************************************************************
5524
5525
5526//*************************************************************************************************
5539template< typename MT // Type of the dense matrix
5540 , size_t... CRAs > // Compile time row arguments
5541BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true,CRAs...>::SIMDType
5542 Row<MT,false,true,true,CRAs...>::loada( size_t index ) const noexcept
5543{
5544 return matrix_.loada( index, row() );
5545}
5547//*************************************************************************************************
5548
5549
5550//*************************************************************************************************
5563template< typename MT // Type of the dense matrix
5564 , size_t... CRAs > // Compile time row arguments
5565BLAZE_ALWAYS_INLINE typename Row<MT,false,true,true,CRAs...>::SIMDType
5566 Row<MT,false,true,true,CRAs...>::loadu( size_t index ) const noexcept
5567{
5568 return matrix_.loadu( index, row() );
5569}
5571//*************************************************************************************************
5572
5573
5574//*************************************************************************************************
5588template< typename MT // Type of the dense matrix
5589 , size_t... CRAs > // Compile time row arguments
5591 Row<MT,false,true,true,CRAs...>::store( size_t index, const SIMDType& value ) noexcept
5592{
5593 matrix_.store( index, row(), value );
5594}
5596//*************************************************************************************************
5597
5598
5599//*************************************************************************************************
5613template< typename MT // Type of the dense matrix
5614 , size_t... CRAs > // Compile time row arguments
5616 Row<MT,false,true,true,CRAs...>::storea( size_t index, const SIMDType& value ) noexcept
5617{
5618 matrix_.storea( index, row(), value );
5619}
5621//*************************************************************************************************
5622
5623
5624//*************************************************************************************************
5638template< typename MT // Type of the dense matrix
5639 , size_t... CRAs > // Compile time row arguments
5641 Row<MT,false,true,true,CRAs...>::storeu( size_t index, const SIMDType& value ) noexcept
5642{
5643 matrix_.storeu( index, row(), value );
5644}
5646//*************************************************************************************************
5647
5648
5649//*************************************************************************************************
5663template< typename MT // Type of the dense matrix
5664 , size_t... CRAs > // Compile time row arguments
5666 Row<MT,false,true,true,CRAs...>::stream( size_t index, const SIMDType& value ) noexcept
5667{
5668 matrix_.stream( index, row(), value );
5669}
5671//*************************************************************************************************
5672
5673
5674//*************************************************************************************************
5686template< typename MT // Type of the dense matrix
5687 , size_t... CRAs > // Compile time row arguments
5688template< typename VT > // Type of the right-hand side dense vector
5689inline auto Row<MT,false,true,true,CRAs...>::assign( const DenseVector<VT,true>& rhs )
5690 -> DisableIf_t< VectorizedAssign_v<VT> >
5691{
5692 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5693
5694 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
5695 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
5696
5697 for( size_t i=0UL; i<ipos; i+=2UL ) {
5698 matrix_(i ,row()) = (*rhs)[i ];
5699 matrix_(i+1UL,row()) = (*rhs)[i+1UL];
5700 }
5701 if( ipos < (*rhs).size() )
5702 matrix_(ipos,row()) = (*rhs)[ipos];
5703}
5705//*************************************************************************************************
5706
5707
5708//*************************************************************************************************
5720template< typename MT // Type of the dense matrix
5721 , size_t... CRAs > // Compile time row arguments
5722template< typename VT > // Type of the right-hand side dense vector
5723inline auto Row<MT,false,true,true,CRAs...>::assign( const DenseVector<VT,true>& rhs )
5724 -> EnableIf_t< VectorizedAssign_v<VT> >
5725{
5727
5728 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5729
5730 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5731
5732 const size_t rows( size() );
5733
5734 const size_t ipos( remainder ? prevMultiple( rows, SIMDSIZE ) : rows );
5735 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
5736
5737 size_t i( 0UL );
5738 Iterator left( begin() );
5739 ConstIterator_t<VT> right( (*rhs).begin() );
5740
5741 if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(*rhs).isAliased( this ) )
5742 {
5743 for( ; i<ipos; i+=SIMDSIZE ) {
5744 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5745 }
5746 for( ; remainder && i<rows; ++i ) {
5747 *left = *right; ++left; ++right;
5748 }
5749 }
5750 else
5751 {
5752 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5753 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5754 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5755 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5756 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5757 }
5758 for( ; i<ipos; i+=SIMDSIZE ) {
5759 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5760 }
5761 for( ; remainder && i<rows; ++i ) {
5762 *left = *right; ++left; ++right;
5763 }
5764 }
5765}
5767//*************************************************************************************************
5768
5769
5770//*************************************************************************************************
5782template< typename MT // Type of the dense matrix
5783 , size_t... CRAs > // Compile time row arguments
5784template< typename VT > // Type of the right-hand side sparse vector
5785inline void Row<MT,false,true,true,CRAs...>::assign( const SparseVector<VT,true>& rhs )
5786{
5787 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5788
5789 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
5790 matrix_(element->index(),row()) = element->value();
5791}
5793//*************************************************************************************************
5794
5795
5796//*************************************************************************************************
5808template< typename MT // Type of the dense matrix
5809 , size_t... CRAs > // Compile time row arguments
5810template< typename VT > // Type of the right-hand side dense vector
5811inline auto Row<MT,false,true,true,CRAs...>::addAssign( const DenseVector<VT,true>& rhs )
5812 -> DisableIf_t< VectorizedAddAssign_v<VT> >
5813{
5814 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5815
5816 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
5817 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
5818
5819 for( size_t i=0UL; i<ipos; i+=2UL ) {
5820 matrix_(i ,row()) += (*rhs)[i ];
5821 matrix_(i+1UL,row()) += (*rhs)[i+1UL];
5822 }
5823 if( ipos < (*rhs).size() )
5824 matrix_(ipos,row()) += (*rhs)[ipos];
5825}
5827//*************************************************************************************************
5828
5829
5830//*************************************************************************************************
5842template< typename MT // Type of the dense matrix
5843 , size_t... CRAs > // Compile time row arguments
5844template< typename VT > // Type of the right-hand side dense vector
5845inline auto Row<MT,false,true,true,CRAs...>::addAssign( const DenseVector<VT,true>& rhs )
5846 -> EnableIf_t< VectorizedAddAssign_v<VT> >
5847{
5849
5850 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5851
5852 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5853
5854 const size_t rows( size() );
5855
5856 const size_t ipos( remainder ? prevMultiple( rows, SIMDSIZE ) : rows );
5857 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
5858
5859 size_t i( 0UL );
5860 Iterator left( begin() );
5861 ConstIterator_t<VT> right( (*rhs).begin() );
5862
5863 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5864 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5865 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5866 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5867 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5868 }
5869 for( ; i<ipos; i+=SIMDSIZE ) {
5870 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5871 }
5872 for( ; remainder && i<rows; ++i ) {
5873 *left += *right; ++left; ++right;
5874 }
5875}
5877//*************************************************************************************************
5878
5879
5880//*************************************************************************************************
5892template< typename MT // Type of the dense matrix
5893 , size_t... CRAs > // Compile time row arguments
5894template< typename VT > // Type of the right-hand side sparse vector
5895inline void Row<MT,false,true,true,CRAs...>::addAssign( const SparseVector<VT,true>& rhs )
5896{
5897 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5898
5899 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
5900 matrix_(element->index(),row()) += element->value();
5901}
5903//*************************************************************************************************
5904
5905
5906//*************************************************************************************************
5918template< typename MT // Type of the dense matrix
5919 , size_t... CRAs > // Compile time row arguments
5920template< typename VT > // Type of the right-hand side dense vector
5921inline auto Row<MT,false,true,true,CRAs...>::subAssign( const DenseVector<VT,true>& rhs )
5922 -> DisableIf_t< VectorizedSubAssign_v<VT> >
5923{
5924 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5925
5926 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
5927 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
5928
5929 for( size_t i=0UL; i<ipos; i+=2UL ) {
5930 matrix_(i ,row()) -= (*rhs)[i ];
5931 matrix_(i+1UL,row()) -= (*rhs)[i+1UL];
5932 }
5933 if( ipos < (*rhs).size() )
5934 matrix_(ipos,row()) -= (*rhs)[ipos];
5935}
5937//*************************************************************************************************
5938
5939
5940//*************************************************************************************************
5952template< typename MT // Type of the dense matrix
5953 , size_t... CRAs > // Compile time row arguments
5954template< typename VT > // Type of the right-hand side dense vector
5955inline auto Row<MT,false,true,true,CRAs...>::subAssign( const DenseVector<VT,true>& rhs )
5956 -> EnableIf_t< VectorizedSubAssign_v<VT> >
5957{
5959
5960 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5961
5962 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5963
5964 const size_t rows( size() );
5965
5966 const size_t ipos( remainder ? prevMultiple( rows, SIMDSIZE ) : rows );
5967 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
5968
5969 size_t i( 0UL );
5970 Iterator left( begin() );
5971 ConstIterator_t<VT> right( (*rhs).begin() );
5972
5973 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
5974 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5975 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5976 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5977 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5978 }
5979 for( ; i<ipos; i+=SIMDSIZE ) {
5980 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5981 }
5982 for( ; remainder && i<rows; ++i ) {
5983 *left -= *right; ++left; ++right;
5984 }
5985}
5987//*************************************************************************************************
5988
5989
5990//*************************************************************************************************
6002template< typename MT // Type of the dense matrix
6003 , size_t... CRAs > // Compile time row arguments
6004template< typename VT > // Type of the right-hand side sparse vector
6005inline void Row<MT,false,true,true,CRAs...>::subAssign( const SparseVector<VT,true>& rhs )
6006{
6007 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6008
6009 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
6010 matrix_(element->index(),row()) -= element->value();
6011}
6013//*************************************************************************************************
6014
6015
6016//*************************************************************************************************
6028template< typename MT // Type of the dense matrix
6029 , size_t... CRAs > // Compile time row arguments
6030template< typename VT > // Type of the right-hand side dense vector
6031inline auto Row<MT,false,true,true,CRAs...>::multAssign( const DenseVector<VT,true>& rhs )
6032 -> DisableIf_t< VectorizedMultAssign_v<VT> >
6033{
6034 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6035
6036 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
6037 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
6038
6039 for( size_t i=0UL; i<ipos; i+=2UL ) {
6040 matrix_(i ,row()) *= (*rhs)[i ];
6041 matrix_(i+1UL,row()) *= (*rhs)[i+1UL];
6042 }
6043 if( ipos < (*rhs).size() )
6044 matrix_(ipos,row()) *= (*rhs)[ipos];
6045}
6047//*************************************************************************************************
6048
6049
6050//*************************************************************************************************
6062template< typename MT // Type of the dense matrix
6063 , size_t... CRAs > // Compile time row arguments
6064template< typename VT > // Type of the right-hand side dense vector
6065inline auto Row<MT,false,true,true,CRAs...>::multAssign( const DenseVector<VT,true>& rhs )
6066 -> EnableIf_t< VectorizedMultAssign_v<VT> >
6067{
6069
6070 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6071
6072 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
6073
6074 const size_t rows( size() );
6075
6076 const size_t ipos( remainder ? prevMultiple( rows, SIMDSIZE ) : rows );
6077 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
6078
6079 size_t i( 0UL );
6080 Iterator left( begin() );
6081 ConstIterator_t<VT> right( (*rhs).begin() );
6082
6083 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6084 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6085 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6086 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6087 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6088 }
6089 for( ; i<ipos; i+=SIMDSIZE ) {
6090 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6091 }
6092 for( ; remainder && i<rows; ++i ) {
6093 *left *= *right; ++left; ++right;
6094 }
6095}
6097//*************************************************************************************************
6098
6099
6100//*************************************************************************************************
6112template< typename MT // Type of the dense matrix
6113 , size_t... CRAs > // Compile time row arguments
6114template< typename VT > // Type of the right-hand side sparse vector
6115inline void Row<MT,false,true,true,CRAs...>::multAssign( const SparseVector<VT,true>& rhs )
6116{
6117 using blaze::reset;
6118
6119 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6120
6121 size_t i( 0UL );
6122
6123 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
6124 const size_t index( element->index() );
6125 for( ; i<index; ++i )
6126 reset( matrix_(i,row()) );
6127 matrix_(i,row()) *= element->value();
6128 ++i;
6129 }
6130
6131 for( ; i<size(); ++i ) {
6132 reset( matrix_(i,row()) );
6133 }
6134}
6136//*************************************************************************************************
6137
6138
6139//*************************************************************************************************
6151template< typename MT // Type of the dense matrix
6152 , size_t... CRAs > // Compile time row arguments
6153template< typename VT > // Type of the right-hand side dense vector
6154inline auto Row<MT,false,true,true,CRAs...>::divAssign( const DenseVector<VT,true>& rhs )
6155 -> DisableIf_t< VectorizedDivAssign_v<VT> >
6156{
6157 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6158
6159 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
6160 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
6161
6162 for( size_t i=0UL; i<ipos; i+=2UL ) {
6163 matrix_(i ,row()) /= (*rhs)[i ];
6164 matrix_(i+1UL,row()) /= (*rhs)[i+1UL];
6165 }
6166 if( ipos < (*rhs).size() )
6167 matrix_(ipos,row()) /= (*rhs)[ipos];
6168}
6170//*************************************************************************************************
6171
6172
6173//*************************************************************************************************
6185template< typename MT // Type of the dense matrix
6186 , size_t... CRAs > // Compile time row arguments
6187template< typename VT > // Type of the right-hand side dense vector
6188inline auto Row<MT,false,true,true,CRAs...>::divAssign( const DenseVector<VT,true>& rhs )
6189 -> EnableIf_t< VectorizedDivAssign_v<VT> >
6190{
6192
6193 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6194
6195 const size_t rows( size() );
6196
6197 const size_t ipos( prevMultiple( rows, SIMDSIZE ) );
6198 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
6199
6200 size_t i( 0UL );
6201 Iterator left( begin() );
6202 ConstIterator_t<VT> right( (*rhs).begin() );
6203
6204 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
6205 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6206 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6207 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6208 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6209 }
6210 for( ; i<ipos; i+=SIMDSIZE ) {
6211 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6212 }
6213 for( ; i<rows; ++i ) {
6214 *left /= *right; ++left; ++right;
6215 }
6216}
6218//*************************************************************************************************
6219
6220} // namespace blaze
6221
6222#endif
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
Header file for the blaze::checked and blaze::unchecked instances.
Constraints on the storage order of matrix types.
Header file for the cross product trait.
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 HasSIMDDiv type trait.
Header file for the HasSIMDMult type trait.
Header file for the HasSIMDSub type trait.
Header file for the If class template.
Header file for the IsConst type trait.
Header file for the isDefault shim.
Header file for the IsExpression type trait class.
Header file for the IsLower type trait.
Header file for the IsPadded 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 IsSparseVector type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsTriangular type trait.
Header file for the IsUniLower type trait.
Header file for the IsUniUpper type trait.
Header file for the IsUpper type trait.
Constraint on the data type.
Header file for the prevMultiple shim.
Constraint on the data type.
Header file for the implementation of the RowData class template.
Constraints on the storage order of matrix types.
Header file for the row trait.
Constraint on the transpose flag of vector types.
Header file for all SIMD functionality.
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 DenseVector 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
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:574
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
auto operator*=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:510
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_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_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.
Definition: DenseVector.h:61
#define BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE(T)
Constraint on the data type.
Definition: RowVector.h:61
#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
typename RowTrait< MT, CRAs... >::Type RowTrait_t
Auxiliary alias declaration for the RowTrait type trait.
Definition: RowTrait.h:144
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 HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.
Definition: HasSIMDAdd.h:187
constexpr bool HasSIMDDiv_v
Auxiliary variable template for the HasSIMDDiv type trait.
Definition: HasSIMDDiv.h:173
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
constexpr void clear(Matrix< MT, SO > &matrix)
Clearing the given matrix.
Definition: Matrix.h:960
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
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
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 smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:221
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 smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector.
Definition: DenseVector.h:192
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
#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
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
Header file for the exception macros of the math module.
Header file for the extended initializer_list functionality.
Header file for the clear shim.
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 basic type definitions.
Header file for the implementation of the Row base template.