Blaze 3.9
Dense.h
Go to the documentation of this file.
1//=================================================================================================
33//=================================================================================================
34
35#ifndef _BLAZE_MATH_VIEWS_COLUMN_DENSE_H_
36#define _BLAZE_MATH_VIEWS_COLUMN_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 COLUMN-MAJOR DENSE MATRICES
109//
110//=================================================================================================
111
112//*************************************************************************************************
120template< typename MT // Type of the dense matrix
121 , bool SF // Symmetry flag
122 , size_t... CCAs > // Compile time column arguments
123class Column<MT,true,true,SF,CCAs...>
124 : public View< DenseVector< Column<MT,true,true,SF,CCAs...>, false > >
125 , private ColumnData<CCAs...>
126{
127 private:
128 //**Type definitions****************************************************************************
129 using DataType = ColumnData<CCAs...>;
130 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
131 //**********************************************************************************************
132
133 public:
134 //**Type definitions****************************************************************************
136 using This = Column<MT,true,true,SF,CCAs...>;
137
139 using BaseType = View< DenseVector<This,false> >;
140
141 using ViewedType = MT;
142 using ResultType = ColumnTrait_t<MT,CCAs...>;
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 Column&;
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... RCAs >
183 explicit inline Column( MT& matrix, RCAs... args );
184
185 Column( const Column& ) = default;
187 //**********************************************************************************************
188
189 //**Destructor**********************************************************************************
192 ~Column() = 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 Column& operator=( const ElementType& rhs );
218 inline Column& operator=( initializer_list<ElementType> list );
219 inline Column& operator=( const Column& rhs );
220
221 template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
222 template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
223 template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
224 template< typename VT > inline Column& operator*=( const Vector<VT,false>& rhs );
225 template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
226 template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
228 //**********************************************************************************************
229
230 //**Utility functions***************************************************************************
233 using DataType::column;
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 Column& 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... CCAs2 >
308 inline bool canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* 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... CCAs2 >
314 inline bool isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* 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,false>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
330
331 template< typename VT >
332 inline auto assign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
333
334 template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
335
336 template< typename VT >
337 inline auto addAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
338
339 template< typename VT >
340 inline auto addAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
341
342 template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
343
344 template< typename VT >
345 inline auto subAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
346
347 template< typename VT >
348 inline auto subAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
349
350 template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
351
352 template< typename VT >
353 inline auto multAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
354
355 template< typename VT >
356 inline auto multAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
357
358 template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
359
360 template< typename VT >
361 inline auto divAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
362
363 template< typename VT >
364 inline auto divAssign( const DenseVector<VT,false>& 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... CCAs2 > friend class Column;
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... CCAs > // Compile time column arguments
418template< typename... RCAs > // Runtime column arguments
419inline Column<MT,true,true,SF,CCAs...>::Column( MT& matrix, RCAs... args )
420 : DataType( args... ) // Base class initialization
421 , matrix_ ( matrix ) // The matrix containing the column
422{
423 if( isChecked( args... ) ) {
424 if( matrix_.columns() <= column() ) {
425 BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
426 }
427 }
428 else {
429 BLAZE_USER_ASSERT( column() < matrix_.columns(), "Invalid column 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... CCAs > // Compile time column arguments
457inline typename Column<MT,true,true,SF,CCAs...>::Reference
458 Column<MT,true,true,SF,CCAs...>::operator[]( size_t index )
459{
460 BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
461 return matrix_(index,column());
462}
464//*************************************************************************************************
465
466
467//*************************************************************************************************
477template< typename MT // Type of the dense matrix
478 , bool SF // Symmetry flag
479 , size_t... CCAs > // Compile time column arguments
480inline typename Column<MT,true,true,SF,CCAs...>::ConstReference
481 Column<MT,true,true,SF,CCAs...>::operator[]( size_t index ) const
482{
483 BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
484 return const_cast<const MT&>( matrix_ )(index,column());
485}
487//*************************************************************************************************
488
489
490//*************************************************************************************************
501template< typename MT // Type of the dense matrix
502 , bool SF // Symmetry flag
503 , size_t... CCAs > // Compile time column arguments
504inline typename Column<MT,true,true,SF,CCAs...>::Reference
505 Column<MT,true,true,SF,CCAs...>::at( size_t index )
506{
507 if( index >= size() ) {
508 BLAZE_THROW_OUT_OF_RANGE( "Invalid column 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... CCAs > // Compile time column arguments
530inline typename Column<MT,true,true,SF,CCAs...>::ConstReference
531 Column<MT,true,true,SF,CCAs...>::at( size_t index ) const
532{
533 if( index >= size() ) {
534 BLAZE_THROW_OUT_OF_RANGE( "Invalid column 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... CCAs > // Compile time column arguments
554inline typename Column<MT,true,true,SF,CCAs...>::Pointer
556{
557 return matrix_.data( column() );
558}
560//*************************************************************************************************
561
562
563//*************************************************************************************************
572template< typename MT // Type of the dense matrix
573 , bool SF // Symmetry flag
574 , size_t... CCAs > // Compile time column arguments
575inline typename Column<MT,true,true,SF,CCAs...>::ConstPointer
577{
578 return matrix_.data( column() );
579}
581//*************************************************************************************************
582
583
584//*************************************************************************************************
592template< typename MT // Type of the dense matrix
593 , bool SF // Symmetry flag
594 , size_t... CCAs > // Compile time column arguments
595inline typename Column<MT,true,true,SF,CCAs...>::Iterator
597{
598 return matrix_.begin( column() );
599}
601//*************************************************************************************************
602
603
604//*************************************************************************************************
612template< typename MT // Type of the dense matrix
613 , bool SF // Symmetry flag
614 , size_t... CCAs > // Compile time column arguments
615inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
617{
618 return matrix_.cbegin( column() );
619}
621//*************************************************************************************************
622
623
624//*************************************************************************************************
632template< typename MT // Type of the dense matrix
633 , bool SF // Symmetry flag
634 , size_t... CCAs > // Compile time column arguments
635inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
637{
638 return matrix_.cbegin( column() );
639}
641//*************************************************************************************************
642
643
644//*************************************************************************************************
652template< typename MT // Type of the dense matrix
653 , bool SF // Symmetry flag
654 , size_t... CCAs > // Compile time column arguments
655inline typename Column<MT,true,true,SF,CCAs...>::Iterator
657{
658 return matrix_.end( column() );
659}
661//*************************************************************************************************
662
663
664//*************************************************************************************************
672template< typename MT // Type of the dense matrix
673 , bool SF // Symmetry flag
674 , size_t... CCAs > // Compile time column arguments
675inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
677{
678 return matrix_.cend( column() );
679}
681//*************************************************************************************************
682
683
684//*************************************************************************************************
692template< typename MT // Type of the dense matrix
693 , bool SF // Symmetry flag
694 , size_t... CCAs > // Compile time column arguments
695inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
697{
698 return matrix_.cend( column() );
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... CCAs > // Compile time column arguments
726inline Column<MT,true,true,SF,CCAs...>&
727 Column<MT,true,true,SF,CCAs...>::operator=( const ElementType& rhs )
728{
729 decltype(auto) left( derestrict( matrix_ ) );
730
731 const size_t ibegin( ( IsLower_v<MT> )
732 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
733 ?( column()+1UL )
734 :( column() ) )
735 :( 0UL ) );
736 const size_t iend ( ( IsUpper_v<MT> )
737 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
738 ?( column() )
739 :( column()+1UL ) )
740 :( size() ) );
741
742 for( size_t i=ibegin; i<iend; ++i ) {
743 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, column(), rhs ) )
744 left(i,column()) = 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... CCAs > // Compile time column arguments
771inline Column<MT,true,true,SF,CCAs...>&
772 Column<MT,true,true,SF,CCAs...>::operator=( initializer_list<ElementType> list )
773{
774 if( list.size() > size() ) {
775 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
776 }
777
778 if( IsRestricted_v<MT> ) {
779 const InitializerVector<ElementType,false> tmp( list, size() );
780 if( !tryAssign( matrix_, tmp, 0UL, column() ) ) {
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... CCAs > // Compile time column arguments
814inline Column<MT,true,true,SF,CCAs...>&
815 Column<MT,true,true,SF,CCAs...>::operator=( const Column& rhs )
816{
817 if( &rhs == this ) return *this;
818
819 if( size() != rhs.size() ) {
820 BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
821 }
822
823 if( !tryAssign( matrix_, rhs, 0UL, column() ) ) {
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... CCAs > // Compile time column arguments
862template< typename VT > // Type of the right-hand side vector
863inline Column<MT,true,true,SF,CCAs...>&
864 Column<MT,true,true,SF,CCAs...>::operator=( const Vector<VT,false>& rhs )
865{
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, 0UL, column() ) ) {
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... CCAs > // Compile time column arguments
917template< typename VT > // Type of the right-hand side vector
918inline Column<MT,true,true,SF,CCAs...>&
919 Column<MT,true,true,SF,CCAs...>::operator+=( const Vector<VT,false>& rhs )
920{
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, 0UL, column() ) ) {
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... CCAs > // Compile time column arguments
970template< typename VT > // Type of the right-hand side vector
971inline Column<MT,true,true,SF,CCAs...>&
972 Column<MT,true,true,SF,CCAs...>::operator-=( const Vector<VT,false>& rhs )
973{
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, 0UL, column() ) ) {
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... CCAs > // Compile time column arguments
1022template< typename VT > // Type of the right-hand side vector
1023inline Column<MT,true,true,SF,CCAs...>&
1024 Column<MT,true,true,SF,CCAs...>::operator*=( const Vector<VT,false>& rhs )
1025{
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, 0UL, column() ) ) {
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... CCAs > // Compile time column arguments
1073template< typename VT > // Type of the right-hand side dense vector
1074inline Column<MT,true,true,SF,CCAs...>&
1075 Column<MT,true,true,SF,CCAs...>::operator/=( const DenseVector<VT,false>& rhs )
1076{
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, 0UL, column() ) ) {
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... CCAs > // Compile time column arguments
1125template< typename VT > // Type of the right-hand side vector
1126inline Column<MT,true,true,SF,CCAs...>&
1127 Column<MT,true,true,SF,CCAs...>::operator%=( const Vector<VT,false>& rhs )
1128{
1129 using blaze::assign;
1130
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, 0UL, column() ) ) {
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... CCAs > // Compile time column arguments
1179inline MT& Column<MT,true,true,SF,CCAs...>::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... CCAs > // Compile time column arguments
1196inline const MT& Column<MT,true,true,SF,CCAs...>::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... CCAs > // Compile time column arguments
1213inline size_t Column<MT,true,true,SF,CCAs...>::size() const noexcept
1214{
1215 return matrix_.rows();
1216}
1218//*************************************************************************************************
1219
1220
1221//*************************************************************************************************
1230template< typename MT // Type of the dense matrix
1231 , bool SF // Symmetry flag
1232 , size_t... CCAs > // Compile time column arguments
1233inline size_t Column<MT,true,true,SF,CCAs...>::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... CCAs > // Compile time column arguments
1250inline size_t Column<MT,true,true,SF,CCAs...>::capacity() const noexcept
1251{
1252 return matrix_.capacity( column() );
1253}
1255//*************************************************************************************************
1256
1257
1258//*************************************************************************************************
1267template< typename MT // Type of the dense matrix
1268 , bool SF // Symmetry flag
1269 , size_t... CCAs > // Compile time column arguments
1271{
1272 return matrix_.nonZeros( column() );
1273}
1275//*************************************************************************************************
1276
1277
1278//*************************************************************************************************
1284template< typename MT // Type of the dense matrix
1285 , bool SF // Symmetry flag
1286 , size_t... CCAs > // Compile time column arguments
1288{
1289 matrix_.reset( column() );
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... CCAs > // Compile time column arguments
1319template< typename Other > // Data type of the scalar value
1320inline Column<MT,true,true,SF,CCAs...>&
1321 Column<MT,true,true,SF,CCAs...>::scale( const Other& scalar )
1322{
1324
1325 const size_t ibegin( ( IsLower_v<MT> )
1326 ?( ( IsStrictlyLower_v<MT> )
1327 ?( column()+1UL )
1328 :( column() ) )
1329 :( 0UL ) );
1330 const size_t iend ( ( IsUpper_v<MT> )
1331 ?( ( IsStrictlyUpper_v<MT> )
1332 ?( column() )
1333 :( column()+1UL ) )
1334 :( size() ) );
1335
1336 for( size_t i=ibegin; i<iend; ++i ) {
1337 matrix_(i,column()) *= 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... CCAs > // Compile time column arguments
1368template< typename Other > // Data type of the foreign expression
1369inline bool Column<MT,true,true,SF,CCAs...>::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... CCAs > // Compile time column arguments
1391template< typename MT2 // Data type of the foreign dense column
1392 , bool SO2 // Storage order of the foreign dense column
1393 , bool SF2 // Symmetry flag of the foreign dense column
1394 , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
1395inline bool
1396 Column<MT,true,true,SF,CCAs...>::canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1397{
1398 return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
1399}
1401//*************************************************************************************************
1402
1403
1404//*************************************************************************************************
1415template< typename MT // Type of the dense matrix
1416 , bool SF // Symmetry flag
1417 , size_t... CCAs > // Compile time column arguments
1418template< typename Other > // Data type of the foreign expression
1419inline bool Column<MT,true,true,SF,CCAs...>::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... CCAs > // Compile time column arguments
1441template< typename MT2 // Data type of the foreign dense column
1442 , bool SO2 // Storage order of the foreign dense column
1443 , bool SF2 // Symmetry flag of the foreign dense column
1444 , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
1445inline bool
1446 Column<MT,true,true,SF,CCAs...>::isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1447{
1448 return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
1449}
1451//*************************************************************************************************
1452
1453
1454//*************************************************************************************************
1464template< typename MT // Type of the dense matrix
1465 , bool SF // Symmetry flag
1466 , size_t... CCAs > // Compile time column arguments
1467inline bool Column<MT,true,true,SF,CCAs...>::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... CCAs > // Compile time column arguments
1489inline bool Column<MT,true,true,SF,CCAs...>::canSMPAssign() const noexcept
1490{
1491 return ( size() > SMP_DVECASSIGN_THRESHOLD );
1492}
1494//*************************************************************************************************
1495
1496
1497//*************************************************************************************************
1509template< typename MT // Type of the dense matrix
1510 , bool SF // Symmetry flag
1511 , size_t... CCAs > // Compile time column arguments
1512BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF,CCAs...>::SIMDType
1513 Column<MT,true,true,SF,CCAs...>::load( size_t index ) const noexcept
1514{
1515 return matrix_.load( index, column() );
1516}
1518//*************************************************************************************************
1519
1520
1521//*************************************************************************************************
1534template< typename MT // Type of the dense matrix
1535 , bool SF // Symmetry flag
1536 , size_t... CCAs > // Compile time column arguments
1537BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF,CCAs...>::SIMDType
1538 Column<MT,true,true,SF,CCAs...>::loada( size_t index ) const noexcept
1539{
1540 return matrix_.loada( index, column() );
1541}
1543//*************************************************************************************************
1544
1545
1546//*************************************************************************************************
1559template< typename MT // Type of the dense matrix
1560 , bool SF // Symmetry flag
1561 , size_t... CCAs > // Compile time column arguments
1562BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF,CCAs...>::SIMDType
1563 Column<MT,true,true,SF,CCAs...>::loadu( size_t index ) const noexcept
1564{
1565 return matrix_.loadu( index, column() );
1566}
1568//*************************************************************************************************
1569
1570
1571//*************************************************************************************************
1584template< typename MT // Type of the dense matrix
1585 , bool SF // Symmetry flag
1586 , size_t... CCAs > // Compile time column arguments
1588 Column<MT,true,true,SF,CCAs...>::store( size_t index, const SIMDType& value ) noexcept
1589{
1590 matrix_.store( index, column(), value );
1591}
1593//*************************************************************************************************
1594
1595
1596//*************************************************************************************************
1610template< typename MT // Type of the dense matrix
1611 , bool SF // Symmetry flag
1612 , size_t... CCAs > // Compile time column arguments
1614 Column<MT,true,true,SF,CCAs...>::storea( size_t index, const SIMDType& value ) noexcept
1615{
1616 matrix_.storea( index, column(), value );
1617}
1619//*************************************************************************************************
1620
1621
1622//*************************************************************************************************
1636template< typename MT // Type of the dense matrix
1637 , bool SF // Symmetry flag
1638 , size_t... CCAs > // Compile time column arguments
1640 Column<MT,true,true,SF,CCAs...>::storeu( size_t index, const SIMDType& value ) noexcept
1641{
1642 matrix_.storeu( index, column(), value );
1643}
1645//*************************************************************************************************
1646
1647
1648//*************************************************************************************************
1662template< typename MT // Type of the dense matrix
1663 , bool SF // Symmetry flag
1664 , size_t... CCAs > // Compile time column arguments
1666 Column<MT,true,true,SF,CCAs...>::stream( size_t index, const SIMDType& value ) noexcept
1667{
1668 matrix_.stream( index, column(), value );
1669}
1671//*************************************************************************************************
1672
1673
1674//*************************************************************************************************
1686template< typename MT // Type of the dense matrix
1687 , bool SF // Symmetry flag
1688 , size_t... CCAs > // Compile time column arguments
1689template< typename VT > // Type of the right-hand side dense vector
1690inline auto Column<MT,true,true,SF,CCAs...>::assign( const DenseVector<VT,false>& rhs )
1691 -> DisableIf_t< VectorizedAssign_v<VT> >
1692{
1693 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1694
1695 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
1696 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
1697
1698 for( size_t i=0UL; i<ipos; i+=2UL ) {
1699 matrix_(i ,column()) = (*rhs)[i ];
1700 matrix_(i+1UL,column()) = (*rhs)[i+1UL];
1701 }
1702 if( ipos < (*rhs).size() )
1703 matrix_(ipos,column()) = (*rhs)[ipos];
1704}
1706//*************************************************************************************************
1707
1708
1709//*************************************************************************************************
1721template< typename MT // Type of the dense matrix
1722 , bool SF // Symmetry flag
1723 , size_t... CCAs > // Compile time column arguments
1724template< typename VT > // Type of the right-hand side dense vector
1725inline auto Column<MT,true,true,SF,CCAs...>::assign( const DenseVector<VT,false>& rhs )
1726 -> EnableIf_t< VectorizedAssign_v<VT> >
1727{
1729
1730 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1731
1732 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1733
1734 const size_t rows( size() );
1735
1736 const size_t ipos( remainder ? prevMultiple( rows, SIMDSIZE ) : rows );
1737 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
1738
1739 size_t i( 0UL );
1740 Iterator left( begin() );
1741 ConstIterator_t<VT> right( (*rhs).begin() );
1742
1743 if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(*rhs).isAliased( this ) )
1744 {
1745 for( ; i<ipos; i+=SIMDSIZE ) {
1746 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1747 }
1748 for( ; remainder && i<rows; ++i ) {
1749 *left = *right; ++left; ++right;
1750 }
1751 }
1752 else
1753 {
1754 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1755 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1756 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1757 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1758 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1759 }
1760 for( ; i<ipos; i+=SIMDSIZE ) {
1761 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1762 }
1763 for( ; remainder && i<rows; ++i ) {
1764 *left = *right; ++left; ++right;
1765 }
1766 }
1767}
1769//*************************************************************************************************
1770
1771
1772//*************************************************************************************************
1784template< typename MT // Type of the dense matrix
1785 , bool SF // Symmetry flag
1786 , size_t... CCAs > // Compile time column arguments
1787template< typename VT > // Type of the right-hand side sparse vector
1788inline void Column<MT,true,true,SF,CCAs...>::assign( const SparseVector<VT,false>& rhs )
1789{
1790 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1791
1792 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
1793 matrix_(element->index(),column()) = element->value();
1794}
1796//*************************************************************************************************
1797
1798
1799//*************************************************************************************************
1811template< typename MT // Type of the dense matrix
1812 , bool SF // Symmetry flag
1813 , size_t... CCAs > // Compile time column arguments
1814template< typename VT > // Type of the right-hand side dense vector
1815inline auto Column<MT,true,true,SF,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
1816 -> DisableIf_t< VectorizedAddAssign_v<VT> >
1817{
1818 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1819
1820 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
1821 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
1822
1823 for( size_t i=0UL; i<ipos; i+=2UL ) {
1824 matrix_(i ,column()) += (*rhs)[i ];
1825 matrix_(i+1UL,column()) += (*rhs)[i+1UL];
1826 }
1827 if( ipos < (*rhs).size() )
1828 matrix_(ipos,column()) += (*rhs)[ipos];
1829}
1831//*************************************************************************************************
1832
1833
1834//*************************************************************************************************
1846template< typename MT // Type of the dense matrix
1847 , bool SF // Symmetry flag
1848 , size_t... CCAs > // Compile time column arguments
1849template< typename VT > // Type of the right-hand side dense vector
1850inline auto Column<MT,true,true,SF,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
1851 -> EnableIf_t< VectorizedAddAssign_v<VT> >
1852{
1854
1855 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1856
1857 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1858
1859 const size_t rows( size() );
1860
1861 const size_t ipos( remainder ? prevMultiple( rows, SIMDSIZE ) : rows );
1862 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
1863
1864 size_t i( 0UL );
1865 Iterator left( begin() );
1866 ConstIterator_t<VT> right( (*rhs).begin() );
1867
1868 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1869 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1870 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1871 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1872 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1873 }
1874 for( ; i<ipos; i+=SIMDSIZE ) {
1875 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1876 }
1877 for( ; remainder && i<rows; ++i ) {
1878 *left += *right; ++left; ++right;
1879 }
1880}
1882//*************************************************************************************************
1883
1884
1885//*************************************************************************************************
1897template< typename MT // Type of the dense matrix
1898 , bool SF // Symmetry flag
1899 , size_t... CCAs > // Compile time column arguments
1900template< typename VT > // Type of the right-hand side sparse vector
1901inline void Column<MT,true,true,SF,CCAs...>::addAssign( const SparseVector<VT,false>& rhs )
1902{
1903 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1904
1905 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
1906 matrix_(element->index(),column()) += element->value();
1907}
1909//*************************************************************************************************
1910
1911
1912//*************************************************************************************************
1924template< typename MT // Type of the dense matrix
1925 , bool SF // Symmetry flag
1926 , size_t... CCAs > // Compile time column arguments
1927template< typename VT > // Type of the right-hand side dense vector
1928inline auto Column<MT,true,true,SF,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
1929 -> DisableIf_t< VectorizedSubAssign_v<VT> >
1930{
1931 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1932
1933 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
1934 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
1935
1936 for( size_t i=0UL; i<ipos; i+=2UL ) {
1937 matrix_(i ,column()) -= (*rhs)[i ];
1938 matrix_(i+1UL,column()) -= (*rhs)[i+1UL];
1939 }
1940 if( ipos < (*rhs).size() )
1941 matrix_(ipos,column()) -= (*rhs)[ipos];
1942}
1944//*************************************************************************************************
1945
1946
1947//*************************************************************************************************
1959template< typename MT // Type of the dense matrix
1960 , bool SF // Symmetry flag
1961 , size_t... CCAs > // Compile time column arguments
1962template< typename VT > // Type of the right-hand side dense vector
1963inline auto Column<MT,true,true,SF,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
1964 -> EnableIf_t< VectorizedSubAssign_v<VT> >
1965{
1967
1968 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
1969
1970 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1971
1972 const size_t rows( size() );
1973
1974 const size_t ipos( remainder ? prevMultiple( rows, SIMDSIZE ) : rows );
1975 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
1976
1977 size_t i( 0UL );
1978 Iterator left( begin() );
1979 ConstIterator_t<VT> right( (*rhs).begin() );
1980
1981 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1982 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1983 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1984 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1985 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1986 }
1987 for( ; i<ipos; i+=SIMDSIZE ) {
1988 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1989 }
1990 for( ; remainder && i<rows; ++i ) {
1991 *left -= *right; ++left; ++right;
1992 }
1993}
1995//*************************************************************************************************
1996
1997
1998//*************************************************************************************************
2010template< typename MT // Type of the dense matrix
2011 , bool SF // Symmetry flag
2012 , size_t... CCAs > // Compile time column arguments
2013template< typename VT > // Type of the right-hand side sparse vector
2014inline void Column<MT,true,true,SF,CCAs...>::subAssign( const SparseVector<VT,false>& rhs )
2015{
2016 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2017
2018 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
2019 matrix_(element->index(),column()) -= element->value();
2020}
2022//*************************************************************************************************
2023
2024
2025//*************************************************************************************************
2037template< typename MT // Type of the dense matrix
2038 , bool SF // Symmetry flag
2039 , size_t... CCAs > // Compile time column arguments
2040template< typename VT > // Type of the right-hand side dense vector
2041inline auto Column<MT,true,true,SF,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
2042 -> DisableIf_t< VectorizedMultAssign_v<VT> >
2043{
2044 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2045
2046 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
2047 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
2048
2049 for( size_t i=0UL; i<ipos; i+=2UL ) {
2050 matrix_(i ,column()) *= (*rhs)[i ];
2051 matrix_(i+1UL,column()) *= (*rhs)[i+1UL];
2052 }
2053 if( ipos < (*rhs).size() )
2054 matrix_(ipos,column()) *= (*rhs)[ipos];
2055}
2057//*************************************************************************************************
2058
2059
2060//*************************************************************************************************
2072template< typename MT // Type of the dense matrix
2073 , bool SF // Symmetry flag
2074 , size_t... CCAs > // Compile time column arguments
2075template< typename VT > // Type of the right-hand side dense vector
2076inline auto Column<MT,true,true,SF,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
2077 -> EnableIf_t< VectorizedMultAssign_v<VT> >
2078{
2080
2081 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2082
2083 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
2084
2085 const size_t rows( size() );
2086
2087 const size_t ipos( remainder ? prevMultiple( rows, SIMDSIZE ) : rows );
2088 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
2089
2090 size_t i( 0UL );
2091 Iterator left( begin() );
2092 ConstIterator_t<VT> right( (*rhs).begin() );
2093
2094 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2095 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2096 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2097 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2098 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2099 }
2100 for( ; i<ipos; i+=SIMDSIZE ) {
2101 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2102 }
2103 for( ; remainder && i<rows; ++i ) {
2104 *left *= *right; ++left, ++right;
2105 }
2106}
2108//*************************************************************************************************
2109
2110
2111//*************************************************************************************************
2123template< typename MT // Type of the dense matrix
2124 , bool SF // Symmetry flag
2125 , size_t... CCAs > // Compile time column arguments
2126template< typename VT > // Type of the right-hand side sparse vector
2127inline void Column<MT,true,true,SF,CCAs...>::multAssign( const SparseVector<VT,false>& rhs )
2128{
2129 using blaze::reset;
2130
2131 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2132
2133 size_t i( 0UL );
2134
2135 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
2136 const size_t index( element->index() );
2137 for( ; i<index; ++i )
2138 reset( matrix_(i,column()) );
2139 matrix_(i,column()) *= element->value();
2140 ++i;
2141 }
2142
2143 for( ; i<size(); ++i ) {
2144 reset( matrix_(i,column()) );
2145 }
2146}
2148//*************************************************************************************************
2149
2150
2151//*************************************************************************************************
2163template< typename MT // Type of the dense matrix
2164 , bool SF // Symmetry flag
2165 , size_t... CCAs > // Compile time column arguments
2166template< typename VT > // Type of the right-hand side dense vector
2167inline auto Column<MT,true,true,SF,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
2168 -> DisableIf_t< VectorizedDivAssign_v<VT> >
2169{
2170 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2171
2172 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
2173 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
2174
2175 for( size_t i=0UL; i<ipos; i+=2UL ) {
2176 matrix_(i ,column()) /= (*rhs)[i ];
2177 matrix_(i+1UL,column()) /= (*rhs)[i+1UL];
2178 }
2179 if( ipos < (*rhs).size() )
2180 matrix_(ipos,column()) /= (*rhs)[ipos];
2181}
2183//*************************************************************************************************
2184
2185
2186//*************************************************************************************************
2198template< typename MT // Type of the dense matrix
2199 , bool SF // Symmetry flag
2200 , size_t... CCAs > // Compile time column arguments
2201template< typename VT > // Type of the right-hand side dense vector
2202inline auto Column<MT,true,true,SF,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
2203 -> EnableIf_t< VectorizedDivAssign_v<VT> >
2204{
2206
2207 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
2208
2209 const size_t rows( size() );
2210
2211 const size_t ipos( prevMultiple( rows, SIMDSIZE ) );
2212 BLAZE_INTERNAL_ASSERT( ipos <= rows, "Invalid end calculation" );
2213
2214 size_t i( 0UL );
2215 Iterator left( begin() );
2216 ConstIterator_t<VT> right( (*rhs).begin() );
2217
2218 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2219 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2220 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2221 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2222 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2223 }
2224 for( ; i<ipos; i+=SIMDSIZE ) {
2225 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2226 }
2227 for( ; i<rows; ++i ) {
2228 *left /= *right; ++left; ++right;
2229 }
2230}
2232//*************************************************************************************************
2233
2234
2235
2236
2237
2238
2239
2240
2241//=================================================================================================
2242//
2243// CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
2244//
2245//=================================================================================================
2246
2247//*************************************************************************************************
2255template< typename MT // Type of the dense matrix
2256 , size_t... CCAs > // Compile time column arguments
2257class Column<MT,false,true,false,CCAs...>
2258 : public View< DenseVector< Column<MT,false,true,false,CCAs...>, false > >
2259 , private ColumnData<CCAs...>
2260{
2261 private:
2262 //**Type definitions****************************************************************************
2263 using DataType = ColumnData<CCAs...>;
2264 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
2265 //**********************************************************************************************
2266
2267 public:
2268 //**Type definitions****************************************************************************
2270 using This = Column<MT,false,true,false,CCAs...>;
2271
2273 using BaseType = View< DenseVector<This,false> >;
2274
2275 using ViewedType = MT;
2276 using ResultType = ColumnTrait_t<MT,CCAs...>;
2277 using TransposeType = TransposeType_t<ResultType>;
2278 using ElementType = ElementType_t<MT>;
2279 using ReturnType = ReturnType_t<MT>;
2280 using CompositeType = const Column&;
2281
2283 using ConstReference = ConstReference_t<MT>;
2284
2286 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
2287
2289 using ConstPointer = ConstPointer_t<MT>;
2290
2292 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
2293 //**********************************************************************************************
2294
2295 //**ColumnIterator class definition*************************************************************
2298 template< typename MatrixType // Type of the dense matrix
2299 , typename IteratorType > // Type of the dense matrix iterator
2300 class ColumnIterator
2301 {
2302 public:
2303 //**Type definitions*************************************************************************
2305 using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
2306
2308 using ValueType = typename std::iterator_traits<IteratorType>::value_type;
2309
2311 using PointerType = typename std::iterator_traits<IteratorType>::pointer;
2312
2314 using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
2315
2317 using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
2318
2319 // STL iterator requirements
2320 using iterator_category = IteratorCategory;
2321 using value_type = ValueType;
2322 using pointer = PointerType;
2323 using reference = ReferenceType;
2324 using difference_type = DifferenceType;
2325 //*******************************************************************************************
2326
2327 //**Constructor******************************************************************************
2330 inline ColumnIterator() noexcept
2331 : matrix_( nullptr ) // The dense matrix containing the column
2332 , row_ ( 0UL ) // The current row index
2333 , column_( 0UL ) // The current column index
2334 , pos_ ( ) // Iterator to the current dense element
2335 {}
2336 //*******************************************************************************************
2337
2338 //**Constructor******************************************************************************
2345 inline ColumnIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2346 : matrix_( &matrix ) // The dense matrix containing the column
2347 , row_ ( row ) // The current row index
2348 , column_( column ) // The current column index
2349 , pos_ ( ) // Iterator to the current dense element
2350 {
2351 if( row_ != matrix_->rows() )
2352 pos_ = matrix_->begin( row_ ) + column_;
2353 }
2354 //*******************************************************************************************
2355
2356 //**Constructor******************************************************************************
2361 template< typename MatrixType2, typename IteratorType2 >
2362 inline ColumnIterator( const ColumnIterator<MatrixType2,IteratorType2>& it ) noexcept
2363 : matrix_( it.matrix_ ) // The dense matrix containing the column
2364 , row_ ( it.row_ ) // The current row index
2365 , column_( it.column_ ) // The current column index
2366 , pos_ ( it.pos_ ) // Iterator to the current dense element
2367 {}
2368 //*******************************************************************************************
2369
2370 //**Addition assignment operator*************************************************************
2376 inline ColumnIterator& operator+=( size_t inc ) noexcept {
2377 using blaze::reset;
2378 row_ += inc;
2379 if( row_ != matrix_->rows() )
2380 pos_ = matrix_->begin( row_ ) + column_;
2381 else reset( pos_ );
2382 return *this;
2383 }
2384 //*******************************************************************************************
2385
2386 //**Subtraction assignment operator**********************************************************
2392 inline ColumnIterator& operator-=( size_t dec ) noexcept {
2393 using blaze::reset;
2394 row_ -= dec;
2395 if( row_ != matrix_->rows() )
2396 pos_ = matrix_->begin( row_ ) + column_;
2397 else reset( pos_ );
2398 return *this;
2399 }
2400 //*******************************************************************************************
2401
2402 //**Prefix increment operator****************************************************************
2407 inline ColumnIterator& operator++() noexcept {
2408 using blaze::reset;
2409 ++row_;
2410 if( row_ != matrix_->rows() )
2411 pos_ = matrix_->begin( row_ ) + column_;
2412 else reset( pos_ );
2413 return *this;
2414 }
2415 //*******************************************************************************************
2416
2417 //**Postfix increment operator***************************************************************
2422 inline const ColumnIterator operator++( int ) noexcept {
2423 const ColumnIterator tmp( *this );
2424 ++(*this);
2425 return tmp;
2426 }
2427 //*******************************************************************************************
2428
2429 //**Prefix decrement operator****************************************************************
2434 inline ColumnIterator& operator--() noexcept {
2435 using blaze::reset;
2436 --row_;
2437 if( row_ != matrix_->rows() )
2438 pos_ = matrix_->begin( row_ ) + column_;
2439 else reset( pos_ );
2440 return *this;
2441 }
2442 //*******************************************************************************************
2443
2444 //**Postfix decrement operator***************************************************************
2449 inline const ColumnIterator operator--( int ) noexcept {
2450 const ColumnIterator tmp( *this );
2451 --(*this);
2452 return tmp;
2453 }
2454 //*******************************************************************************************
2455
2456 //**Subscript operator***********************************************************************
2462 inline ReferenceType operator[]( size_t index ) const {
2463 BLAZE_USER_ASSERT( row_+index < matrix_->rows(), "Invalid access index detected" );
2464 const IteratorType pos( matrix_->begin( row_+index ) + column_ );
2465 return *pos;
2466 }
2467 //*******************************************************************************************
2468
2469 //**Element access operator******************************************************************
2474 inline ReferenceType operator*() const {
2475 return *pos_;
2476 }
2477 //*******************************************************************************************
2478
2479 //**Element access operator******************************************************************
2484 inline PointerType operator->() const {
2485 return pos_;
2486 }
2487 //*******************************************************************************************
2488
2489 //**Equality operator************************************************************************
2495 template< typename MatrixType2, typename IteratorType2 >
2496 inline bool operator==( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2497 return row_ == rhs.row_;
2498 }
2499 //*******************************************************************************************
2500
2501 //**Inequality operator**********************************************************************
2507 template< typename MatrixType2, typename IteratorType2 >
2508 inline bool operator!=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2509 return !( *this == rhs );
2510 }
2511 //*******************************************************************************************
2512
2513 //**Less-than operator***********************************************************************
2519 template< typename MatrixType2, typename IteratorType2 >
2520 inline bool operator<( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2521 return row_ < rhs.row_;
2522 }
2523 //*******************************************************************************************
2524
2525 //**Greater-than operator********************************************************************
2531 template< typename MatrixType2, typename IteratorType2 >
2532 inline bool operator>( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2533 return row_ > rhs.row_;
2534 }
2535 //*******************************************************************************************
2536
2537 //**Less-or-equal-than operator**************************************************************
2543 template< typename MatrixType2, typename IteratorType2 >
2544 inline bool operator<=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2545 return row_ <= rhs.row_;
2546 }
2547 //*******************************************************************************************
2548
2549 //**Greater-or-equal-than operator***********************************************************
2555 template< typename MatrixType2, typename IteratorType2 >
2556 inline bool operator>=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2557 return row_ >= rhs.row_;
2558 }
2559 //*******************************************************************************************
2560
2561 //**Subtraction operator*********************************************************************
2567 inline DifferenceType operator-( const ColumnIterator& rhs ) const noexcept {
2568 return row_ - rhs.row_;
2569 }
2570 //*******************************************************************************************
2571
2572 //**Addition operator************************************************************************
2579 friend inline const ColumnIterator operator+( const ColumnIterator& it, size_t inc ) noexcept {
2580 return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2581 }
2582 //*******************************************************************************************
2583
2584 //**Addition operator************************************************************************
2591 friend inline const ColumnIterator operator+( size_t inc, const ColumnIterator& it ) noexcept {
2592 return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2593 }
2594 //*******************************************************************************************
2595
2596 //**Subtraction operator*********************************************************************
2603 friend inline const ColumnIterator operator-( const ColumnIterator& it, size_t dec ) noexcept {
2604 return ColumnIterator( *it.matrix_, it.row_-dec, it.column_ );
2605 }
2606 //*******************************************************************************************
2607
2608 private:
2609 //**Member variables*************************************************************************
2610 MatrixType* matrix_;
2611 size_t row_;
2612 size_t column_;
2613 IteratorType pos_;
2614 //*******************************************************************************************
2615
2616 //**Friend declarations**********************************************************************
2617 template< typename MatrixType2, typename IteratorType2 > friend class ColumnIterator;
2618 //*******************************************************************************************
2619 };
2620 //**********************************************************************************************
2621
2622 //**Type definitions****************************************************************************
2624 using ConstIterator = ColumnIterator< const MT, ConstIterator_t<MT> >;
2625
2627 using Iterator = If_t< IsConst_v<MT>, ConstIterator, ColumnIterator< MT, Iterator_t<MT> > >;
2628 //**********************************************************************************************
2629
2630 //**Compilation flags***************************************************************************
2632 static constexpr bool simdEnabled = false;
2633
2635 static constexpr bool smpAssignable = MT::smpAssignable;
2636
2638 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2639 //**********************************************************************************************
2640
2641 //**Constructors********************************************************************************
2644 template< typename... RCAs >
2645 explicit inline Column( MT& matrix, RCAs... args );
2646
2647 Column( const Column& ) = default;
2649 //**********************************************************************************************
2650
2651 //**Destructor**********************************************************************************
2654 ~Column() = default;
2656 //**********************************************************************************************
2657
2658 //**Data access functions***********************************************************************
2661 inline Reference operator[]( size_t index );
2662 inline ConstReference operator[]( size_t index ) const;
2663 inline Reference at( size_t index );
2664 inline ConstReference at( size_t index ) const;
2665 inline Pointer data () noexcept;
2666 inline ConstPointer data () const noexcept;
2667 inline Iterator begin ();
2668 inline ConstIterator begin () const;
2669 inline ConstIterator cbegin() const;
2670 inline Iterator end ();
2671 inline ConstIterator end () const;
2672 inline ConstIterator cend () const;
2674 //**********************************************************************************************
2675
2676 //**Assignment operators************************************************************************
2679 inline Column& operator=( const ElementType& rhs );
2680 inline Column& operator=( initializer_list<ElementType> list );
2681 inline Column& operator=( const Column& rhs );
2682
2683 template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
2684 template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
2685 template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
2686 template< typename VT > inline Column& operator*=( const Vector<VT,false>& rhs );
2687 template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
2688 template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
2690 //**********************************************************************************************
2691
2692 //**Utility functions***************************************************************************
2695 using DataType::column;
2696
2697 inline MT& operand() noexcept;
2698 inline const MT& operand() const noexcept;
2699
2700 inline size_t size() const noexcept;
2701 inline size_t spacing() const noexcept;
2702 inline size_t capacity() const noexcept;
2703 inline size_t nonZeros() const;
2704 inline void reset();
2706 //**********************************************************************************************
2707
2708 //**Numeric functions***************************************************************************
2711 template< typename Other > inline Column& scale( const Other& scalar );
2713 //**********************************************************************************************
2714
2715 //**Expression template evaluation functions****************************************************
2718 template< typename Other >
2719 inline bool canAlias ( const Other* alias ) const noexcept;
2720
2721 template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
2722 inline bool canAlias ( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
2723
2724 template< typename Other >
2725 inline bool isAliased( const Other* alias ) const noexcept;
2726
2727 template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
2728 inline bool isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
2729
2730 inline bool isAligned () const noexcept;
2731 inline bool canSMPAssign() const noexcept;
2732
2733 template< typename VT > inline void assign ( const DenseVector <VT,false>& rhs );
2734 template< typename VT > inline void assign ( const SparseVector<VT,false>& rhs );
2735 template< typename VT > inline void addAssign ( const DenseVector <VT,false>& rhs );
2736 template< typename VT > inline void addAssign ( const SparseVector<VT,false>& rhs );
2737 template< typename VT > inline void subAssign ( const DenseVector <VT,false>& rhs );
2738 template< typename VT > inline void subAssign ( const SparseVector<VT,false>& rhs );
2739 template< typename VT > inline void multAssign( const DenseVector <VT,false>& rhs );
2740 template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
2741 template< typename VT > inline void divAssign ( const DenseVector <VT,false>& rhs );
2743 //**********************************************************************************************
2744
2745 private:
2746 //**Member variables****************************************************************************
2749 Operand matrix_;
2751 //**********************************************************************************************
2752
2753 //**Friend declarations*************************************************************************
2754 template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Column;
2755 //**********************************************************************************************
2756
2757 //**Compile time checks*************************************************************************
2766 //**********************************************************************************************
2767};
2769//*************************************************************************************************
2770
2771
2772
2773
2774//=================================================================================================
2775//
2776// CONSTRUCTORS
2777//
2778//=================================================================================================
2779
2780//*************************************************************************************************
2793template< typename MT // Type of the dense matrix
2794 , size_t... CCAs > // Compile time column arguments
2795template< typename... RCAs > // Runtime column arguments
2796inline Column<MT,false,true,false,CCAs...>::Column( MT& matrix, RCAs... args )
2797 : DataType( args... ) // Base class initialization
2798 , matrix_ ( matrix ) // The matrix containing the column
2799{
2800 if( isChecked( args... ) ) {
2801 if( matrix_.columns() <= column() ) {
2802 BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2803 }
2804 }
2805 else {
2806 BLAZE_USER_ASSERT( column() < matrix_.columns(), "Invalid column access index" );
2807 }
2808}
2810//*************************************************************************************************
2811
2812
2813
2814
2815//=================================================================================================
2816//
2817// DATA ACCESS FUNCTIONS
2818//
2819//=================================================================================================
2820
2821//*************************************************************************************************
2831template< typename MT // Type of the dense matrix
2832 , size_t... CCAs > // Compile time column arguments
2833inline typename Column<MT,false,true,false,CCAs...>::Reference
2834 Column<MT,false,true,false,CCAs...>::operator[]( size_t index )
2835{
2836 BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2837 return matrix_(index,column());
2838}
2840//*************************************************************************************************
2841
2842
2843//*************************************************************************************************
2853template< typename MT // Type of the dense matrix
2854 , size_t... CCAs > // Compile time column arguments
2855inline typename Column<MT,false,true,false,CCAs...>::ConstReference
2856 Column<MT,false,true,false,CCAs...>::operator[]( size_t index ) const
2857{
2858 BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2859 return const_cast<const MT&>( matrix_ )(index,column());
2860}
2862//*************************************************************************************************
2863
2864
2865//*************************************************************************************************
2876template< typename MT // Type of the dense matrix
2877 , size_t... CCAs > // Compile time column arguments
2878inline typename Column<MT,false,true,false,CCAs...>::Reference
2879 Column<MT,false,true,false,CCAs...>::at( size_t index )
2880{
2881 if( index >= size() ) {
2882 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2883 }
2884 return (*this)[index];
2885}
2887//*************************************************************************************************
2888
2889
2890//*************************************************************************************************
2901template< typename MT // Type of the dense matrix
2902 , size_t... CCAs > // Compile time column arguments
2903inline typename Column<MT,false,true,false,CCAs...>::ConstReference
2904 Column<MT,false,true,false,CCAs...>::at( size_t index ) const
2905{
2906 if( index >= size() ) {
2907 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2908 }
2909 return (*this)[index];
2910}
2912//*************************************************************************************************
2913
2914
2915//*************************************************************************************************
2924template< typename MT // Type of the dense matrix
2925 , size_t... CCAs > // Compile time column arguments
2926inline typename Column<MT,false,true,false,CCAs...>::Pointer
2928{
2929 return matrix_.data() + column();
2930}
2932//*************************************************************************************************
2933
2934
2935//*************************************************************************************************
2944template< typename MT // Type of the dense matrix
2945 , size_t... CCAs > // Compile time column arguments
2946inline typename Column<MT,false,true,false,CCAs...>::ConstPointer
2948{
2949 return matrix_.data() + column();
2950}
2952//*************************************************************************************************
2953
2954
2955//*************************************************************************************************
2963template< typename MT // Type of the dense matrix
2964 , size_t... CCAs > // Compile time column arguments
2965inline typename Column<MT,false,true,false,CCAs...>::Iterator
2967{
2968 return Iterator( matrix_, 0UL, column() );
2969}
2971//*************************************************************************************************
2972
2973
2974//*************************************************************************************************
2982template< typename MT // Type of the dense matrix
2983 , size_t... CCAs > // Compile time column arguments
2984inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
2986{
2987 return ConstIterator( matrix_, 0UL, column() );
2988}
2990//*************************************************************************************************
2991
2992
2993//*************************************************************************************************
3001template< typename MT // Type of the dense matrix
3002 , size_t... CCAs > // Compile time column arguments
3003inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
3005{
3006 return ConstIterator( matrix_, 0UL, column() );
3007}
3009//*************************************************************************************************
3010
3011
3012//*************************************************************************************************
3020template< typename MT // Type of the dense matrix
3021 , size_t... CCAs > // Compile time column arguments
3022inline typename Column<MT,false,true,false,CCAs...>::Iterator
3024{
3025 return Iterator( matrix_, size(), column() );
3026}
3028//*************************************************************************************************
3029
3030
3031//*************************************************************************************************
3039template< typename MT // Type of the dense matrix
3040 , size_t... CCAs > // Compile time column arguments
3041inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
3043{
3044 return ConstIterator( matrix_, size(), column() );
3045}
3047//*************************************************************************************************
3048
3049
3050//*************************************************************************************************
3058template< typename MT // Type of the dense matrix
3059 , size_t... CCAs > // Compile time column arguments
3060inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
3062{
3063 return ConstIterator( matrix_, size(), column() );
3064}
3066//*************************************************************************************************
3067
3068
3069
3070
3071//=================================================================================================
3072//
3073// ASSIGNMENT OPERATORS
3074//
3075//=================================================================================================
3076
3077//*************************************************************************************************
3088template< typename MT // Type of the dense matrix
3089 , size_t... CCAs > // Compile time column arguments
3090inline Column<MT,false,true,false,CCAs...>&
3091 Column<MT,false,true,false,CCAs...>::operator=( const ElementType& rhs )
3092{
3093 decltype(auto) left( derestrict( matrix_ ) );
3094
3095 const size_t ibegin( ( IsLower_v<MT> )
3096 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3097 ?( column()+1UL )
3098 :( column() ) )
3099 :( 0UL ) );
3100 const size_t iend ( ( IsUpper_v<MT> )
3101 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3102 ?( column() )
3103 :( column()+1UL ) )
3104 :( size() ) );
3105
3106 for( size_t i=ibegin; i<iend; ++i ) {
3107 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, column(), rhs ) )
3108 left(i,column()) = rhs;
3109 }
3110
3111 return *this;
3112}
3114//*************************************************************************************************
3115
3116
3117//*************************************************************************************************
3132template< typename MT // Type of the dense matrix
3133 , size_t... CCAs > // Compile time column arguments
3134inline Column<MT,false,true,false,CCAs...>&
3135 Column<MT,false,true,false,CCAs...>::operator=( initializer_list<ElementType> list )
3136{
3137 if( list.size() > size() ) {
3138 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
3139 }
3140
3141 if( IsRestricted_v<MT> ) {
3142 const InitializerVector<ElementType,false> tmp( list, size() );
3143 if( !tryAssign( matrix_, tmp, 0UL, column() ) ) {
3144 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3145 }
3146 }
3147
3148 decltype(auto) left( derestrict( *this ) );
3149
3150 std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
3151
3152 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3153
3154 return *this;
3155}
3157//*************************************************************************************************
3158
3159
3160//*************************************************************************************************
3174template< typename MT // Type of the dense matrix
3175 , size_t... CCAs > // Compile time column arguments
3176inline Column<MT,false,true,false,CCAs...>&
3177 Column<MT,false,true,false,CCAs...>::operator=( const Column& rhs )
3178{
3179 if( &rhs == this ) return *this;
3180
3181 if( size() != rhs.size() ) {
3182 BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
3183 }
3184
3185 if( !tryAssign( matrix_, rhs, 0UL, column() ) ) {
3186 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3187 }
3188
3189 decltype(auto) left( derestrict( *this ) );
3190
3191 if( IsExpression_v<MT> && rhs.canAlias( this ) ) {
3192 const ResultType tmp( rhs );
3193 smpAssign( left, tmp );
3194 }
3195 else {
3196 smpAssign( left, rhs );
3197 }
3198
3199 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3200
3201 return *this;
3202}
3204//*************************************************************************************************
3205
3206
3207//*************************************************************************************************
3221template< typename MT // Type of the dense matrix
3222 , size_t... CCAs > // Compile time column arguments
3223template< typename VT > // Type of the right-hand side vector
3224inline Column<MT,false,true,false,CCAs...>&
3225 Column<MT,false,true,false,CCAs...>::operator=( const Vector<VT,false>& rhs )
3226{
3230
3231 if( size() != (*rhs).size() ) {
3232 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3233 }
3234
3235 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3236 Right right( *rhs );
3237
3238 if( !tryAssign( matrix_, right, 0UL, column() ) ) {
3239 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3240 }
3241
3242 decltype(auto) left( derestrict( *this ) );
3243
3244 if( IsReference_v<Right> && right.canAlias( this ) ) {
3245 const ResultType tmp( right );
3246 smpAssign( left, tmp );
3247 }
3248 else {
3249 if( IsSparseVector_v<VT> )
3250 reset();
3251 smpAssign( left, right );
3252 }
3253
3254 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3255
3256 return *this;
3257}
3259//*************************************************************************************************
3260
3261
3262//*************************************************************************************************
3276template< typename MT // Type of the dense matrix
3277 , size_t... CCAs > // Compile time column arguments
3278template< typename VT > // Type of the right-hand side vector
3279inline Column<MT,false,true,false,CCAs...>&
3280 Column<MT,false,true,false,CCAs...>::operator+=( const Vector<VT,false>& rhs )
3281{
3284
3285 if( size() != (*rhs).size() ) {
3286 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3287 }
3288
3289 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3290 Right right( *rhs );
3291
3292 if( !tryAddAssign( matrix_, right, 0UL, column() ) ) {
3293 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3294 }
3295
3296 decltype(auto) left( derestrict( *this ) );
3297
3298 if( IsReference_v<Right> && right.canAlias( this ) ) {
3299 const ResultType_t<VT> tmp( right );
3300 smpAddAssign( left, tmp );
3301 }
3302 else {
3303 smpAddAssign( left, right );
3304 }
3305
3306 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3307
3308 return *this;
3309}
3311//*************************************************************************************************
3312
3313
3314//*************************************************************************************************
3328template< typename MT // Type of the dense matrix
3329 , size_t... CCAs > // Compile time column arguments
3330template< typename VT > // Type of the right-hand side vector
3331inline Column<MT,false,true,false,CCAs...>&
3332 Column<MT,false,true,false,CCAs...>::operator-=( const Vector<VT,false>& rhs )
3333{
3336
3337 if( size() != (*rhs).size() ) {
3338 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3339 }
3340
3341 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3342 Right right( *rhs );
3343
3344 if( !trySubAssign( matrix_, right, 0UL, column() ) ) {
3345 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3346 }
3347
3348 decltype(auto) left( derestrict( *this ) );
3349
3350 if( IsReference_v<Right> && right.canAlias( this ) ) {
3351 const ResultType_t<VT> tmp( right );
3352 smpSubAssign( left, tmp );
3353 }
3354 else {
3355 smpSubAssign( left, right );
3356 }
3357
3358 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3359
3360 return *this;
3361}
3363//*************************************************************************************************
3364
3365
3366//*************************************************************************************************
3379template< typename MT // Type of the dense matrix
3380 , size_t... CCAs > // Compile time column arguments
3381template< typename VT > // Type of the right-hand side vector
3382inline Column<MT,false,true,false,CCAs...>&
3383 Column<MT,false,true,false,CCAs...>::operator*=( const Vector<VT,false>& rhs )
3384{
3387
3388 if( size() != (*rhs).size() ) {
3389 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3390 }
3391
3392 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3393 Right right( *rhs );
3394
3395 if( !tryMultAssign( matrix_, right, 0UL, column() ) ) {
3396 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3397 }
3398
3399 decltype(auto) left( derestrict( *this ) );
3400
3401 if( IsReference_v<Right> && right.canAlias( this ) ) {
3402 const ResultType_t<VT> tmp( right );
3403 smpMultAssign( left, tmp );
3404 }
3405 else {
3406 smpMultAssign( left, right );
3407 }
3408
3409 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3410
3411 return *this;
3412}
3414//*************************************************************************************************
3415
3416
3417//*************************************************************************************************
3429template< typename MT // Type of the dense matrix
3430 , size_t... CCAs > // Compile time column arguments
3431template< typename VT > // Type of the right-hand side dense vector
3432inline Column<MT,false,true,false,CCAs...>&
3433 Column<MT,false,true,false,CCAs...>::operator/=( const DenseVector<VT,false>& rhs )
3434{
3437
3438 if( size() != (*rhs).size() ) {
3439 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3440 }
3441
3442 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3443 Right right( *rhs );
3444
3445 if( !tryDivAssign( matrix_, right, 0UL, column() ) ) {
3446 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3447 }
3448
3449 decltype(auto) left( derestrict( *this ) );
3450
3451 if( IsReference_v<Right> && right.canAlias( this ) ) {
3452 const ResultType_t<VT> tmp( right );
3453 smpDivAssign( left, tmp );
3454 }
3455 else {
3456 smpDivAssign( left, right );
3457 }
3458
3459 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3460
3461 return *this;
3462}
3464//*************************************************************************************************
3465
3466
3467//*************************************************************************************************
3480template< typename MT // Type of the dense matrix
3481 , size_t... CCAs > // Compile time column arguments
3482template< typename VT > // Type of the right-hand side vector
3483inline Column<MT,false,true,false,CCAs...>&
3484 Column<MT,false,true,false,CCAs...>::operator%=( const Vector<VT,false>& rhs )
3485{
3486 using blaze::assign;
3487
3490
3491 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
3492
3496
3497 if( size() != 3UL || (*rhs).size() != 3UL ) {
3498 BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3499 }
3500
3501 const CrossType right( *this % (*rhs) );
3502
3503 if( !tryAssign( matrix_, right, 0UL, column() ) ) {
3504 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3505 }
3506
3507 decltype(auto) left( derestrict( *this ) );
3508
3509 assign( left, right );
3510
3511 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3512
3513 return *this;
3514}
3516//*************************************************************************************************
3517
3518
3519
3520
3521//=================================================================================================
3522//
3523// UTILITY FUNCTIONS
3524//
3525//=================================================================================================
3526
3527//*************************************************************************************************
3533template< typename MT // Type of the dense matrix
3534 , size_t... CCAs > // Compile time column arguments
3535inline MT& Column<MT,false,true,false,CCAs...>::operand() noexcept
3536{
3537 return matrix_;
3538}
3540//*************************************************************************************************
3541
3542
3543//*************************************************************************************************
3549template< typename MT // Type of the dense matrix
3550 , size_t... CCAs > // Compile time column arguments
3551inline const MT& Column<MT,false,true,false,CCAs...>::operand() const noexcept
3552{
3553 return matrix_;
3554}
3556//*************************************************************************************************
3557
3558
3559//*************************************************************************************************
3565template< typename MT // Type of the dense matrix
3566 , size_t... CCAs > // Compile time column arguments
3567inline size_t Column<MT,false,true,false,CCAs...>::size() const noexcept
3568{
3569 return matrix_.rows();
3570}
3572//*************************************************************************************************
3573
3574
3575//*************************************************************************************************
3584template< typename MT // Type of the dense matrix
3585 , size_t... CCAs > // Compile time column arguments
3586inline size_t Column<MT,false,true,false,CCAs...>::spacing() const noexcept
3587{
3588 return matrix_.spacing();
3589}
3591//*************************************************************************************************
3592
3593
3594//*************************************************************************************************
3600template< typename MT // Type of the dense matrix
3601 , size_t... CCAs > // Compile time column arguments
3602inline size_t Column<MT,false,true,false,CCAs...>::capacity() const noexcept
3603{
3604 return matrix_.rows();
3605}
3607//*************************************************************************************************
3608
3609
3610//*************************************************************************************************
3619template< typename MT // Type of the dense matrix
3620 , size_t... CCAs > // Compile time column arguments
3622{
3623 const size_t rows( size() );
3624 size_t nonzeros( 0UL );
3625
3626 for( size_t i=0UL; i<rows; ++i )
3627 if( !isDefault( matrix_(i,column()) ) )
3628 ++nonzeros;
3629
3630 return nonzeros;
3631}
3633//*************************************************************************************************
3634
3635
3636//*************************************************************************************************
3642template< typename MT // Type of the dense matrix
3643 , size_t... CCAs > // Compile time column arguments
3645{
3646 using blaze::clear;
3647
3648 const size_t ibegin( ( IsLower_v<MT> )
3649 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3650 ?( column()+1UL )
3651 :( column() ) )
3652 :( 0UL ) );
3653 const size_t iend ( ( IsUpper_v<MT> )
3654 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3655 ?( column() )
3656 :( column()+1UL ) )
3657 :( size() ) );
3658
3659 for( size_t i=ibegin; i<iend; ++i )
3660 clear( matrix_(i,column()) );
3661}
3663//*************************************************************************************************
3664
3665
3666
3667
3668//=================================================================================================
3669//
3670// NUMERIC FUNCTIONS
3671//
3672//=================================================================================================
3673
3674//*************************************************************************************************
3687template< typename MT // Type of the dense matrix
3688 , size_t... CCAs > // Compile time column arguments
3689template< typename Other > // Data type of the scalar value
3690inline Column<MT,false,true,false,CCAs...>&
3691 Column<MT,false,true,false,CCAs...>::scale( const Other& scalar )
3692{
3694
3695 const size_t ibegin( ( IsLower_v<MT> )
3696 ?( ( IsStrictlyLower_v<MT> )
3697 ?( column()+1UL )
3698 :( column() ) )
3699 :( 0UL ) );
3700 const size_t iend ( ( IsUpper_v<MT> )
3701 ?( ( IsStrictlyUpper_v<MT> )
3702 ?( column() )
3703 :( column()+1UL ) )
3704 :( size() ) );
3705
3706 for( size_t i=ibegin; i<iend; ++i ) {
3707 matrix_(i,column()) *= scalar;
3708 }
3709
3710 return *this;
3711}
3713//*************************************************************************************************
3714
3715
3716
3717
3718//=================================================================================================
3719//
3720// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3721//
3722//=================================================================================================
3723
3724//*************************************************************************************************
3735template< typename MT // Type of the dense matrix
3736 , size_t... CCAs > // Compile time column arguments
3737template< typename Other > // Data type of the foreign expression
3738inline bool Column<MT,false,true,false,CCAs...>::canAlias( const Other* alias ) const noexcept
3739{
3740 return matrix_.isAliased( &unview( *alias ) );
3741}
3743//*************************************************************************************************
3744
3745
3746//*************************************************************************************************
3757template< typename MT // Type of the dense matrix
3758 , size_t... CCAs > // Compile time column arguments
3759template< typename MT2 // Data type of the foreign dense column
3760 , bool SO2 // Storage order of the foreign dense column
3761 , bool SF2 // Symmetry flag of the foreign dense column
3762 , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
3763inline bool
3764 Column<MT,false,true,false,CCAs...>::canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
3765{
3766 return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
3767}
3769//*************************************************************************************************
3770
3771
3772//*************************************************************************************************
3783template< typename MT // Type of the dense matrix
3784 , size_t... CCAs > // Compile time column arguments
3785template< typename Other > // Data type of the foreign expression
3786inline bool Column<MT,false,true,false,CCAs...>::isAliased( const Other* alias ) const noexcept
3787{
3788 return matrix_.isAliased( &unview( *alias ) );
3789}
3791//*************************************************************************************************
3792
3793
3794//*************************************************************************************************
3805template< typename MT // Type of the dense matrix
3806 , size_t... CCAs > // Compile time column arguments
3807template< typename MT2 // Data type of the foreign dense column
3808 , bool SO2 // Storage order of the foreign dense column
3809 , bool SF2 // Symmetry flag of the foreign dense column
3810 , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
3811inline bool
3812 Column<MT,false,true,false,CCAs...>::isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
3813{
3814 return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
3815}
3817//*************************************************************************************************
3818
3819
3820//*************************************************************************************************
3830template< typename MT // Type of the dense matrix
3831 , size_t... CCAs > // Compile time column arguments
3832inline bool Column<MT,false,true,false,CCAs...>::isAligned() const noexcept
3833{
3834 return false;
3835}
3837//*************************************************************************************************
3838
3839
3840//*************************************************************************************************
3851template< typename MT // Type of the dense matrix
3852 , size_t... CCAs > // Compile time column arguments
3853inline bool Column<MT,false,true,false,CCAs...>::canSMPAssign() const noexcept
3854{
3855 return ( size() > SMP_DVECASSIGN_THRESHOLD );
3856}
3858//*************************************************************************************************
3859
3860
3861//*************************************************************************************************
3873template< typename MT // Type of the dense matrix
3874 , size_t... CCAs > // Compile time column arguments
3875template< typename VT > // Type of the right-hand side dense vector
3876inline void Column<MT,false,true,false,CCAs...>::assign( const DenseVector<VT,false>& rhs )
3877{
3878 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3879
3880 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
3881 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
3882
3883 for( size_t i=0UL; i<ipos; i+=2UL ) {
3884 matrix_(i ,column()) = (*rhs)[i ];
3885 matrix_(i+1UL,column()) = (*rhs)[i+1UL];
3886 }
3887 if( ipos < (*rhs).size() )
3888 matrix_(ipos,column()) = (*rhs)[ipos];
3889}
3891//*************************************************************************************************
3892
3893
3894//*************************************************************************************************
3906template< typename MT // Type of the dense matrix
3907 , size_t... CCAs > // Compile time column arguments
3908template< typename VT > // Type of the right-hand side sparse vector
3909inline void Column<MT,false,true,false,CCAs...>::assign( const SparseVector<VT,false>& rhs )
3910{
3911 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3912
3913 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
3914 matrix_(element->index(),column()) = element->value();
3915}
3917//*************************************************************************************************
3918
3919
3920//*************************************************************************************************
3932template< typename MT // Type of the dense matrix
3933 , size_t... CCAs > // Compile time column arguments
3934template< typename VT > // Type of the right-hand side dense vector
3935inline void Column<MT,false,true,false,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
3936{
3937 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3938
3939 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
3940 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
3941
3942 for( size_t i=0UL; i<ipos; i+=2UL ) {
3943 matrix_(i ,column()) += (*rhs)[i ];
3944 matrix_(i+1UL,column()) += (*rhs)[i+1UL];
3945 }
3946 if( ipos < (*rhs).size() )
3947 matrix_(ipos,column()) += (*rhs)[ipos];
3948}
3950//*************************************************************************************************
3951
3952
3953//*************************************************************************************************
3965template< typename MT // Type of the dense matrix
3966 , size_t... CCAs > // Compile time column arguments
3967template< typename VT > // Type of the right-hand side sparse vector
3968inline void Column<MT,false,true,false,CCAs...>::addAssign( const SparseVector<VT,false>& rhs )
3969{
3970 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3971
3972 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
3973 matrix_(element->index(),column()) += element->value();
3974}
3976//*************************************************************************************************
3977
3978
3979//*************************************************************************************************
3991template< typename MT // Type of the dense matrix
3992 , size_t... CCAs > // Compile time column arguments
3993template< typename VT > // Type of the right-hand side dense vector
3994inline void Column<MT,false,true,false,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
3995{
3996 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
3997
3998 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
3999 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
4000
4001 for( size_t i=0UL; i<ipos; i+=2UL ) {
4002 matrix_(i ,column()) -= (*rhs)[i ];
4003 matrix_(i+1UL,column()) -= (*rhs)[i+1UL];
4004 }
4005 if( ipos < (*rhs).size() )
4006 matrix_(ipos,column()) -= (*rhs)[ipos];
4007}
4009//*************************************************************************************************
4010
4011
4012//*************************************************************************************************
4024template< typename MT // Type of the dense matrix
4025 , size_t... CCAs > // Compile time column arguments
4026template< typename VT > // Type of the right-hand side sparse vector
4027inline void Column<MT,false,true,false,CCAs...>::subAssign( const SparseVector<VT,false>& rhs )
4028{
4029 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4030
4031 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
4032 matrix_(element->index(),column()) -= element->value();
4033}
4035//*************************************************************************************************
4036
4037
4038//*************************************************************************************************
4050template< typename MT // Type of the dense matrix
4051 , size_t... CCAs > // Compile time column arguments
4052template< typename VT > // Type of the right-hand side dense vector
4053inline void Column<MT,false,true,false,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
4054{
4055 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4056
4057 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
4058 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
4059
4060 for( size_t i=0UL; i<ipos; i+=2UL ) {
4061 matrix_(i ,column()) *= (*rhs)[i ];
4062 matrix_(i+1UL,column()) *= (*rhs)[i+1UL];
4063 }
4064 if( ipos < (*rhs).size() )
4065 matrix_(ipos,column()) *= (*rhs)[ipos];
4066}
4068//*************************************************************************************************
4069
4070
4071//*************************************************************************************************
4083template< typename MT // Type of the dense matrix
4084 , size_t... CCAs > // Compile time column arguments
4085template< typename VT > // Type of the right-hand side sparse vector
4086inline void Column<MT,false,true,false,CCAs...>::multAssign( const SparseVector<VT,false>& rhs )
4087{
4088 using blaze::reset;
4089
4090 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4091
4092 size_t i( 0UL );
4093
4094 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
4095 const size_t index( element->index() );
4096 for( ; i<index; ++i )
4097 reset( matrix_(i,column()) );
4098 matrix_(i,column()) *= element->value();
4099 ++i;
4100 }
4101
4102 for( ; i<size(); ++i ) {
4103 reset( matrix_(i,column()) );
4104 }
4105}
4107//*************************************************************************************************
4108
4109
4110//*************************************************************************************************
4122template< typename MT // Type of the dense matrix
4123 , size_t... CCAs > // Compile time column arguments
4124template< typename VT > // Type of the right-hand side dense vector
4125inline void Column<MT,false,true,false,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
4126{
4127 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
4128
4129 const size_t ipos( prevMultiple( (*rhs).size(), 2UL ) );
4130 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).size(), "Invalid end calculation" );
4131
4132 for( size_t i=0UL; i<ipos; i+=2UL ) {
4133 matrix_(i ,column()) /= (*rhs)[i ];
4134 matrix_(i+1UL,column()) /= (*rhs)[i+1UL];
4135 }
4136 if( ipos < (*rhs).size() )
4137 matrix_(ipos,column()) /= (*rhs)[ipos];
4138}
4140//*************************************************************************************************
4141
4142
4143
4144
4145
4146
4147
4148
4149//=================================================================================================
4150//
4151// CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
4152//
4153//=================================================================================================
4154
4155//*************************************************************************************************
4163template< typename MT // Type of the dense matrix
4164 , size_t... CCAs > // Compile time column arguments
4165class Column<MT,false,true,true,CCAs...>
4166 : public View< DenseVector< Column<MT,false,true,true,CCAs...>, false > >
4167 , private ColumnData<CCAs...>
4168{
4169 private:
4170 //**Type definitions****************************************************************************
4171 using DataType = ColumnData<CCAs...>;
4172 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
4173 //**********************************************************************************************
4174
4175 public:
4176 //**Type definitions****************************************************************************
4178 using This = Column<MT,false,true,true,CCAs...>;
4179
4181 using BaseType = View< DenseVector<This,false> >;
4182
4183 using ViewedType = MT;
4184 using ResultType = ColumnTrait_t<MT,CCAs...>;
4185 using TransposeType = TransposeType_t<ResultType>;
4186 using ElementType = ElementType_t<MT>;
4187 using SIMDType = SIMDTrait_t<ElementType>;
4188 using ReturnType = ReturnType_t<MT>;
4189 using CompositeType = const Column&;
4190
4192 using ConstReference = ConstReference_t<MT>;
4193
4195 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
4196
4198 using ConstPointer = ConstPointer_t<MT>;
4199
4201 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
4202
4204 using ConstIterator = ConstIterator_t<MT>;
4205
4207 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
4208 //**********************************************************************************************
4209
4210 //**Compilation flags***************************************************************************
4212 static constexpr bool simdEnabled = MT::simdEnabled;
4213
4215 static constexpr bool smpAssignable = MT::smpAssignable;
4216
4218 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4219 //**********************************************************************************************
4220
4221 //**Constructors********************************************************************************
4224 template< typename... RCAs >
4225 explicit inline Column( MT& matrix, RCAs... args );
4226
4227 Column( const Column& ) = default;
4229 //**********************************************************************************************
4230
4231 //**Destructor**********************************************************************************
4234 ~Column() = default;
4236 //**********************************************************************************************
4237
4238 //**Data access functions***********************************************************************
4241 inline Reference operator[]( size_t index );
4242 inline ConstReference operator[]( size_t index ) const;
4243 inline Reference at( size_t index );
4244 inline ConstReference at( size_t index ) const;
4245 inline Pointer data () noexcept;
4246 inline ConstPointer data () const noexcept;
4247 inline Iterator begin ();
4248 inline ConstIterator begin () const;
4249 inline ConstIterator cbegin() const;
4250 inline Iterator end ();
4251 inline ConstIterator end () const;
4252 inline ConstIterator cend () const;
4254 //**********************************************************************************************
4255
4256 //**Assignment operators************************************************************************
4259 inline Column& operator=( const ElementType& rhs );
4260 inline Column& operator=( initializer_list<ElementType> list );
4261 inline Column& operator=( const Column& rhs );
4262
4263 template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
4264 template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
4265 template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
4266 template< typename VT > inline Column& operator*=( const Vector<VT,false>& rhs );
4267 template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
4268 template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
4270 //**********************************************************************************************
4271
4272 //**Utility functions***************************************************************************
4275 using DataType::column;
4276
4277 inline MT& operand() noexcept;
4278 inline const MT& operand() const noexcept;
4279
4280 inline size_t size() const noexcept;
4281 inline size_t spacing() const noexcept;
4282 inline size_t capacity() const noexcept;
4283 inline size_t nonZeros() const;
4284 inline void reset();
4286 //**********************************************************************************************
4287
4288 //**Numeric functions***************************************************************************
4291 template< typename Other > inline Column& scale( const Other& scalar );
4293 //**********************************************************************************************
4294
4295 private:
4296 //**********************************************************************************************
4298 template< typename VT >
4299 static constexpr bool VectorizedAssign_v =
4300 ( useOptimizedKernels &&
4301 simdEnabled && VT::simdEnabled &&
4302 IsSIMDCombinable_v< ElementType, ElementType_t<VT> > );
4303 //**********************************************************************************************
4304
4305 //**********************************************************************************************
4307 template< typename VT >
4308 static constexpr bool VectorizedAddAssign_v =
4309 ( VectorizedAssign_v<VT> &&
4310 HasSIMDAdd_v< ElementType, ElementType_t<VT> > );
4311 //**********************************************************************************************
4312
4313 //**********************************************************************************************
4315 template< typename VT >
4316 static constexpr bool VectorizedSubAssign_v =
4317 ( VectorizedAssign_v<VT> &&
4318 HasSIMDSub_v< ElementType, ElementType_t<VT> > );
4319 //**********************************************************************************************
4320
4321 //**********************************************************************************************
4323 template< typename VT >
4324 static constexpr bool VectorizedMultAssign_v =
4325 ( VectorizedAssign_v<VT> &&
4326 HasSIMDMult_v< ElementType, ElementType_t<VT> > );
4327 //**********************************************************************************************
4328
4329 //**********************************************************************************************
4331 template< typename VT >
4332 static constexpr bool VectorizedDivAssign_v =
4333 ( VectorizedAssign_v<VT> &&
4334 HasSIMDDiv_v< ElementType, ElementType_t<VT> > );
4335 //**********************************************************************************************
4336
4337 //**SIMD properties*****************************************************************************
4339 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
4340 //**********************************************************************************************
4341
4342 public:
4343 //**Expression template evaluation functions****************************************************
4346 template< typename Other >
4347 inline bool canAlias( const Other* alias ) const noexcept;
4348
4349 template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
4350 inline bool canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
4351
4352 template< typename Other >
4353 inline bool isAliased( const Other* alias ) const noexcept;
4354
4355 template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
4356 inline bool isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
4357
4358 inline bool isAligned () const noexcept;
4359 inline bool canSMPAssign() const noexcept;
4360
4361 BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4362 BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4363 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4364
4365 BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4366 BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4367 BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4368 BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4369
4370 template< typename VT >
4371 inline auto assign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
4372
4373 template< typename VT >
4374 inline auto assign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
4375
4376 template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
4377
4378 template< typename VT >
4379 inline auto addAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
4380
4381 template< typename VT >
4382 inline auto addAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
4383
4384 template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
4385
4386 template< typename VT >
4387 inline auto subAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
4388
4389 template< typename VT >
4390 inline auto subAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
4391
4392 template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
4393
4394 template< typename VT >
4395 inline auto multAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
4396
4397 template< typename VT >
4398 inline auto multAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
4399
4400 template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
4401
4402 template< typename VT >
4403 inline auto divAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
4404
4405 template< typename VT >
4406 inline auto divAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT> >;
4408 //**********************************************************************************************
4409
4410 private:
4411 //**Member variables****************************************************************************
4414 Operand matrix_;
4416 //**********************************************************************************************
4417
4418 //**Friend declarations*************************************************************************
4419 template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Column;
4420 //**********************************************************************************************
4421
4422 //**Compile time checks*************************************************************************
4431 //**********************************************************************************************
4432};
4434//*************************************************************************************************
4435
4436
4437
4438
4439//=================================================================================================
4440//
4441// CONSTRUCTORS
4442//
4443//=================================================================================================
4444
4445//*************************************************************************************************
4458template< typename MT // Type of the dense matrix
4459 , size_t... CCAs > // Compile time column arguments
4460template< typename... RCAs > // Runtime column arguments
4461inline Column<MT,false,true,true,CCAs...>::Column( MT& matrix, RCAs... args )
4462 : DataType( args... ) // Base class initialization
4463 , matrix_ ( matrix ) // The matrix containing the column
4464{
4465 if( isChecked( args... ) ) {
4466 if( matrix_.columns() <= column() ) {
4467 BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
4468 }
4469 }
4470 else {
4471 BLAZE_USER_ASSERT( column() < matrix_.columns(), "Invalid column access index" );
4472 }
4473}
4475//*************************************************************************************************
4476
4477
4478
4479
4480//=================================================================================================
4481//
4482// DATA ACCESS FUNCTIONS
4483//
4484//=================================================================================================
4485
4486//*************************************************************************************************
4496template< typename MT // Type of the dense matrix
4497 , size_t... CCAs > // Compile time column arguments
4498inline typename Column<MT,false,true,true,CCAs...>::Reference
4499 Column<MT,false,true,true,CCAs...>::operator[]( size_t index )
4500{
4501 BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4502 return matrix_(column(),index);
4503}
4505//*************************************************************************************************
4506
4507
4508//*************************************************************************************************
4518template< typename MT // Type of the dense matrix
4519 , size_t... CCAs > // Compile time column arguments
4520inline typename Column<MT,false,true,true,CCAs...>::ConstReference
4521 Column<MT,false,true,true,CCAs...>::operator[]( size_t index ) const
4522{
4523 BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4524 return const_cast<const MT&>( matrix_ )(column(),index);
4525}
4527//*************************************************************************************************
4528
4529
4530//*************************************************************************************************
4541template< typename MT // Type of the dense matrix
4542 , size_t... CCAs > // Compile time column arguments
4543inline typename Column<MT,false,true,true,CCAs...>::Reference
4544 Column<MT,false,true,true,CCAs...>::at( size_t index )
4545{
4546 if( index >= size() ) {
4547 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4548 }
4549 return (*this)[index];
4550}
4552//*************************************************************************************************
4553
4554
4555//*************************************************************************************************
4566template< typename MT // Type of the dense matrix
4567 , size_t... CCAs > // Compile time column arguments
4568inline typename Column<MT,false,true,true,CCAs...>::ConstReference
4569 Column<MT,false,true,true,CCAs...>::at( size_t index ) const
4570{
4571 if( index >= size() ) {
4572 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4573 }
4574 return (*this)[index];
4575}
4577//*************************************************************************************************
4578
4579
4580//*************************************************************************************************
4589template< typename MT // Type of the dense matrix
4590 , size_t... CCAs > // Compile time column arguments
4591inline typename Column<MT,false,true,true,CCAs...>::Pointer
4593{
4594 return matrix_.data( column() );
4595}
4597//*************************************************************************************************
4598
4599
4600//*************************************************************************************************
4609template< typename MT // Type of the dense matrix
4610 , size_t... CCAs > // Compile time column arguments
4611inline typename Column<MT,false,true,true,CCAs...>::ConstPointer
4613{
4614 return matrix_.data( column() );
4615}
4617//*************************************************************************************************
4618
4619
4620//*************************************************************************************************
4628template< typename MT // Type of the dense matrix
4629 , size_t... CCAs > // Compile time column arguments
4630inline typename Column<MT,false,true,true,CCAs...>::Iterator
4632{
4633 return matrix_.begin( column() );
4634}
4636//*************************************************************************************************
4637
4638
4639//*************************************************************************************************
4647template< typename MT // Type of the dense matrix
4648 , size_t... CCAs > // Compile time column arguments
4649inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4651{
4652 return matrix_.cbegin( column() );
4653}
4655//*************************************************************************************************
4656
4657
4658//*************************************************************************************************
4666template< typename MT // Type of the dense matrix
4667 , size_t... CCAs > // Compile time column arguments
4668inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4670{
4671 return matrix_.cbegin( column() );
4672}
4674//*************************************************************************************************
4675
4676
4677//*************************************************************************************************
4685template< typename MT // Type of the dense matrix
4686 , size_t... CCAs > // Compile time column arguments
4687inline typename Column<MT,false,true,true,CCAs...>::Iterator
4689{
4690 return matrix_.end( column() );
4691}
4693//*************************************************************************************************
4694
4695
4696//*************************************************************************************************
4704template< typename MT // Type of the dense matrix
4705 , size_t... CCAs > // Compile time column arguments
4706inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4708{
4709 return matrix_.cend( column() );
4710}
4712//*************************************************************************************************
4713
4714
4715//*************************************************************************************************
4723template< typename MT // Type of the dense matrix
4724 , size_t... CCAs > // Compile time column arguments
4725inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4727{
4728 return matrix_.cend( column() );
4729}
4731//*************************************************************************************************
4732
4733
4734
4735
4736//=================================================================================================
4737//
4738// ASSIGNMENT OPERATORS
4739//
4740//=================================================================================================
4741
4742//*************************************************************************************************
4749template< typename MT // Type of the dense matrix
4750 , size_t... CCAs > // Compile time column arguments
4751inline Column<MT,false,true,true,CCAs...>&
4752 Column<MT,false,true,true,CCAs...>::operator=( const ElementType& rhs )
4753{
4754 decltype(auto) left( derestrict( matrix_ ) );
4755
4756 const size_t jbegin( ( IsUpper_v<MT> )
4757 ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
4758 ?( column()+1UL )
4759 :( column() ) )
4760 :( 0UL ) );
4761 const size_t jend ( ( IsLower_v<MT> )
4762 ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
4763 ?( column() )
4764 :( column()+1UL ) )
4765 :( size() ) );
4766
4767 for( size_t j=jbegin; j<jend; ++j ) {
4768 if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, column(), j, rhs ) )
4769 left(column(),j) = rhs;
4770 }
4771
4772 return *this;
4773}
4775//*************************************************************************************************
4776
4777
4778//*************************************************************************************************
4793template< typename MT // Type of the dense matrix
4794 , size_t... CCAs > // Compile time column arguments
4795inline Column<MT,false,true,true,CCAs...>&
4796 Column<MT,false,true,true,CCAs...>::operator=( initializer_list<ElementType> list )
4797{
4798 if( list.size() > size() ) {
4799 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
4800 }
4801
4802 if( IsRestricted_v<MT> ) {
4803 const InitializerVector<ElementType,false> tmp( list, size() );
4804 if( !tryAssign( matrix_, tmp, 0UL, column() ) ) {
4805 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4806 }
4807 }
4808
4809 decltype(auto) left( derestrict( *this ) );
4810
4811 std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
4812
4813 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4814
4815 return *this;
4816}
4818//*************************************************************************************************
4819
4820
4821//*************************************************************************************************
4835template< typename MT // Type of the dense matrix
4836 , size_t... CCAs > // Compile time column arguments
4837inline Column<MT,false,true,true,CCAs...>&
4838 Column<MT,false,true,true,CCAs...>::operator=( const Column& rhs )
4839{
4840 if( &rhs == this ) return *this;
4841
4842 if( size() != rhs.size() ) {
4843 BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
4844 }
4845
4846 if( !tryAssign( matrix_, rhs, 0UL, column() ) ) {
4847 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4848 }
4849
4850 decltype(auto) left( derestrict( *this ) );
4851
4852 if( IsExpression_v<MT> && rhs.canAlias( this ) ) {
4853 const ResultType tmp( rhs );
4854 smpAssign( left, tmp );
4855 }
4856 else {
4857 smpAssign( left, rhs );
4858 }
4859
4860 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4861
4862 return *this;
4863}
4865//*************************************************************************************************
4866
4867
4868//*************************************************************************************************
4882template< typename MT // Type of the dense matrix
4883 , size_t... CCAs > // Compile time column arguments
4884template< typename VT > // Type of the right-hand side vector
4885inline Column<MT,false,true,true,CCAs...>&
4886 Column<MT,false,true,true,CCAs...>::operator=( const Vector<VT,false>& rhs )
4887{
4890
4891 if( size() != (*rhs).size() ) {
4892 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4893 }
4894
4895 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
4896 Right right( *rhs );
4897
4898 if( !tryAssign( matrix_, right, 0UL, column() ) ) {
4899 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4900 }
4901
4902 decltype(auto) left( derestrict( *this ) );
4903
4904 if( IsReference_v<Right> && right.canAlias( this ) ) {
4905 const ResultType_t<VT> tmp( right );
4906 smpAssign( left, tmp );
4907 }
4908 else {
4909 if( IsSparseVector_v<VT> )
4910 reset();
4911 smpAssign( left, right );
4912 }
4913
4914 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4915
4916 return *this;
4917}
4919//*************************************************************************************************
4920
4921
4922//*************************************************************************************************
4936template< typename MT // Type of the dense matrix
4937 , size_t... CCAs > // Compile time column arguments
4938template< typename VT > // Type of the right-hand side vector
4939inline Column<MT,false,true,true,CCAs...>&
4940 Column<MT,false,true,true,CCAs...>::operator+=( const Vector<VT,false>& rhs )
4941{
4944
4945 if( size() != (*rhs).size() ) {
4946 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4947 }
4948
4949 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
4950 Right right( *rhs );
4951
4952 if( !tryAddAssign( matrix_, right, 0UL, column() ) ) {
4953 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4954 }
4955
4956 decltype(auto) left( derestrict( *this ) );
4957
4958 if( IsReference_v<Right> && right.canAlias( this ) ) {
4959 const ResultType_t<VT> tmp( right );
4960 smpAddAssign( left, tmp );
4961 }
4962 else {
4963 smpAddAssign( left, right );
4964 }
4965
4966 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4967
4968 return *this;
4969}
4971//*************************************************************************************************
4972
4973
4974//*************************************************************************************************
4988template< typename MT // Type of the dense matrix
4989 , size_t... CCAs > // Compile time column arguments
4990template< typename VT > // Type of the right-hand side vector
4991inline Column<MT,false,true,true,CCAs...>&
4992 Column<MT,false,true,true,CCAs...>::operator-=( const Vector<VT,false>& rhs )
4993{
4996
4997 if( size() != (*rhs).size() ) {
4998 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4999 }
5000
5001 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
5002 Right right( *rhs );
5003
5004 if( !trySubAssign( matrix_, right, 0UL, column() ) ) {
5005 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5006 }
5007
5008 decltype(auto) left( derestrict( *this ) );
5009
5010 if( IsReference_v<Right> && right.canAlias( this ) ) {
5011 const ResultType_t<VT> tmp( right );
5012 smpSubAssign( left, tmp );
5013 }
5014 else {
5015 smpSubAssign( left, right );
5016 }
5017
5018 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5019
5020 return *this;
5021}
5023//*************************************************************************************************
5024
5025
5026//*************************************************************************************************
5039template< typename MT // Type of the dense matrix
5040 , size_t... CCAs > // Compile time column arguments
5041template< typename VT > // Type of the right-hand side vector
5042inline Column<MT,false,true,true,CCAs...>&
5043 Column<MT,false,true,true,CCAs...>::operator*=( const Vector<VT,false>& rhs )
5044{
5047
5048 if( size() != (*rhs).size() ) {
5049 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5050 }
5051
5052 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
5053 Right right( *rhs );
5054
5055 if( !tryMultAssign( matrix_, right, 0UL, column() ) ) {
5056 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5057 }
5058
5059 decltype(auto) left( derestrict( *this ) );
5060
5061 if( IsReference_v<Right> && right.canAlias( this ) ) {
5062 const ResultType_t<VT> tmp( right );
5063 smpMultAssign( left, tmp );
5064 }
5065 else {
5066 smpMultAssign( left, right );
5067 }
5068
5069 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5070
5071 return *this;
5072}
5074//*************************************************************************************************
5075
5076
5077//*************************************************************************************************
5089template< typename MT // Type of the dense matrix
5090 , size_t... CCAs > // Compile time column arguments
5091template< typename VT > // Type of the right-hand side dense vector
5092inline Column<MT,false,true,true,CCAs...>&
5093 Column<MT,false,true,true,CCAs...>::operator/=( const DenseVector<VT,false>& rhs )
5094{
5097
5098 if( size() != (*rhs).size() ) {
5099 BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5100 }
5101
5102 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
5103 Right right( *rhs );
5104
5105 if( !tryDivAssign( matrix_, right, 0UL, column() ) ) {
5106 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5107 }
5108
5109 decltype(auto) left( derestrict( *this ) );
5110
5111 if( IsReference_v<Right> && right.canAlias( this ) ) {
5112 const ResultType_t<VT> tmp( right );
5113 smpDivAssign( left, tmp );
5114 }
5115 else {
5116 smpDivAssign( left, right );
5117 }
5118
5119 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5120
5121 return *this;
5122}
5124//*************************************************************************************************
5125
5126
5127//*************************************************************************************************
5140template< typename MT // Type of the dense matrix
5141 , size_t... CCAs > // Compile time column arguments
5142template< typename VT > // Type of the right-hand side vector
5143inline Column<MT,false,true,true,CCAs...>&
5144 Column<MT,false,true,true,CCAs...>::operator%=( const Vector<VT,false>& rhs )
5145{
5146 using blaze::assign;
5147
5150
5151 using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
5152
5156
5157 if( size() != 3UL || (*rhs).size() != 3UL ) {
5158 BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
5159 }
5160
5161 const CrossType right( *this % (*rhs) );
5162
5163 if( !tryAssign( matrix_, right, 0UL, column() ) ) {
5164 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5165 }
5166
5167 decltype(auto) left( derestrict( *this ) );
5168
5169 assign( left, right );
5170
5171 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5172
5173 return *this;
5174}
5176//*************************************************************************************************
5177
5178
5179
5180
5181//=================================================================================================
5182//
5183// UTILITY FUNCTIONS
5184//
5185//=================================================================================================
5186
5187//*************************************************************************************************
5193template< typename MT // Type of the dense matrix
5194 , size_t... CCAs > // Compile time column arguments
5195inline MT& Column<MT,false,true,true,CCAs...>::operand() noexcept
5196{
5197 return matrix_;
5198}
5200//*************************************************************************************************
5201
5202
5203//*************************************************************************************************
5209template< typename MT // Type of the dense matrix
5210 , size_t... CCAs > // Compile time column arguments
5211inline const MT& Column<MT,false,true,true,CCAs...>::operand() const noexcept
5212{
5213 return matrix_;
5214}
5216//*************************************************************************************************
5217
5218
5219//*************************************************************************************************
5225template< typename MT // Type of the dense matrix
5226 , size_t... CCAs > // Compile time column arguments
5227inline size_t Column<MT,false,true,true,CCAs...>::size() const noexcept
5228{
5229 return matrix_.rows();
5230}
5232//*************************************************************************************************
5233
5234
5235//*************************************************************************************************
5244template< typename MT // Type of the dense matrix
5245 , size_t... CCAs > // Compile time column arguments
5246inline size_t Column<MT,false,true,true,CCAs...>::spacing() const noexcept
5247{
5248 return matrix_.spacing();
5249}
5251//*************************************************************************************************
5252
5253
5254//*************************************************************************************************
5260template< typename MT // Type of the dense matrix
5261 , size_t... CCAs > // Compile time column arguments
5262inline size_t Column<MT,false,true,true,CCAs...>::capacity() const noexcept
5263{
5264 return matrix_.capacity( column() );
5265}
5267//*************************************************************************************************
5268
5269
5270//*************************************************************************************************
5279template< typename MT // Type of the dense matrix
5280 , size_t... CCAs > // Compile time column arguments
5282{
5283 return matrix_.nonZeros( column() );
5284}
5286//*************************************************************************************************
5287
5288
5289//*************************************************************************************************
5295template< typename MT // Type of the dense matrix
5296 , size_t... CCAs > // Compile time column arguments
5298{
5299 matrix_.reset( column() );
5300}
5302//*************************************************************************************************
5303
5304
5305
5306
5307//=================================================================================================
5308//
5309// NUMERIC FUNCTIONS
5310//
5311//=================================================================================================
5312
5313//*************************************************************************************************
5326template< typename MT // Type of the dense matrix
5327 , size_t... CCAs > // Compile time column arguments
5328template< typename Other > // Data type of the scalar value
5329inline Column<MT,false,true,true,CCAs...>&
5330 Column<MT,false,true,true,CCAs...>::scale( const Other& scalar )
5331{
5333
5334 const size_t jbegin( ( IsUpper_v<MT> )
5335 ?( ( IsStrictlyUpper_v<MT> )
5336 ?( column()+1UL )
5337 :( column() ) )
5338 :( 0UL ) );
5339 const size_t jend ( ( IsLower_v<MT> )
5340 ?( ( IsStrictlyLower_v<MT> )
5341 ?( column() )
5342 :( column()+1UL ) )
5343 :( size() ) );
5344
5345 for( size_t j=jbegin; j<jend; ++j ) {
5346 matrix_(column(),j) *= scalar;
5347 }
5348
5349 return *this;
5350}
5352//*************************************************************************************************
5353
5354
5355
5356
5357//=================================================================================================
5358//
5359// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5360//
5361//=================================================================================================
5362
5363//*************************************************************************************************
5374template< typename MT // Type of the dense matrix
5375 , size_t... CCAs > // Compile time column arguments
5376template< typename Other > // Data type of the foreign expression
5377inline bool Column<MT,false,true,true,CCAs...>::canAlias( const Other* alias ) const noexcept
5378{
5379 return matrix_.isAliased( &unview( *alias ) );
5380}
5382//*************************************************************************************************
5383
5384
5385//*************************************************************************************************
5396template< typename MT // Type of the dense matrix
5397 , size_t... CCAs > // Compile time column arguments
5398template< typename MT2 // Data type of the foreign dense column
5399 , bool SO2 // Storage order of the foreign dense column
5400 , bool SF2 // Symmetry flag of the foreign dense column
5401 , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
5402inline bool
5403 Column<MT,false,true,true,CCAs...>::canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5404{
5405 return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
5406}
5408//*************************************************************************************************
5409
5410
5411//*************************************************************************************************
5422template< typename MT // Type of the dense matrix
5423 , size_t... CCAs > // Compile time column arguments
5424template< typename Other > // Data type of the foreign expression
5425inline bool Column<MT,false,true,true,CCAs...>::isAliased( const Other* alias ) const noexcept
5426{
5427 return matrix_.isAliased( &unview( *alias ) );
5428}
5430//*************************************************************************************************
5431
5432
5433//*************************************************************************************************
5444template< typename MT // Type of the dense matrix
5445 , size_t... CCAs > // Compile time column arguments
5446template< typename MT2 // Data type of the foreign dense column
5447 , bool SO2 // Storage order of the foreign dense column
5448 , bool SF2 // Symmetry flag of the foreign dense column
5449 , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
5450inline bool
5451 Column<MT,false,true,true,CCAs...>::isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5452{
5453 return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
5454}
5456//*************************************************************************************************
5457
5458
5459//*************************************************************************************************
5469template< typename MT // Type of the dense matrix
5470 , size_t... CCAs > // Compile time column arguments
5471inline bool Column<MT,false,true,true,CCAs...>::isAligned() const noexcept
5472{
5473 return matrix_.isAligned();
5474}
5476//*************************************************************************************************
5477
5478
5479//*************************************************************************************************
5490template< typename MT // Type of the dense matrix
5491 , size_t... CCAs > // Compile time column arguments
5492inline bool Column<MT,false,true,true,CCAs...>::canSMPAssign() const noexcept
5493{
5494 return ( size() > SMP_DVECASSIGN_THRESHOLD );
5495}
5497//*************************************************************************************************
5498
5499
5500//*************************************************************************************************
5512template< typename MT // Type of the dense matrix
5513 , size_t... CCAs > // Compile time column arguments
5514BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true,CCAs...>::SIMDType
5515 Column<MT,false,true,true,CCAs...>::load( size_t index ) const noexcept
5516{
5517 return matrix_.load( column(), index );
5518}
5520//*************************************************************************************************
5521
5522
5523//*************************************************************************************************
5536template< typename MT // Type of the dense matrix
5537 , size_t... CCAs > // Compile time column arguments
5538BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true,CCAs...>::SIMDType
5539 Column<MT,false,true,true,CCAs...>::loada( size_t index ) const noexcept
5540{
5541 return matrix_.loada( column(), index );
5542}
5544//*************************************************************************************************
5545
5546
5547//*************************************************************************************************
5560template< typename MT // Type of the dense matrix
5561 , size_t... CCAs > // Compile time column arguments
5562BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true,CCAs...>::SIMDType
5563 Column<MT,false,true,true,CCAs...>::loadu( size_t index ) const noexcept
5564{
5565 return matrix_.loadu( column(), index );
5566}
5568//*************************************************************************************************
5569
5570
5571//*************************************************************************************************
5584template< typename MT // Type of the dense matrix
5585 , size_t... CCAs > // Compile time column arguments
5587 Column<MT,false,true,true,CCAs...>::store( size_t index, const SIMDType& value ) noexcept
5588{
5589 matrix_.store( column(), index, value );
5590}
5592//*************************************************************************************************
5593
5594
5595//*************************************************************************************************
5609template< typename MT // Type of the dense matrix
5610 , size_t... CCAs > // Compile time column arguments
5612 Column<MT,false,true,true,CCAs...>::storea( size_t index, const SIMDType& value ) noexcept
5613{
5614 matrix_.storea( column(), index, value );
5615}
5617//*************************************************************************************************
5618
5619
5620//*************************************************************************************************
5634template< typename MT // Type of the dense matrix
5635 , size_t... CCAs > // Compile time column arguments
5637 Column<MT,false,true,true,CCAs...>::storeu( size_t index, const SIMDType& value ) noexcept
5638{
5639 matrix_.storeu( column(), index, value );
5640}
5642//*************************************************************************************************
5643
5644
5645//*************************************************************************************************
5659template< typename MT // Type of the dense matrix
5660 , size_t... CCAs > // Compile time column arguments
5662 Column<MT,false,true,true,CCAs...>::stream( size_t index, const SIMDType& value ) noexcept
5663{
5664 matrix_.stream( column(), index, value );
5665}
5667//*************************************************************************************************
5668
5669
5670//*************************************************************************************************
5682template< typename MT // Type of the dense matrix
5683 , size_t... CCAs > // Compile time column arguments
5684template< typename VT > // Type of the right-hand side dense vector
5685inline auto Column<MT,false,true,true,CCAs...>::assign( const DenseVector<VT,false>& rhs )
5686 -> DisableIf_t< VectorizedAssign_v<VT> >
5687{
5688 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5689
5690 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
5691 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
5692
5693 for( size_t j=0UL; j<jpos; j+=2UL ) {
5694 matrix_(column(),j ) = (*rhs)[j ];
5695 matrix_(column(),j+1UL) = (*rhs)[j+1UL];
5696 }
5697 if( jpos < (*rhs).size() )
5698 matrix_(column(),jpos) = (*rhs)[jpos];
5699}
5701//*************************************************************************************************
5702
5703
5704//*************************************************************************************************
5716template< typename MT // Type of the dense matrix
5717 , size_t... CCAs > // Compile time column arguments
5718template< typename VT > // Type of the right-hand side dense vector
5719inline auto Column<MT,false,true,true,CCAs...>::assign( const DenseVector<VT,false>& rhs )
5720 -> EnableIf_t< VectorizedAssign_v<VT> >
5721{
5723
5724 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5725
5726 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5727
5728 const size_t columns( size() );
5729
5730 const size_t jpos( remainder ? prevMultiple( columns, SIMDSIZE ) : columns );
5731 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
5732
5733 size_t j( 0UL );
5734 Iterator left( begin() );
5735 ConstIterator_t<VT> right( (*rhs).begin() );
5736
5737 if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(*rhs).isAliased( this ) )
5738 {
5739 for( ; j<jpos; j+=SIMDSIZE ) {
5740 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5741 }
5742 for( ; remainder && j<columns; ++j ) {
5743 *left = *right; ++left; ++right;
5744 }
5745 }
5746 else
5747 {
5748 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5749 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5750 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5751 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5752 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5753 }
5754 for( ; j<jpos; j+=SIMDSIZE ) {
5755 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5756 }
5757 for( ; remainder && j<columns; ++j ) {
5758 *left = *right; ++left; ++right;
5759 }
5760 }
5761}
5763//*************************************************************************************************
5764
5765
5766//*************************************************************************************************
5778template< typename MT // Type of the dense matrix
5779 , size_t... CCAs > // Compile time column arguments
5780template< typename VT > // Type of the right-hand side sparse vector
5781inline void Column<MT,false,true,true,CCAs...>::assign( const SparseVector<VT,false>& rhs )
5782{
5783 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5784
5785 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
5786 matrix_(column(),element->index()) = element->value();
5787}
5789//*************************************************************************************************
5790
5791
5792//*************************************************************************************************
5804template< typename MT // Type of the dense matrix
5805 , size_t... CCAs > // Compile time column arguments
5806template< typename VT > // Type of the right-hand side dense vector
5807inline auto Column<MT,false,true,true,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
5808 -> DisableIf_t< VectorizedAddAssign_v<VT> >
5809{
5810 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5811
5812 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
5813 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
5814
5815 for( size_t j=0UL; j<jpos; j+=2UL ) {
5816 matrix_(column(),j ) += (*rhs)[j ];
5817 matrix_(column(),j+1UL) += (*rhs)[j+1UL];
5818 }
5819 if( jpos < (*rhs).size() )
5820 matrix_(column(),jpos) += (*rhs)[jpos];
5821}
5823//*************************************************************************************************
5824
5825
5826//*************************************************************************************************
5838template< typename MT // Type of the dense matrix
5839 , size_t... CCAs > // Compile time column arguments
5840template< typename VT > // Type of the right-hand side dense vector
5841inline auto Column<MT,false,true,true,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
5842 -> EnableIf_t< VectorizedAddAssign_v<VT> >
5843{
5845
5846 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5847
5848 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5849
5850 const size_t columns( size() );
5851
5852 const size_t jpos( remainder ? prevMultiple( columns, SIMDSIZE ) : columns );
5853 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
5854
5855 size_t j( 0UL );
5856 Iterator left( begin() );
5857 ConstIterator_t<VT> right( (*rhs).begin() );
5858
5859 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5860 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5861 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5862 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5863 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5864 }
5865 for( ; j<jpos; j+=SIMDSIZE ) {
5866 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5867 }
5868 for( ; remainder && j<columns; ++j ) {
5869 *left += *right; ++left; ++right;
5870 }
5871}
5873//*************************************************************************************************
5874
5875
5876//*************************************************************************************************
5888template< typename MT // Type of the dense matrix
5889 , size_t... CCAs > // Compile time column arguments
5890template< typename VT > // Type of the right-hand side sparse vector
5891inline void Column<MT,false,true,true,CCAs...>::addAssign( const SparseVector<VT,false>& rhs )
5892{
5893 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5894
5895 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
5896 matrix_(column(),element->index()) += element->value();
5897}
5899//*************************************************************************************************
5900
5901
5902//*************************************************************************************************
5914template< typename MT // Type of the dense matrix
5915 , size_t... CCAs > // Compile time column arguments
5916template< typename VT > // Type of the right-hand side dense vector
5917inline auto Column<MT,false,true,true,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
5918 -> DisableIf_t< VectorizedSubAssign_v<VT> >
5919{
5920 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5921
5922 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
5923 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
5924
5925 for( size_t j=0UL; j<jpos; j+=2UL ) {
5926 matrix_(column(),j ) -= (*rhs)[j ];
5927 matrix_(column(),j+1UL) -= (*rhs)[j+1UL];
5928 }
5929 if( jpos < (*rhs).size() )
5930 matrix_(column(),jpos) -= (*rhs)[jpos];
5931}
5933//*************************************************************************************************
5934
5935
5936//*************************************************************************************************
5948template< typename MT // Type of the dense matrix
5949 , size_t... CCAs > // Compile time column arguments
5950template< typename VT > // Type of the right-hand side dense vector
5951inline auto Column<MT,false,true,true,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
5952 -> EnableIf_t< VectorizedSubAssign_v<VT> >
5953{
5955
5956 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
5957
5958 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5959
5960 const size_t columns( size() );
5961
5962 const size_t jpos( remainder ? prevMultiple( columns, SIMDSIZE ) : columns );
5963 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
5964
5965 size_t j( 0UL );
5966 Iterator left( begin() );
5967 ConstIterator_t<VT> right( (*rhs).begin() );
5968
5969 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5970 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5971 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5972 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5973 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5974 }
5975 for( ; j<jpos; j+=SIMDSIZE ) {
5976 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5977 }
5978 for( ; remainder && j<columns; ++j ) {
5979 *left -= *right; ++left; ++right;
5980 }
5981}
5983//*************************************************************************************************
5984
5985
5986//*************************************************************************************************
5998template< typename MT // Type of the dense matrix
5999 , size_t... CCAs > // Compile time column arguments
6000template< typename VT > // Type of the right-hand side sparse vector
6001inline void Column<MT,false,true,true,CCAs...>::subAssign( const SparseVector<VT,false>& rhs )
6002{
6003 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6004
6005 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element )
6006 matrix_(column(),element->index()) -= element->value();
6007}
6009//*************************************************************************************************
6010
6011
6012//*************************************************************************************************
6024template< typename MT // Type of the dense matrix
6025 , size_t... CCAs > // Compile time column arguments
6026template< typename VT > // Type of the right-hand side dense vector
6027inline auto Column<MT,false,true,true,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
6028 -> DisableIf_t< VectorizedMultAssign_v<VT> >
6029{
6030 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6031
6032 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
6033 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
6034
6035 for( size_t j=0UL; j<jpos; j+=2UL ) {
6036 matrix_(column(),j ) *= (*rhs)[j ];
6037 matrix_(column(),j+1UL) *= (*rhs)[j+1UL];
6038 }
6039 if( jpos < (*rhs).size() )
6040 matrix_(column(),jpos) *= (*rhs)[jpos];
6041}
6043//*************************************************************************************************
6044
6045
6046//*************************************************************************************************
6058template< typename MT // Type of the dense matrix
6059 , size_t... CCAs > // Compile time column arguments
6060template< typename VT > // Type of the right-hand side dense vector
6061inline auto Column<MT,false,true,true,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
6062 -> EnableIf_t< VectorizedMultAssign_v<VT> >
6063{
6065
6066 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6067
6068 constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
6069
6070 const size_t columns( size() );
6071
6072 const size_t jpos( remainder ? prevMultiple( columns, SIMDSIZE ) : columns );
6073 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
6074
6075 size_t j( 0UL );
6076 Iterator left( begin() );
6077 ConstIterator_t<VT> right( (*rhs).begin() );
6078
6079 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
6080 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6081 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6082 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6083 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6084 }
6085 for( ; j<jpos; j+=SIMDSIZE ) {
6086 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6087 }
6088 for( ; remainder && j<columns; ++j ) {
6089 *left *= *right; ++left; ++right;
6090 }
6091}
6093//*************************************************************************************************
6094
6095
6096//*************************************************************************************************
6108template< typename MT // Type of the dense matrix
6109 , size_t... CCAs > // Compile time column arguments
6110template< typename VT > // Type of the right-hand side sparse vector
6111inline void Column<MT,false,true,true,CCAs...>::multAssign( const SparseVector<VT,false>& rhs )
6112{
6113 using blaze::reset;
6114
6115 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6116
6117 size_t j( 0UL );
6118
6119 for( ConstIterator_t<VT> element=(*rhs).begin(); element!=(*rhs).end(); ++element ) {
6120 const size_t index( element->index() );
6121 for( ; j<index; ++j )
6122 reset( matrix_(column(),j) );
6123 matrix_(column(),j) *= element->value();
6124 ++j;
6125 }
6126
6127 for( ; j<size(); ++j ) {
6128 reset( matrix_(column(),j) );
6129 }
6130}
6132//*************************************************************************************************
6133
6134
6135//*************************************************************************************************
6147template< typename MT // Type of the dense matrix
6148 , size_t... CCAs > // Compile time column arguments
6149template< typename VT > // Type of the right-hand side dense vector
6150inline auto Column<MT,false,true,true,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
6151 -> DisableIf_t< VectorizedDivAssign_v<VT> >
6152{
6153 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6154
6155 const size_t jpos( prevMultiple( (*rhs).size(), 2UL ) );
6156 BLAZE_INTERNAL_ASSERT( jpos <= (*rhs).size(), "Invalid end calculation" );
6157
6158 for( size_t j=0UL; j<jpos; j+=2UL ) {
6159 matrix_(column(),j ) /= (*rhs)[j ];
6160 matrix_(column(),j+1UL) /= (*rhs)[j+1UL];
6161 }
6162 if( jpos < (*rhs).size() )
6163 matrix_(column(),jpos) /= (*rhs)[jpos];
6164}
6166//*************************************************************************************************
6167
6168
6169//*************************************************************************************************
6181template< typename MT // Type of the dense matrix
6182 , size_t... CCAs > // Compile time column arguments
6183template< typename VT > // Type of the right-hand side dense vector
6184inline auto Column<MT,false,true,true,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
6185 -> EnableIf_t< VectorizedDivAssign_v<VT> >
6186{
6188
6189 BLAZE_INTERNAL_ASSERT( size() == (*rhs).size(), "Invalid vector sizes" );
6190
6191 const size_t columns( size() );
6192
6193 const size_t jpos( prevMultiple( columns, SIMDSIZE ) );
6194 BLAZE_INTERNAL_ASSERT( jpos <= columns, "Invalid end calculation" );
6195
6196 size_t j( 0UL );
6197 Iterator left( begin() );
6198 ConstIterator_t<VT> right( (*rhs).begin() );
6199
6200 for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
6201 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6202 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6203 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6204 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6205 }
6206 for( ; j<jpos; j+=SIMDSIZE ) {
6207 left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6208 }
6209 for( ; j<columns; ++j ) {
6210 *left /= *right; ++left; ++right;
6211 }
6212}
6214//*************************************************************************************************
6215
6216} // namespace blaze
6217
6218#endif
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
Header file for the blaze::checked and blaze::unchecked instances.
Header file for the implementation of the ColumnData class template.
Constraints on the storage order of matrix types.
Header file for the column trait.
Constraint on the transpose flag of vector 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.
Constraints on the storage order of matrix 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_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.
Definition: ColumnVector.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 ColumnTrait< MT, CCAs... >::Type ColumnTrait_t
Auxiliary alias declaration for the ColumnTrait type trait.
Definition: ColumnTrait.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 Column base template.