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>
56 #include <blaze/math/Exception.h>
60 #include <blaze/math/shims/Clear.h>
62 #include <blaze/math/SIMD.h>
81 #include <blaze/system/CacheSize.h>
82 #include <blaze/system/Inline.h>
85 #include <blaze/util/Assert.h>
89 #include <blaze/util/DisableIf.h>
90 #include <blaze/util/EnableIf.h>
91 #include <blaze/util/mpl/If.h>
92 #include <blaze/util/mpl/Not.h>
93 #include <blaze/util/mpl/Or.h>
94 #include <blaze/util/Template.h>
95 #include <blaze/util/TrueType.h>
96 #include <blaze/util/Types.h>
101 
102 
103 namespace blaze {
104 
105 //=================================================================================================
106 //
107 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR DENSE MATRICES
108 //
109 //=================================================================================================
110 
111 //*************************************************************************************************
119 template< typename MT // Type of the dense matrix
120  , bool SF > // Symmetry flag
121 class Column<MT,true,true,SF>
122  : public View< DenseVector< Column<MT,true,true,SF>, false > >
123 {
124  private:
125  //**Type definitions****************************************************************************
127  using Operand = If_< IsExpression<MT>, MT, MT& >;
128  //**********************************************************************************************
129 
130  public:
131  //**Type definitions****************************************************************************
132  using This = Column<MT,true,true,SF>;
133  using BaseType = DenseVector<This,false>;
134  using ResultType = ColumnTrait_<MT>;
135  using TransposeType = TransposeType_<ResultType>;
136  using ElementType = ElementType_<MT>;
137  using SIMDType = SIMDTrait_<ElementType>;
138  using ReturnType = ReturnType_<MT>;
139  using CompositeType = const Column&;
140 
142  using ConstReference = ConstReference_<MT>;
143 
145  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
146 
148  using ConstPointer = const ElementType*;
149 
151  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* >;
152 
154  using ConstIterator = ConstIterator_<MT>;
155 
157  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
158  //**********************************************************************************************
159 
160  //**Compilation flags***************************************************************************
162  enum : bool { simdEnabled = MT::simdEnabled };
163 
165  enum : bool { smpAssignable = MT::smpAssignable };
166  //**********************************************************************************************
167 
168  //**Constructors********************************************************************************
171  explicit inline Column( Operand matrix, size_t index );
172  // No explicitly declared copy constructor.
174  //**********************************************************************************************
175 
176  //**Destructor**********************************************************************************
177  // No explicitly declared destructor.
178  //**********************************************************************************************
179 
180  //**Data access functions***********************************************************************
183  inline Reference operator[]( size_t index );
184  inline ConstReference operator[]( size_t index ) const;
185  inline Reference at( size_t index );
186  inline ConstReference at( size_t index ) const;
187  inline Pointer data () noexcept;
188  inline ConstPointer data () const noexcept;
189  inline Iterator begin ();
190  inline ConstIterator begin () const;
191  inline ConstIterator cbegin() const;
192  inline Iterator end ();
193  inline ConstIterator end () const;
194  inline ConstIterator cend () const;
196  //**********************************************************************************************
197 
198  //**Assignment operators************************************************************************
201  inline Column& operator=( const ElementType& rhs );
202  inline Column& operator=( initializer_list<ElementType> list );
203  inline Column& operator=( const Column& rhs );
204 
205  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
206  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
207  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
208  template< typename VT > inline Column& operator*=( const DenseVector<VT,false>& rhs );
209  template< typename VT > inline Column& operator*=( const SparseVector<VT,false>& rhs );
210  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
211  template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
212 
213  template< typename Other >
214  inline EnableIf_< IsNumeric<Other>, Column >& operator*=( Other rhs );
215 
216  template< typename Other >
217  inline EnableIf_< IsNumeric<Other>, Column >& operator/=( Other rhs );
219  //**********************************************************************************************
220 
221  //**Utility functions***************************************************************************
224  inline Operand operand() const noexcept;
225  inline size_t column() const noexcept;
226  inline size_t size() const noexcept;
227  inline size_t spacing() const noexcept;
228  inline size_t capacity() const noexcept;
229  inline size_t nonZeros() const;
230  inline void reset();
232  //**********************************************************************************************
233 
234  //**Numeric functions***************************************************************************
237  template< typename Other > inline Column& scale( const Other& scalar );
239  //**********************************************************************************************
240 
241  private:
242  //**********************************************************************************************
244  template< typename VT >
245  struct VectorizedAssign {
246  enum : bool { value = useOptimizedKernels &&
247  simdEnabled && VT::simdEnabled &&
248  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
249  };
250  //**********************************************************************************************
251 
252  //**********************************************************************************************
254  template< typename VT >
255  struct VectorizedAddAssign {
256  enum : bool { value = useOptimizedKernels &&
257  simdEnabled && VT::simdEnabled &&
258  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
259  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
260  };
261  //**********************************************************************************************
262 
263  //**********************************************************************************************
265  template< typename VT >
266  struct VectorizedSubAssign {
267  enum : bool { value = useOptimizedKernels &&
268  simdEnabled && VT::simdEnabled &&
269  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
270  HasSIMDSub< ElementType, ElementType_<VT> >::value };
271  };
272  //**********************************************************************************************
273 
274  //**********************************************************************************************
276  template< typename VT >
277  struct VectorizedMultAssign {
278  enum : bool { value = useOptimizedKernels &&
279  simdEnabled && VT::simdEnabled &&
280  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
281  HasSIMDMult< ElementType, ElementType_<VT> >::value };
282  };
283  //**********************************************************************************************
284 
285  //**********************************************************************************************
287  template< typename VT >
288  struct VectorizedDivAssign {
289  enum : bool { value = useOptimizedKernels &&
290  simdEnabled && VT::simdEnabled &&
291  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
292  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
293  };
294  //**********************************************************************************************
295 
296  //**SIMD properties*****************************************************************************
298  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
299  //**********************************************************************************************
300 
301  public:
302  //**Expression template evaluation functions****************************************************
305  template< typename Other >
306  inline bool canAlias( const Other* alias ) const noexcept;
307 
308  template< typename MT2, bool SO2, bool SF2 >
309  inline bool canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
310 
311  template< typename Other >
312  inline bool isAliased( const Other* alias ) const noexcept;
313 
314  template< typename MT2, bool SO2, bool SF2 >
315  inline bool isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
316 
317  inline bool isAligned () const noexcept;
318  inline bool canSMPAssign() const noexcept;
319 
320  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
321  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
322  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
323 
324  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
325  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
326  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
327  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
328 
329  template< typename VT >
330  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
331 
332  template< typename VT >
333  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
334 
335  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
336 
337  template< typename VT >
338  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
339 
340  template< typename VT >
341  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
342 
343  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
344 
345  template< typename VT >
346  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
347 
348  template< typename VT >
349  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
350 
351  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
352 
353  template< typename VT >
354  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
355 
356  template< typename VT >
357  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
358 
359  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
360 
361  template< typename VT >
362  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
363 
364  template< typename VT >
365  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
367  //**********************************************************************************************
368 
369  private:
370  //**Member variables****************************************************************************
373  Operand matrix_;
374  const size_t col_;
375 
376  //**********************************************************************************************
377 
378  //**Friend declarations*************************************************************************
379  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Column;
380  //**********************************************************************************************
381 
382  //**Compile time checks*************************************************************************
389  //**********************************************************************************************
390 };
392 //*************************************************************************************************
393 
394 
395 
396 
397 //=================================================================================================
398 //
399 // CONSTRUCTOR
400 //
401 //=================================================================================================
402 
403 //*************************************************************************************************
411 template< typename MT // Type of the dense matrix
412  , bool SF > // Symmetry flag
413 inline Column<MT,true,true,SF>::Column( Operand matrix, size_t index )
414  : matrix_( matrix ) // The dense matrix containing the column
415  , col_ ( index ) // The index of the column in the matrix
416 {
417  if( matrix_.columns() <= index ) {
418  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
419  }
420 }
422 //*************************************************************************************************
423 
424 
425 
426 
427 //=================================================================================================
428 //
429 // DATA ACCESS FUNCTIONS
430 //
431 //=================================================================================================
432 
433 //*************************************************************************************************
443 template< typename MT // Type of the dense matrix
444  , bool SF > // Symmetry flag
445 inline typename Column<MT,true,true,SF>::Reference Column<MT,true,true,SF>::operator[]( size_t index )
446 {
447  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
448  return matrix_(index,col_);
449 }
451 //*************************************************************************************************
452 
453 
454 //*************************************************************************************************
464 template< typename MT // Type of the dense matrix
465  , bool SF > // Symmetry flag
467  Column<MT,true,true,SF>::operator[]( size_t index ) const
468 {
469  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
470  return const_cast<const MT&>( matrix_ )(index,col_);
471 }
473 //*************************************************************************************************
474 
475 
476 //*************************************************************************************************
487 template< typename MT // Type of the dense matrix
488  , bool SF > // Symmetry flag
489 inline typename Column<MT,true,true,SF>::Reference Column<MT,true,true,SF>::at( size_t index )
490 {
491  if( index >= size() ) {
492  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
493  }
494  return (*this)[index];
495 }
497 //*************************************************************************************************
498 
499 
500 //*************************************************************************************************
511 template< typename MT // Type of the dense matrix
512  , bool SF > // Symmetry flag
514  Column<MT,true,true,SF>::at( size_t index ) const
515 {
516  if( index >= size() ) {
517  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
518  }
519  return (*this)[index];
520 }
522 //*************************************************************************************************
523 
524 
525 //*************************************************************************************************
534 template< typename MT // Type of the dense matrix
535  , bool SF > // Symmetry flag
536 inline typename Column<MT,true,true,SF>::Pointer Column<MT,true,true,SF>::data() noexcept
537 {
538  return matrix_.data( col_ );
539 }
541 //*************************************************************************************************
542 
543 
544 //*************************************************************************************************
553 template< typename MT // Type of the dense matrix
554  , bool SF > // Symmetry flag
555 inline typename Column<MT,true,true,SF>::ConstPointer Column<MT,true,true,SF>::data() const noexcept
556 {
557  return matrix_.data( col_ );
558 }
560 //*************************************************************************************************
561 
562 
563 //*************************************************************************************************
571 template< typename MT // Type of the dense matrix
572  , bool SF > // Symmetry flag
574 {
575  return matrix_.begin( col_ );
576 }
578 //*************************************************************************************************
579 
580 
581 //*************************************************************************************************
589 template< typename MT // Type of the dense matrix
590  , bool SF > // Symmetry flag
592 {
593  return matrix_.cbegin( col_ );
594 }
596 //*************************************************************************************************
597 
598 
599 //*************************************************************************************************
607 template< typename MT // Type of the dense matrix
608  , bool SF > // Symmetry flag
610 {
611  return matrix_.cbegin( col_ );
612 }
614 //*************************************************************************************************
615 
616 
617 //*************************************************************************************************
625 template< typename MT // Type of the dense matrix
626  , bool SF > // Symmetry flag
628 {
629  return matrix_.end( col_ );
630 }
632 //*************************************************************************************************
633 
634 
635 //*************************************************************************************************
643 template< typename MT // Type of the dense matrix
644  , bool SF > // Symmetry flag
646 {
647  return matrix_.cend( col_ );
648 }
650 //*************************************************************************************************
651 
652 
653 //*************************************************************************************************
661 template< typename MT // Type of the dense matrix
662  , bool SF > // Symmetry flag
664 {
665  return matrix_.cend( col_ );
666 }
668 //*************************************************************************************************
669 
670 
671 
672 
673 //=================================================================================================
674 //
675 // ASSIGNMENT OPERATORS
676 //
677 //=================================================================================================
678 
679 //*************************************************************************************************
690 template< typename MT // Type of the dense matrix
691  , bool SF > // Symmetry flag
692 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( const ElementType& rhs )
693 {
694  const size_t ibegin( ( IsLower<MT>::value )
695  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
696  ?( col_+1UL )
697  :( col_ ) )
698  :( 0UL ) );
699  const size_t iend ( ( IsUpper<MT>::value )
700  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
701  ?( col_ )
702  :( col_+1UL ) )
703  :( size() ) );
704 
705  for( size_t i=ibegin; i<iend; ++i )
706  matrix_(i,col_) = rhs;
707 
708  return *this;
709 }
711 //*************************************************************************************************
712 
713 
714 //*************************************************************************************************
727 template< typename MT // Type of the dense matrix
728  , bool SF > // Symmetry flag
729 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( initializer_list<ElementType> list )
730 {
731  if( list.size() > size() ) {
732  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
733  }
734 
735  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
736 
737  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
738 
739  return *this;
740 }
742 //*************************************************************************************************
743 
744 
745 //*************************************************************************************************
759 template< typename MT // Type of the dense matrix
760  , bool SF > // Symmetry flag
761 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( const Column& rhs )
762 {
763  if( &rhs == this ) return *this;
764 
765  if( size() != rhs.size() ) {
766  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
767  }
768 
769  if( !tryAssign( matrix_, rhs, 0UL, col_ ) ) {
770  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
771  }
772 
773  decltype(auto) left( derestrict( *this ) );
774 
775  smpAssign( left, rhs );
776 
777  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
778 
779  return *this;
780 }
782 //*************************************************************************************************
783 
784 
785 //*************************************************************************************************
799 template< typename MT // Type of the dense matrix
800  , bool SF > // Symmetry flag
801 template< typename VT > // Type of the right-hand side vector
802 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( const Vector<VT,false>& rhs )
803 {
806 
807  if( size() != (~rhs).size() ) {
808  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
809  }
810 
811  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
812  Right right( ~rhs );
813 
814  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
815  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
816  }
817 
818  decltype(auto) left( derestrict( *this ) );
819 
820  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
821  const ResultType_<VT> tmp( right );
822  smpAssign( left, tmp );
823  }
824  else {
825  if( IsSparseVector<VT>::value )
826  reset();
827  smpAssign( left, right );
828  }
829 
830  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
831 
832  return *this;
833 }
835 //*************************************************************************************************
836 
837 
838 //*************************************************************************************************
852 template< typename MT // Type of the dense matrix
853  , bool SF > // Symmetry flag
854 template< typename VT > // Type of the right-hand side vector
855 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator+=( const Vector<VT,false>& rhs )
856 {
859 
860  if( size() != (~rhs).size() ) {
861  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
862  }
863 
864  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
865  Right right( ~rhs );
866 
867  if( !tryAddAssign( matrix_, right, 0UL, col_ ) ) {
868  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
869  }
870 
871  decltype(auto) left( derestrict( *this ) );
872 
873  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
874  const ResultType_<VT> tmp( right );
875  smpAddAssign( left, tmp );
876  }
877  else {
878  smpAddAssign( left, right );
879  }
880 
881  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
882 
883  return *this;
884 }
886 //*************************************************************************************************
887 
888 
889 //*************************************************************************************************
903 template< typename MT // Type of the dense matrix
904  , bool SF > // Symmetry flag
905 template< typename VT > // Type of the right-hand side vector
906 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator-=( const Vector<VT,false>& rhs )
907 {
910 
911  if( size() != (~rhs).size() ) {
912  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
913  }
914 
915  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
916  Right right( ~rhs );
917 
918  if( !trySubAssign( matrix_, right, 0UL, col_ ) ) {
919  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
920  }
921 
922  decltype(auto) left( derestrict( *this ) );
923 
924  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
925  const ResultType_<VT> tmp( right );
926  smpSubAssign( left, tmp );
927  }
928  else {
929  smpSubAssign( left, right );
930  }
931 
932  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
933 
934  return *this;
935 }
937 //*************************************************************************************************
938 
939 
940 //*************************************************************************************************
953 template< typename MT // Type of the dense matrix
954  , bool SF > // Symmetry flag
955 template< typename VT > // Type of the right-hand side dense vector
956 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator*=( const DenseVector<VT,false>& rhs )
957 {
960 
961  if( size() != (~rhs).size() ) {
962  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
963  }
964 
965  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
966  Right right( ~rhs );
967 
968  if( !tryMultAssign( matrix_, right, 0UL, col_ ) ) {
969  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
970  }
971 
972  decltype(auto) left( derestrict( *this ) );
973 
974  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
975  const ResultType_<VT> tmp( right );
976  smpMultAssign( left, tmp );
977  }
978  else {
979  smpMultAssign( left, right );
980  }
981 
982  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
983 
984  return *this;
985 }
987 //*************************************************************************************************
988 
989 
990 //*************************************************************************************************
1003 template< typename MT // Type of the dense matrix
1004  , bool SF > // Symmetry flag
1005 template< typename VT > // Type of the right-hand side sparse vector
1006 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator*=( const SparseVector<VT,false>& rhs )
1007 {
1011 
1012  if( size() != (~rhs).size() ) {
1013  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1014  }
1015 
1016  const ResultType right( *this * (~rhs) );
1017 
1018  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
1019  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1020  }
1021 
1022  decltype(auto) left( derestrict( *this ) );
1023 
1024  smpAssign( left, right );
1025 
1026  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1027 
1028  return *this;
1029 }
1031 //*************************************************************************************************
1032 
1033 
1034 //*************************************************************************************************
1046 template< typename MT // Type of the dense matrix
1047  , bool SF > // Symmetry flag
1048 template< typename VT > // Type of the right-hand side dense vector
1049 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator/=( const DenseVector<VT,false>& rhs )
1050 {
1051  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
1053 
1054  if( size() != (~rhs).size() ) {
1055  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1056  }
1057 
1058  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
1059  Right right( ~rhs );
1060 
1061  if( !tryDivAssign( matrix_, right, 0UL, col_ ) ) {
1062  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1063  }
1064 
1065  decltype(auto) left( derestrict( *this ) );
1066 
1067  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1068  const ResultType_<VT> tmp( right );
1069  smpDivAssign( left, tmp );
1070  }
1071  else {
1072  smpDivAssign( left, right );
1073  }
1074 
1075  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1076 
1077  return *this;
1078 }
1080 //*************************************************************************************************
1081 
1082 
1083 //*************************************************************************************************
1096 template< typename MT // Type of the dense matrix
1097  , bool SF > // Symmetry flag
1098 template< typename VT > // Type of the right-hand side vector
1099 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator%=( const Vector<VT,false>& rhs )
1100 {
1101  using blaze::assign;
1102 
1103  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
1105 
1106  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
1107 
1111 
1112  if( size() != 3UL || (~rhs).size() != 3UL ) {
1113  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1114  }
1115 
1116  const CrossType right( *this % (~rhs) );
1117 
1118  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
1119  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1120  }
1121 
1122  decltype(auto) left( derestrict( *this ) );
1123 
1124  assign( left, right );
1125 
1126  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1127 
1128  return *this;
1129 }
1131 //*************************************************************************************************
1132 
1133 
1134 //*************************************************************************************************
1145 template< typename MT // Type of the dense matrix
1146  , bool SF > // Symmetry flag
1147 template< typename Other > // Data type of the right-hand side scalar
1148 inline EnableIf_< IsNumeric<Other>, Column<MT,true,true,SF> >&
1149  Column<MT,true,true,SF>::operator*=( Other rhs )
1150 {
1152 
1153  return operator=( (*this) * rhs );
1154 }
1156 //*************************************************************************************************
1157 
1158 
1159 //*************************************************************************************************
1172 template< typename MT // Type of the dense matrix
1173  , bool SF > // Symmetry flag
1174 template< typename Other > // Data type of the right-hand side scalar
1175 inline EnableIf_< IsNumeric<Other>, Column<MT,true,true,SF> >&
1177 {
1179 
1180  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1181 
1182  return operator=( (*this) / rhs );
1183 }
1185 //*************************************************************************************************
1186 
1187 
1188 
1189 
1190 //=================================================================================================
1191 //
1192 // UTILITY FUNCTIONS
1193 //
1194 //=================================================================================================
1195 
1196 //*************************************************************************************************
1202 template< typename MT // Type of the dense matrix
1203  , bool SF > // Symmetry flag
1204 inline typename Column<MT,true,true,SF>::Operand
1205  Column<MT,true,true,SF>::operand() const noexcept
1206 {
1207  return matrix_;
1208 }
1210 //*************************************************************************************************
1211 
1212 
1213 //*************************************************************************************************
1219 template< typename MT // Type of the dense matrix
1220  , bool SF > // Symmetry flag
1221 inline size_t Column<MT,true,true,SF>::column() const noexcept
1222 {
1223  return col_;
1224 }
1226 //*************************************************************************************************
1227 
1228 
1229 //*************************************************************************************************
1235 template< typename MT // Type of the dense matrix
1236  , bool SF > // Symmetry flag
1237 inline size_t Column<MT,true,true,SF>::size() const noexcept
1238 {
1239  return matrix_.rows();
1240 }
1242 //*************************************************************************************************
1243 
1244 
1245 //*************************************************************************************************
1254 template< typename MT // Type of the dense matrix
1255  , bool SF > // Symmetry flag
1256 inline size_t Column<MT,true,true,SF>::spacing() const noexcept
1257 {
1258  return matrix_.spacing();
1259 }
1261 //*************************************************************************************************
1262 
1263 
1264 //*************************************************************************************************
1270 template< typename MT // Type of the dense matrix
1271  , bool SF > // Symmetry flag
1272 inline size_t Column<MT,true,true,SF>::capacity() const noexcept
1273 {
1274  return matrix_.capacity( col_ );
1275 }
1277 //*************************************************************************************************
1278 
1279 
1280 //*************************************************************************************************
1289 template< typename MT // Type of the dense matrix
1290  , bool SF > // Symmetry flag
1291 inline size_t Column<MT,true,true,SF>::nonZeros() const
1292 {
1293  return matrix_.nonZeros( col_ );
1294 }
1296 //*************************************************************************************************
1297 
1298 
1299 //*************************************************************************************************
1305 template< typename MT // Type of the dense matrix
1306  , bool SF > // Symmetry flag
1307 inline void Column<MT,true,true,SF>::reset()
1308 {
1309  matrix_.reset( col_ );
1310 }
1312 //*************************************************************************************************
1313 
1314 
1315 
1316 
1317 //=================================================================================================
1318 //
1319 // NUMERIC FUNCTIONS
1320 //
1321 //=================================================================================================
1322 
1323 //*************************************************************************************************
1336 template< typename MT // Type of the dense matrix
1337  , bool SF > // Symmetry flag
1338 template< typename Other > // Data type of the scalar value
1339 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::scale( const Other& scalar )
1340 {
1342 
1343  const size_t ibegin( ( IsLower<MT>::value )
1344  ?( ( IsStrictlyLower<MT>::value )
1345  ?( col_+1UL )
1346  :( col_ ) )
1347  :( 0UL ) );
1348  const size_t iend ( ( IsUpper<MT>::value )
1349  ?( ( IsStrictlyUpper<MT>::value )
1350  ?( col_ )
1351  :( col_+1UL ) )
1352  :( size() ) );
1353 
1354  for( size_t i=ibegin; i<iend; ++i ) {
1355  matrix_(i,col_) *= scalar;
1356  }
1357 
1358  return *this;
1359 }
1361 //*************************************************************************************************
1362 
1363 
1364 
1365 
1366 //=================================================================================================
1367 //
1368 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1369 //
1370 //=================================================================================================
1371 
1372 //*************************************************************************************************
1383 template< typename MT // Type of the dense matrix
1384  , bool SF > // Symmetry flag
1385 template< typename Other > // Data type of the foreign expression
1386 inline bool Column<MT,true,true,SF>::canAlias( const Other* alias ) const noexcept
1387 {
1388  return matrix_.isAliased( alias );
1389 }
1391 //*************************************************************************************************
1392 
1393 
1394 //*************************************************************************************************
1405 template< typename MT // Type of the dense matrix
1406  , bool SF > // Symmetry flag
1407 template< typename MT2 // Data type of the foreign dense column
1408  , bool SO2 // Storage order of the foreign dense column
1409  , bool SF2 > // Symmetry flag of the foreign dense column
1410 inline bool Column<MT,true,true,SF>::canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
1411 {
1412  return matrix_.isAliased( alias->matrix_ ) && ( col_ == alias->col_ );
1413 }
1415 //*************************************************************************************************
1416 
1417 
1418 //*************************************************************************************************
1429 template< typename MT // Type of the dense matrix
1430  , bool SF > // Symmetry flag
1431 template< typename Other > // Data type of the foreign expression
1432 inline bool Column<MT,true,true,SF>::isAliased( const Other* alias ) const noexcept
1433 {
1434  return matrix_.isAliased( alias );
1435 }
1437 //*************************************************************************************************
1438 
1439 
1440 //*************************************************************************************************
1451 template< typename MT // Type of the dense matrix
1452  , bool SF > // Symmetry flag
1453 template< typename MT2 // Data type of the foreign dense column
1454  , bool SO2 // Storage order of the foreign dense column
1455  , bool SF2 > // Symmetry flag of the foreign dense column
1456 inline bool Column<MT,true,true,SF>::isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
1457 {
1458  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
1459 }
1461 //*************************************************************************************************
1462 
1463 
1464 //*************************************************************************************************
1474 template< typename MT // Type of the dense matrix
1475  , bool SF > // Symmetry flag
1476 inline bool Column<MT,true,true,SF>::isAligned() const noexcept
1477 {
1478  return matrix_.isAligned();
1479 }
1481 //*************************************************************************************************
1482 
1483 
1484 //*************************************************************************************************
1495 template< typename MT // Type of the dense matrix
1496  , bool SF > // Symmetry flag
1497 inline bool Column<MT,true,true,SF>::canSMPAssign() const noexcept
1498 {
1499  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1500 }
1502 //*************************************************************************************************
1503 
1504 
1505 //*************************************************************************************************
1517 template< typename MT // Type of the dense matrix
1518  , bool SF > // Symmetry flag
1519 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF>::SIMDType
1520  Column<MT,true,true,SF>::load( size_t index ) const noexcept
1521 {
1522  return matrix_.load( index, col_ );
1523 }
1525 //*************************************************************************************************
1526 
1527 
1528 //*************************************************************************************************
1541 template< typename MT // Type of the dense matrix
1542  , bool SF > // Symmetry flag
1543 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF>::SIMDType
1544  Column<MT,true,true,SF>::loada( size_t index ) const noexcept
1545 {
1546  return matrix_.loada( index, col_ );
1547 }
1549 //*************************************************************************************************
1550 
1551 
1552 //*************************************************************************************************
1565 template< typename MT // Type of the dense matrix
1566  , bool SF > // Symmetry flag
1567 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF>::SIMDType
1568  Column<MT,true,true,SF>::loadu( size_t index ) const noexcept
1569 {
1570  return matrix_.loadu( index, col_ );
1571 }
1573 //*************************************************************************************************
1574 
1575 
1576 //*************************************************************************************************
1589 template< typename MT // Type of the dense matrix
1590  , bool SF > // Symmetry flag
1592  Column<MT,true,true,SF>::store( size_t index, const SIMDType& value ) noexcept
1593 {
1594  matrix_.store( index, col_, value );
1595 }
1597 //*************************************************************************************************
1598 
1599 
1600 //*************************************************************************************************
1614 template< typename MT // Type of the dense matrix
1615  , bool SF > // Symmetry flag
1617  Column<MT,true,true,SF>::storea( size_t index, const SIMDType& value ) noexcept
1618 {
1619  matrix_.storea( index, col_, value );
1620 }
1622 //*************************************************************************************************
1623 
1624 
1625 //*************************************************************************************************
1639 template< typename MT // Type of the dense matrix
1640  , bool SF > // Symmetry flag
1642  Column<MT,true,true,SF>::storeu( size_t index, const SIMDType& value ) noexcept
1643 {
1644  matrix_.storeu( index, col_, value );
1645 }
1647 //*************************************************************************************************
1648 
1649 
1650 //*************************************************************************************************
1664 template< typename MT // Type of the dense matrix
1665  , bool SF > // Symmetry flag
1667  Column<MT,true,true,SF>::stream( size_t index, const SIMDType& value ) noexcept
1668 {
1669  matrix_.stream( index, col_, value );
1670 }
1672 //*************************************************************************************************
1673 
1674 
1675 //*************************************************************************************************
1687 template< typename MT // Type of the dense matrix
1688  , bool SF > // Symmetry flag
1689 template< typename VT > // Type of the right-hand side dense vector
1690 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1691  Column<MT,true,true,SF>::assign( const DenseVector<VT,false>& rhs )
1692 {
1693  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1694 
1695  const size_t ipos( (~rhs).size() & size_t(-2) );
1696  for( size_t i=0UL; i<ipos; i+=2UL ) {
1697  matrix_(i ,col_) = (~rhs)[i ];
1698  matrix_(i+1UL,col_) = (~rhs)[i+1UL];
1699  }
1700  if( ipos < (~rhs).size() )
1701  matrix_(ipos,col_) = (~rhs)[ipos];
1702 }
1704 //*************************************************************************************************
1705 
1706 
1707 //*************************************************************************************************
1719 template< typename MT // Type of the dense matrix
1720  , bool SF > // Symmetry flag
1721 template< typename VT > // Type of the right-hand side dense vector
1722 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1723  Column<MT,true,true,SF>::assign( const DenseVector<VT,false>& rhs )
1724 {
1726 
1727  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1728 
1729  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1730 
1731  const size_t rows( size() );
1732 
1733  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1734  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1735 
1736  size_t i( 0UL );
1737  Iterator left( begin() );
1738  ConstIterator_<VT> right( (~rhs).begin() );
1739 
1740  if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
1741  {
1742  for( ; i<ipos; i+=SIMDSIZE ) {
1743  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1744  }
1745  for( ; remainder && i<rows; ++i ) {
1746  *left = *right; ++left; ++right;
1747  }
1748  }
1749  else
1750  {
1751  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1752  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1753  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1754  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1755  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1756  }
1757  for( ; i<ipos; i+=SIMDSIZE ) {
1758  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1759  }
1760  for( ; remainder && i<rows; ++i ) {
1761  *left = *right; ++left; ++right;
1762  }
1763  }
1764 }
1766 //*************************************************************************************************
1767 
1768 
1769 //*************************************************************************************************
1781 template< typename MT // Type of the dense matrix
1782  , bool SF > // Symmetry flag
1783 template< typename VT > // Type of the right-hand side sparse vector
1784 inline void Column<MT,true,true,SF>::assign( const SparseVector<VT,false>& rhs )
1785 {
1786  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1787 
1788  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1789  matrix_(element->index(),col_) = element->value();
1790 }
1792 //*************************************************************************************************
1793 
1794 
1795 //*************************************************************************************************
1807 template< typename MT // Type of the dense matrix
1808  , bool SF > // Symmetry flag
1809 template< typename VT > // Type of the right-hand side dense vector
1810 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1811  Column<MT,true,true,SF>::addAssign( const DenseVector<VT,false>& rhs )
1812 {
1813  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1814 
1815  const size_t ipos( (~rhs).size() & size_t(-2) );
1816  for( size_t i=0UL; i<ipos; i+=2UL ) {
1817  matrix_(i ,col_) += (~rhs)[i ];
1818  matrix_(i+1UL,col_) += (~rhs)[i+1UL];
1819  }
1820  if( ipos < (~rhs).size() )
1821  matrix_(ipos,col_) += (~rhs)[ipos];
1822 }
1824 //*************************************************************************************************
1825 
1826 
1827 //*************************************************************************************************
1839 template< typename MT // Type of the dense matrix
1840  , bool SF > // Symmetry flag
1841 template< typename VT > // Type of the right-hand side dense vector
1842 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1843  Column<MT,true,true,SF>::addAssign( const DenseVector<VT,false>& rhs )
1844 {
1846 
1847  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1848 
1849  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1850 
1851  const size_t rows( size() );
1852 
1853  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1854  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1855 
1856  size_t i( 0UL );
1857  Iterator left( begin() );
1858  ConstIterator_<VT> right( (~rhs).begin() );
1859 
1860  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1861  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1862  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1863  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1864  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1865  }
1866  for( ; i<ipos; i+=SIMDSIZE ) {
1867  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1868  }
1869  for( ; remainder && i<rows; ++i ) {
1870  *left += *right; ++left; ++right;
1871  }
1872 }
1874 //*************************************************************************************************
1875 
1876 
1877 //*************************************************************************************************
1889 template< typename MT // Type of the dense matrix
1890  , bool SF > // Symmetry flag
1891 template< typename VT > // Type of the right-hand side sparse vector
1892 inline void Column<MT,true,true,SF>::addAssign( const SparseVector<VT,false>& rhs )
1893 {
1894  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1895 
1896  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1897  matrix_(element->index(),col_) += element->value();
1898 }
1900 //*************************************************************************************************
1901 
1902 
1903 //*************************************************************************************************
1915 template< typename MT // Type of the dense matrix
1916  , bool SF > // Symmetry flag
1917 template< typename VT > // Type of the right-hand side dense vector
1918 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1919  Column<MT,true,true,SF>::subAssign( const DenseVector<VT,false>& rhs )
1920 {
1921  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1922 
1923  const size_t ipos( (~rhs).size() & size_t(-2) );
1924  for( size_t i=0UL; i<ipos; i+=2UL ) {
1925  matrix_(i ,col_) -= (~rhs)[i ];
1926  matrix_(i+1UL,col_) -= (~rhs)[i+1UL];
1927  }
1928  if( ipos < (~rhs).size() )
1929  matrix_(ipos,col_) -= (~rhs)[ipos];
1930 }
1932 //*************************************************************************************************
1933 
1934 
1935 //*************************************************************************************************
1947 template< typename MT // Type of the dense matrix
1948  , bool SF > // Symmetry flag
1949 template< typename VT > // Type of the right-hand side dense vector
1950 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1951  Column<MT,true,true,SF>::subAssign( const DenseVector<VT,false>& rhs )
1952 {
1954 
1955  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1956 
1957  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1958 
1959  const size_t rows( size() );
1960 
1961  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1962  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1963 
1964  size_t i( 0UL );
1965  Iterator left( begin() );
1966  ConstIterator_<VT> right( (~rhs).begin() );
1967 
1968  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1969  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1970  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1971  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1972  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1973  }
1974  for( ; i<ipos; i+=SIMDSIZE ) {
1975  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1976  }
1977  for( ; remainder && i<rows; ++i ) {
1978  *left -= *right; ++left; ++right;
1979  }
1980 }
1982 //*************************************************************************************************
1983 
1984 
1985 //*************************************************************************************************
1997 template< typename MT // Type of the dense matrix
1998  , bool SF > // Symmetry flag
1999 template< typename VT > // Type of the right-hand side sparse vector
2000 inline void Column<MT,true,true,SF>::subAssign( const SparseVector<VT,false>& rhs )
2001 {
2002  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2003 
2004  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2005  matrix_(element->index(),col_) -= element->value();
2006 }
2008 //*************************************************************************************************
2009 
2010 
2011 //*************************************************************************************************
2023 template< typename MT // Type of the dense matrix
2024  , bool SF > // Symmetry flag
2025 template< typename VT > // Type of the right-hand side dense vector
2026 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
2027  Column<MT,true,true,SF>::multAssign( const DenseVector<VT,false>& rhs )
2028 {
2029  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2030 
2031  const size_t ipos( (~rhs).size() & size_t(-2) );
2032  for( size_t i=0UL; i<ipos; i+=2UL ) {
2033  matrix_(i ,col_) *= (~rhs)[i ];
2034  matrix_(i+1UL,col_) *= (~rhs)[i+1UL];
2035  }
2036  if( ipos < (~rhs).size() )
2037  matrix_(ipos,col_) *= (~rhs)[ipos];
2038 }
2040 //*************************************************************************************************
2041 
2042 
2043 //*************************************************************************************************
2055 template< typename MT // Type of the dense matrix
2056  , bool SF > // Symmetry flag
2057 template< typename VT > // Type of the right-hand side dense vector
2058 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
2059  Column<MT,true,true,SF>::multAssign( const DenseVector<VT,false>& rhs )
2060 {
2062 
2063  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2064 
2065  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
2066 
2067  const size_t rows( size() );
2068 
2069  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
2070  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2071 
2072  size_t i( 0UL );
2073  Iterator left( begin() );
2074  ConstIterator_<VT> right( (~rhs).begin() );
2075 
2076  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2077  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2078  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2079  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2080  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2081  }
2082  for( ; i<ipos; i+=SIMDSIZE ) {
2083  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2084  }
2085  for( ; remainder && i<rows; ++i ) {
2086  *left *= *right; ++left, ++right;
2087  }
2088 }
2090 //*************************************************************************************************
2091 
2092 
2093 //*************************************************************************************************
2105 template< typename MT // Type of the dense matrix
2106  , bool SF > // Symmetry flag
2107 template< typename VT > // Type of the right-hand side sparse vector
2108 inline void Column<MT,true,true,SF>::multAssign( const SparseVector<VT,false>& rhs )
2109 {
2110  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2111 
2112  const ResultType tmp( serial( *this ) );
2113 
2114  reset();
2115 
2116  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2117  matrix_(element->index(),col_) = tmp[element->index()] * element->value();
2118 }
2120 //*************************************************************************************************
2121 
2122 
2123 //*************************************************************************************************
2135 template< typename MT // Type of the dense matrix
2136  , bool SF > // Symmetry flag
2137 template< typename VT > // Type of the right-hand side dense vector
2138 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2139  Column<MT,true,true,SF>::divAssign( const DenseVector<VT,false>& rhs )
2140 {
2141  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2142 
2143  const size_t ipos( (~rhs).size() & size_t(-2) );
2144  for( size_t i=0UL; i<ipos; i+=2UL ) {
2145  matrix_(i ,col_) /= (~rhs)[i ];
2146  matrix_(i+1UL,col_) /= (~rhs)[i+1UL];
2147  }
2148  if( ipos < (~rhs).size() )
2149  matrix_(ipos,col_) /= (~rhs)[ipos];
2150 }
2152 //*************************************************************************************************
2153 
2154 
2155 //*************************************************************************************************
2167 template< typename MT // Type of the dense matrix
2168  , bool SF > // Symmetry flag
2169 template< typename VT > // Type of the right-hand side dense vector
2170 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2171  Column<MT,true,true,SF>::divAssign( const DenseVector<VT,false>& rhs )
2172 {
2174 
2175  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2176 
2177  const size_t rows( size() );
2178 
2179  const size_t ipos( rows & size_t(-SIMDSIZE) );
2180  BLAZE_INTERNAL_ASSERT( ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2181 
2182  size_t i( 0UL );
2183  Iterator left( begin() );
2184  ConstIterator_<VT> right( (~rhs).begin() );
2185 
2186  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2187  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2188  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2189  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2190  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2191  }
2192  for( ; i<ipos; i+=SIMDSIZE ) {
2193  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2194  }
2195  for( ; i<rows; ++i ) {
2196  *left /= *right; ++left; ++right;
2197  }
2198 }
2200 //*************************************************************************************************
2201 
2202 
2203 
2204 
2205 
2206 
2207 
2208 
2209 //=================================================================================================
2210 //
2211 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
2212 //
2213 //=================================================================================================
2214 
2215 //*************************************************************************************************
2223 template< typename MT > // Type of the dense matrix
2224 class Column<MT,false,true,false>
2225  : public View< DenseVector< Column<MT,false,true,false>, false > >
2226 {
2227  private:
2228  //**Type definitions****************************************************************************
2230  using Operand = If_< IsExpression<MT>, MT, MT& >;
2231  //**********************************************************************************************
2232 
2233  public:
2234  //**Type definitions****************************************************************************
2235  using This = Column<MT,false,true,false>;
2236  using BaseType = DenseVector<This,false>;
2237  using ResultType = ColumnTrait_<MT>;
2238  using TransposeType = TransposeType_<ResultType>;
2239  using ElementType = ElementType_<MT>;
2240  using ReturnType = ReturnType_<MT>;
2241  using CompositeType = const Column&;
2242 
2244  using ConstReference = ConstReference_<MT>;
2245 
2247  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
2248 
2250  using ConstPointer = const ElementType*;
2251 
2253  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* >;
2254  //**********************************************************************************************
2255 
2256  //**ColumnIterator class definition*************************************************************
2259  template< typename MatrixType > // Type of the dense matrix
2260  class ColumnIterator
2261  {
2262  public:
2263  //**Type definitions*************************************************************************
2265  using Reference = If_< IsConst<MatrixType>, ConstReference_<MatrixType>, Reference_<MatrixType> >;
2266 
2267  using IteratorCategory = std::random_access_iterator_tag;
2268  using ValueType = RemoveReference_<Reference>;
2269  using PointerType = ValueType*;
2270  using ReferenceType = Reference;
2271  using DifferenceType = ptrdiff_t;
2272 
2273  // STL iterator requirements
2274  using iterator_category = IteratorCategory;
2275  using value_type = ValueType;
2276  using pointer = PointerType;
2277  using reference = ReferenceType;
2278  using difference_type = DifferenceType;
2279  //*******************************************************************************************
2280 
2281  //**Constructor******************************************************************************
2284  inline ColumnIterator() noexcept
2285  : matrix_( nullptr ) // The dense matrix containing the column.
2286  , row_ ( 0UL ) // The current row index.
2287  , column_( 0UL ) // The current column index.
2288  {}
2289  //*******************************************************************************************
2290 
2291  //**Constructor******************************************************************************
2298  inline ColumnIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2299  : matrix_( &matrix ) // The dense matrix containing the column.
2300  , row_ ( row ) // The current row index.
2301  , column_( column ) // The current column index.
2302  {}
2303  //*******************************************************************************************
2304 
2305  //**Constructor******************************************************************************
2310  template< typename MatrixType2 >
2311  inline ColumnIterator( const ColumnIterator<MatrixType2>& it ) noexcept
2312  : matrix_( it.matrix_ ) // The dense matrix containing the column.
2313  , row_ ( it.row_ ) // The current row index.
2314  , column_( it.column_ ) // The current column index.
2315  {}
2316  //*******************************************************************************************
2317 
2318  //**Addition assignment operator*************************************************************
2324  inline ColumnIterator& operator+=( size_t inc ) noexcept {
2325  row_ += inc;
2326  return *this;
2327  }
2328  //*******************************************************************************************
2329 
2330  //**Subtraction assignment operator**********************************************************
2336  inline ColumnIterator& operator-=( size_t dec ) noexcept {
2337  row_ -= dec;
2338  return *this;
2339  }
2340  //*******************************************************************************************
2341 
2342  //**Prefix increment operator****************************************************************
2347  inline ColumnIterator& operator++() noexcept {
2348  ++row_;
2349  return *this;
2350  }
2351  //*******************************************************************************************
2352 
2353  //**Postfix increment operator***************************************************************
2358  inline const ColumnIterator operator++( int ) noexcept {
2359  const ColumnIterator tmp( *this );
2360  ++(*this);
2361  return tmp;
2362  }
2363  //*******************************************************************************************
2364 
2365  //**Prefix decrement operator****************************************************************
2370  inline ColumnIterator& operator--() noexcept {
2371  --row_;
2372  return *this;
2373  }
2374  //*******************************************************************************************
2375 
2376  //**Postfix decrement operator***************************************************************
2381  inline const ColumnIterator operator--( int ) noexcept {
2382  const ColumnIterator tmp( *this );
2383  --(*this);
2384  return tmp;
2385  }
2386  //*******************************************************************************************
2387 
2388  //**Subscript operator***********************************************************************
2394  inline ReferenceType operator[]( size_t index ) const {
2395  return (*matrix_)(row_+index,column_);
2396  }
2397  //*******************************************************************************************
2398 
2399  //**Element access operator******************************************************************
2404  inline ReferenceType operator*() const {
2405  return (*matrix_)(row_,column_);
2406  }
2407  //*******************************************************************************************
2408 
2409  //**Element access operator******************************************************************
2414  inline PointerType operator->() const {
2415  return &(*matrix_)(row_,column_);
2416  }
2417  //*******************************************************************************************
2418 
2419  //**Equality operator************************************************************************
2425  template< typename MatrixType2 >
2426  inline bool operator==( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2427  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
2428  }
2429  //*******************************************************************************************
2430 
2431  //**Inequality operator**********************************************************************
2437  template< typename MatrixType2 >
2438  inline bool operator!=( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2439  return !( *this == rhs );
2440  }
2441  //*******************************************************************************************
2442 
2443  //**Less-than operator***********************************************************************
2449  template< typename MatrixType2 >
2450  inline bool operator<( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2451  return ( matrix_ == rhs.matrix_ ) && ( row_ < rhs.row_ ) && ( column_ == rhs.column_ );
2452  }
2453  //*******************************************************************************************
2454 
2455  //**Greater-than operator********************************************************************
2461  template< typename MatrixType2 >
2462  inline bool operator>( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2463  return ( matrix_ == rhs.matrix_ ) && ( row_ > rhs.row_ ) && ( column_ == rhs.column_ );
2464  }
2465  //*******************************************************************************************
2466 
2467  //**Less-or-equal-than operator**************************************************************
2473  template< typename MatrixType2 >
2474  inline bool operator<=( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2475  return ( matrix_ == rhs.matrix_ ) && ( row_ <= rhs.row_ ) && ( column_ == rhs.column_ );
2476  }
2477  //*******************************************************************************************
2478 
2479  //**Greater-or-equal-than operator***********************************************************
2485  template< typename MatrixType2 >
2486  inline bool operator>=( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2487  return ( matrix_ == rhs.matrix_ ) && ( row_ >= rhs.row_ ) && ( column_ == rhs.column_ );
2488  }
2489  //*******************************************************************************************
2490 
2491  //**Subtraction operator*********************************************************************
2497  inline DifferenceType operator-( const ColumnIterator& rhs ) const noexcept {
2498  return row_ - rhs.row_;
2499  }
2500  //*******************************************************************************************
2501 
2502  //**Addition operator************************************************************************
2509  friend inline const ColumnIterator operator+( const ColumnIterator& it, size_t inc ) noexcept {
2510  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2511  }
2512  //*******************************************************************************************
2513 
2514  //**Addition operator************************************************************************
2521  friend inline const ColumnIterator operator+( size_t inc, const ColumnIterator& it ) noexcept {
2522  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2523  }
2524  //*******************************************************************************************
2525 
2526  //**Subtraction operator*********************************************************************
2533  friend inline const ColumnIterator operator-( const ColumnIterator& it, size_t dec ) noexcept {
2534  return ColumnIterator( *it.matrix_, it.row_-dec, it.column_ );
2535  }
2536  //*******************************************************************************************
2537 
2538  private:
2539  //**Member variables*************************************************************************
2540  MatrixType* matrix_;
2541  size_t row_;
2542  size_t column_;
2543  //*******************************************************************************************
2544 
2545  //**Friend declarations**********************************************************************
2546  template< typename MatrixType2 > friend class ColumnIterator;
2547  //*******************************************************************************************
2548  };
2549  //**********************************************************************************************
2550 
2551  //**Type definitions****************************************************************************
2553  using ConstIterator = ColumnIterator<const MT>;
2554 
2556  using Iterator = If_< IsConst<MT>, ConstIterator, ColumnIterator<MT> >;
2557  //**********************************************************************************************
2558 
2559  //**Compilation flags***************************************************************************
2561  enum : bool { simdEnabled = false };
2562 
2564  enum : bool { smpAssignable = MT::smpAssignable };
2565  //**********************************************************************************************
2566 
2567  //**Constructors********************************************************************************
2570  explicit inline Column( Operand matrix, size_t index );
2571  // No explicitly declared copy constructor.
2573  //**********************************************************************************************
2574 
2575  //**Destructor**********************************************************************************
2576  // No explicitly declared destructor.
2577  //**********************************************************************************************
2578 
2579  //**Data access functions***********************************************************************
2582  inline Reference operator[]( size_t index );
2583  inline ConstReference operator[]( size_t index ) const;
2584  inline Reference at( size_t index );
2585  inline ConstReference at( size_t index ) const;
2586  inline Pointer data () noexcept;
2587  inline ConstPointer data () const noexcept;
2588  inline Iterator begin ();
2589  inline ConstIterator begin () const;
2590  inline ConstIterator cbegin() const;
2591  inline Iterator end ();
2592  inline ConstIterator end () const;
2593  inline ConstIterator cend () const;
2595  //**********************************************************************************************
2596 
2597  //**Assignment operators************************************************************************
2600  inline Column& operator=( const ElementType& rhs );
2601  inline Column& operator=( initializer_list<ElementType> list );
2602  inline Column& operator=( const Column& rhs );
2603 
2604  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
2605  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
2606  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
2607  template< typename VT > inline Column& operator*=( const DenseVector<VT,false>& rhs );
2608  template< typename VT > inline Column& operator*=( const SparseVector<VT,false>& rhs );
2609  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
2610  template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
2611 
2612  template< typename Other >
2613  inline EnableIf_< IsNumeric<Other>, Column >& operator*=( Other rhs );
2614 
2615  template< typename Other >
2616  inline EnableIf_< IsNumeric<Other>, Column >& operator/=( Other rhs );
2618  //**********************************************************************************************
2619 
2620  //**Utility functions***************************************************************************
2623  inline Operand operand() const noexcept;
2624  inline size_t column() const noexcept;
2625  inline size_t size() const noexcept;
2626  inline size_t spacing() const noexcept;
2627  inline size_t capacity() const noexcept;
2628  inline size_t nonZeros() const;
2629  inline void reset();
2631  //**********************************************************************************************
2632 
2633  //**Numeric functions***************************************************************************
2636  template< typename Other > inline Column& scale( const Other& scalar );
2638  //**********************************************************************************************
2639 
2640  //**Expression template evaluation functions****************************************************
2643  template< typename Other >
2644  inline bool canAlias ( const Other* alias ) const noexcept;
2645 
2646  template< typename MT2, bool SO2, bool SF2 >
2647  inline bool canAlias ( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
2648 
2649  template< typename Other >
2650  inline bool isAliased( const Other* alias ) const noexcept;
2651 
2652  template< typename MT2, bool SO2, bool SF2 >
2653  inline bool isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
2654 
2655  inline bool isAligned () const noexcept;
2656  inline bool canSMPAssign() const noexcept;
2657 
2658  template< typename VT > inline void assign ( const DenseVector <VT,false>& rhs );
2659  template< typename VT > inline void assign ( const SparseVector<VT,false>& rhs );
2660  template< typename VT > inline void addAssign ( const DenseVector <VT,false>& rhs );
2661  template< typename VT > inline void addAssign ( const SparseVector<VT,false>& rhs );
2662  template< typename VT > inline void subAssign ( const DenseVector <VT,false>& rhs );
2663  template< typename VT > inline void subAssign ( const SparseVector<VT,false>& rhs );
2664  template< typename VT > inline void multAssign( const DenseVector <VT,false>& rhs );
2665  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
2666  template< typename VT > inline void divAssign ( const DenseVector <VT,false>& rhs );
2668  //**********************************************************************************************
2669 
2670  private:
2671  //**Member variables****************************************************************************
2674  Operand matrix_;
2675  const size_t col_;
2676 
2677  //**********************************************************************************************
2678 
2679  //**Friend declarations*************************************************************************
2680  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Column;
2681  //**********************************************************************************************
2682 
2683  //**Compile time checks*************************************************************************
2691  //**********************************************************************************************
2692 };
2694 //*************************************************************************************************
2695 
2696 
2697 
2698 
2699 //=================================================================================================
2700 //
2701 // CONSTRUCTOR
2702 //
2703 //=================================================================================================
2704 
2705 //*************************************************************************************************
2713 template< typename MT > // Type of the dense matrix
2714 inline Column<MT,false,true,false>::Column( Operand matrix, size_t index )
2715  : matrix_( matrix ) // The dense matrix containing the column
2716  , col_ ( index ) // The index of the column in the matrix
2717 {
2718  if( matrix_.columns() <= index ) {
2719  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2720  }
2721 }
2723 //*************************************************************************************************
2724 
2725 
2726 
2727 
2728 //=================================================================================================
2729 //
2730 // DATA ACCESS FUNCTIONS
2731 //
2732 //=================================================================================================
2733 
2734 //*************************************************************************************************
2744 template< typename MT > // Type of the dense matrix
2746  Column<MT,false,true,false>::operator[]( size_t index )
2747 {
2748  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2749  return matrix_(index,col_);
2750 }
2752 //*************************************************************************************************
2753 
2754 
2755 //*************************************************************************************************
2765 template< typename MT > // Type of the dense matrix
2767  Column<MT,false,true,false>::operator[]( size_t index ) const
2768 {
2769  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2770  return const_cast<const MT&>( matrix_ )(index,col_);
2771 }
2773 //*************************************************************************************************
2774 
2775 
2776 //*************************************************************************************************
2787 template< typename MT > // Type of the dense matrix
2789  Column<MT,false,true,false>::at( size_t index )
2790 {
2791  if( index >= size() ) {
2792  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2793  }
2794  return (*this)[index];
2795 }
2797 //*************************************************************************************************
2798 
2799 
2800 //*************************************************************************************************
2811 template< typename MT > // Type of the dense matrix
2813  Column<MT,false,true,false>::at( size_t index ) const
2814 {
2815  if( index >= size() ) {
2816  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2817  }
2818  return (*this)[index];
2819 }
2821 //*************************************************************************************************
2822 
2823 
2824 //*************************************************************************************************
2833 template< typename MT > // Type of the dense matrix
2834 inline typename Column<MT,false,true,false>::Pointer Column<MT,false,true,false>::data() noexcept
2835 {
2836  return matrix_.data() + col_;
2837 }
2839 //*************************************************************************************************
2840 
2841 
2842 //*************************************************************************************************
2851 template< typename MT > // Type of the dense matrix
2852 inline typename Column<MT,false,true,false>::ConstPointer Column<MT,false,true,false>::data() const noexcept
2853 {
2854  return matrix_.data() + col_;
2855 }
2857 //*************************************************************************************************
2858 
2859 
2860 //*************************************************************************************************
2868 template< typename MT > // Type of the dense matrix
2870 {
2871  return Iterator( matrix_, 0UL, col_ );
2872 }
2874 //*************************************************************************************************
2875 
2876 
2877 //*************************************************************************************************
2885 template< typename MT > // Type of the dense matrix
2888 {
2889  return ConstIterator( matrix_, 0UL, col_ );
2890 }
2892 //*************************************************************************************************
2893 
2894 
2895 //*************************************************************************************************
2903 template< typename MT > // Type of the dense matrix
2906 {
2907  return ConstIterator( matrix_, 0UL, col_ );
2908 }
2910 //*************************************************************************************************
2911 
2912 
2913 //*************************************************************************************************
2921 template< typename MT > // Type of the dense matrix
2923 {
2924  return Iterator( matrix_, size(), col_ );
2925 }
2927 //*************************************************************************************************
2928 
2929 
2930 //*************************************************************************************************
2938 template< typename MT > // Type of the dense matrix
2941 {
2942  return ConstIterator( matrix_, size(), col_ );
2943 }
2945 //*************************************************************************************************
2946 
2947 
2948 //*************************************************************************************************
2956 template< typename MT > // Type of the dense matrix
2959 {
2960  return ConstIterator( matrix_, size(), col_ );
2961 }
2963 //*************************************************************************************************
2964 
2965 
2966 
2967 
2968 //=================================================================================================
2969 //
2970 // ASSIGNMENT OPERATORS
2971 //
2972 //=================================================================================================
2973 
2974 //*************************************************************************************************
2985 template< typename MT > // Type of the dense matrix
2986 inline Column<MT,false,true,false>&
2987  Column<MT,false,true,false>::operator=( const ElementType& rhs )
2988 {
2989  const size_t ibegin( ( IsLower<MT>::value )
2990  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
2991  ?( col_+1UL )
2992  :( col_ ) )
2993  :( 0UL ) );
2994  const size_t iend ( ( IsUpper<MT>::value )
2995  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
2996  ?( col_ )
2997  :( col_+1UL ) )
2998  :( size() ) );
2999 
3000  for( size_t i=ibegin; i<iend; ++i )
3001  matrix_(i,col_) = rhs;
3002 
3003  return *this;
3004 }
3006 //*************************************************************************************************
3007 
3008 
3009 //*************************************************************************************************
3022 template< typename MT > // Type of the dense matrix
3023 inline Column<MT,false,true,false>&
3024  Column<MT,false,true,false>::operator=( initializer_list<ElementType> list )
3025 {
3026  if( list.size() > size() ) {
3027  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
3028  }
3029 
3030  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
3031 
3032  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3033 
3034  return *this;
3035 }
3037 //*************************************************************************************************
3038 
3039 
3040 //*************************************************************************************************
3054 template< typename MT > // Type of the dense matrix
3055 inline Column<MT,false,true,false>&
3056  Column<MT,false,true,false>::operator=( const Column& rhs )
3057 {
3058  if( &rhs == this ) return *this;
3059 
3060  if( size() != rhs.size() ) {
3061  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
3062  }
3063 
3064  if( !tryAssign( matrix_, rhs, 0UL, col_ ) ) {
3065  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3066  }
3067 
3068  decltype(auto) left( derestrict( *this ) );
3069 
3070  smpAssign( left, rhs );
3071 
3072  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3073 
3074  return *this;
3075 }
3077 //*************************************************************************************************
3078 
3079 
3080 //*************************************************************************************************
3094 template< typename MT > // Type of the dense matrix
3095 template< typename VT > // Type of the right-hand side vector
3096 inline Column<MT,false,true,false>&
3097  Column<MT,false,true,false>::operator=( const Vector<VT,false>& rhs )
3098 {
3102 
3103  if( size() != (~rhs).size() ) {
3104  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3105  }
3106 
3107  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3108  Right right( ~rhs );
3109 
3110  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
3111  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3112  }
3113 
3114  decltype(auto) left( derestrict( *this ) );
3115 
3116  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3117  const ResultType tmp( right );
3118  smpAssign( left, tmp );
3119  }
3120  else {
3121  if( IsSparseVector<VT>::value )
3122  reset();
3123  smpAssign( left, right );
3124  }
3125 
3126  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3127 
3128  return *this;
3129 }
3131 //*************************************************************************************************
3132 
3133 
3134 //*************************************************************************************************
3148 template< typename MT > // Type of the dense matrix
3149 template< typename VT > // Type of the right-hand side vector
3150 inline Column<MT,false,true,false>&
3151  Column<MT,false,true,false>::operator+=( const Vector<VT,false>& rhs )
3152 {
3153  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3155 
3156  if( size() != (~rhs).size() ) {
3157  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3158  }
3159 
3160  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3161  Right right( ~rhs );
3162 
3163  if( !tryAddAssign( matrix_, right, 0UL, col_ ) ) {
3164  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3165  }
3166 
3167  decltype(auto) left( derestrict( *this ) );
3168 
3169  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3170  const ResultType_<VT> tmp( right );
3171  smpAddAssign( left, tmp );
3172  }
3173  else {
3174  smpAddAssign( left, right );
3175  }
3176 
3177  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3178 
3179  return *this;
3180 }
3182 //*************************************************************************************************
3183 
3184 
3185 //*************************************************************************************************
3199 template< typename MT > // Type of the dense matrix
3200 template< typename VT > // Type of the right-hand side vector
3201 inline Column<MT,false,true,false>&
3202  Column<MT,false,true,false>::operator-=( const Vector<VT,false>& rhs )
3203 {
3204  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3206 
3207  if( size() != (~rhs).size() ) {
3208  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3209  }
3210 
3211  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3212  Right right( ~rhs );
3213 
3214  if( !trySubAssign( matrix_, right, 0UL, col_ ) ) {
3215  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3216  }
3217 
3218  decltype(auto) left( derestrict( *this ) );
3219 
3220  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3221  const ResultType_<VT> tmp( right );
3222  smpSubAssign( left, tmp );
3223  }
3224  else {
3225  smpSubAssign( left, right );
3226  }
3227 
3228  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3229 
3230  return *this;
3231 }
3233 //*************************************************************************************************
3234 
3235 
3236 //*************************************************************************************************
3249 template< typename MT > // Type of the dense matrix
3250 template< typename VT > // Type of the right-hand side dense vector
3251 inline Column<MT,false,true,false>&
3252  Column<MT,false,true,false>::operator*=( const DenseVector<VT,false>& rhs )
3253 {
3254  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3256 
3257  if( size() != (~rhs).size() ) {
3258  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3259  }
3260 
3261  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3262  Right right( ~rhs );
3263 
3264  if( !tryMultAssign( matrix_, right, 0UL, col_ ) ) {
3265  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3266  }
3267 
3268  decltype(auto) left( derestrict( *this ) );
3269 
3270  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3271  const ResultType_<VT> tmp( right );
3272  smpMultAssign( left, tmp );
3273  }
3274  else {
3275  smpMultAssign( left, right );
3276  }
3277 
3278  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3279 
3280  return *this;
3281 }
3283 //*************************************************************************************************
3284 
3285 
3286 //*************************************************************************************************
3299 template< typename MT > // Type of the dense matrix
3300 template< typename VT > // Type of the right-hand side sparse vector
3301 inline Column<MT,false,true,false>&
3302  Column<MT,false,true,false>::operator*=( const SparseVector<VT,false>& rhs )
3303 {
3307 
3308  if( size() != (~rhs).size() ) {
3309  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3310  }
3311 
3312  const ResultType right( *this * (~rhs) );
3313 
3314  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
3315  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3316  }
3317 
3318  decltype(auto) left( derestrict( *this ) );
3319 
3320  smpAssign( left, right );
3321 
3322  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3323 
3324  return *this;
3325 }
3327 //*************************************************************************************************
3328 
3329 
3330 //*************************************************************************************************
3342 template< typename MT > // Type of the dense matrix
3343 template< typename VT > // Type of the right-hand side dense vector
3344 inline Column<MT,false,true,false>&
3345  Column<MT,false,true,false>::operator/=( const DenseVector<VT,false>& rhs )
3346 {
3347  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3349 
3350  if( size() != (~rhs).size() ) {
3351  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3352  }
3353 
3354  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3355  Right right( ~rhs );
3356 
3357  if( !tryDivAssign( matrix_, right, 0UL, col_ ) ) {
3358  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3359  }
3360 
3361  decltype(auto) left( derestrict( *this ) );
3362 
3363  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3364  const ResultType_<VT> tmp( right );
3365  smpDivAssign( left, tmp );
3366  }
3367  else {
3368  smpDivAssign( left, right );
3369  }
3370 
3371  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3372 
3373  return *this;
3374 }
3376 //*************************************************************************************************
3377 
3378 
3379 //*************************************************************************************************
3392 template< typename MT > // Type of the dense matrix
3393 template< typename VT > // Type of the right-hand side vector
3394 inline Column<MT,false,true,false>&
3395  Column<MT,false,true,false>::operator%=( const Vector<VT,false>& rhs )
3396 {
3397  using blaze::assign;
3398 
3399  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3401 
3402  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
3403 
3407 
3408  if( size() != 3UL || (~rhs).size() != 3UL ) {
3409  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3410  }
3411 
3412  const CrossType right( *this % (~rhs) );
3413 
3414  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
3415  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3416  }
3417 
3418  decltype(auto) left( derestrict( *this ) );
3419 
3420  assign( left, right );
3421 
3422  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3423 
3424  return *this;
3425 }
3427 //*************************************************************************************************
3428 
3429 
3430 //*************************************************************************************************
3441 template< typename MT > // Type of the dense matrix
3442 template< typename Other > // Data type of the right-hand side scalar
3443 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,false> >&
3444  Column<MT,false,true,false>::operator*=( Other rhs )
3445 {
3447 
3448  return operator=( (*this) * rhs );
3449 }
3451 //*************************************************************************************************
3452 
3453 
3454 //*************************************************************************************************
3467 template< typename MT > // Type of the dense matrix
3468 template< typename Other > // Data type of the right-hand side scalar
3469 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,false> >&
3471 {
3473 
3474  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3475 
3476  return operator=( (*this) / rhs );
3477 }
3479 //*************************************************************************************************
3480 
3481 
3482 
3483 
3484 //=================================================================================================
3485 //
3486 // UTILITY FUNCTIONS
3487 //
3488 //=================================================================================================
3489 
3490 //*************************************************************************************************
3496 template< typename MT > // Type of the dense matrix
3497 inline typename Column<MT,false,true,false>::Operand
3498  Column<MT,false,true,false>::operand() const noexcept
3499 {
3500  return matrix_;
3501 }
3503 //*************************************************************************************************
3504 
3505 
3506 //*************************************************************************************************
3512 template< typename MT > // Type of the dense matrix
3513 inline size_t Column<MT,false,true,false>::column() const noexcept
3514 {
3515  return col_;
3516 }
3518 //*************************************************************************************************
3519 
3520 
3521 //*************************************************************************************************
3527 template< typename MT > // Type of the dense matrix
3528 inline size_t Column<MT,false,true,false>::size() const noexcept
3529 {
3530  return matrix_.rows();
3531 }
3533 //*************************************************************************************************
3534 
3535 
3536 //*************************************************************************************************
3545 template< typename MT > // Type of the dense matrix
3546 inline size_t Column<MT,false,true,false>::spacing() const noexcept
3547 {
3548  return matrix_.spacing();
3549 }
3551 //*************************************************************************************************
3552 
3553 
3554 //*************************************************************************************************
3560 template< typename MT > // Type of the dense matrix
3561 inline size_t Column<MT,false,true,false>::capacity() const noexcept
3562 {
3563  return matrix_.rows();
3564 }
3566 //*************************************************************************************************
3567 
3568 
3569 //*************************************************************************************************
3578 template< typename MT > // Type of the dense matrix
3579 inline size_t Column<MT,false,true,false>::nonZeros() const
3580 {
3581  const size_t rows( size() );
3582  size_t nonzeros( 0UL );
3583 
3584  for( size_t i=0UL; i<rows; ++i )
3585  if( !isDefault( matrix_(i,col_) ) )
3586  ++nonzeros;
3587 
3588  return nonzeros;
3589 }
3591 //*************************************************************************************************
3592 
3593 
3594 //*************************************************************************************************
3600 template< typename MT > // Type of the dense matrix
3602 {
3603  using blaze::clear;
3604 
3605  const size_t ibegin( ( IsLower<MT>::value )
3606  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3607  ?( col_+1UL )
3608  :( col_ ) )
3609  :( 0UL ) );
3610  const size_t iend ( ( IsUpper<MT>::value )
3611  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3612  ?( col_ )
3613  :( col_+1UL ) )
3614  :( size() ) );
3615 
3616  for( size_t i=ibegin; i<iend; ++i )
3617  clear( matrix_(i,col_) );
3618 }
3620 //*************************************************************************************************
3621 
3622 
3623 
3624 
3625 //=================================================================================================
3626 //
3627 // NUMERIC FUNCTIONS
3628 //
3629 //=================================================================================================
3630 
3631 //*************************************************************************************************
3644 template< typename MT > // Type of the dense matrix
3645 template< typename Other > // Data type of the scalar value
3646 inline Column<MT,false,true,false>& Column<MT,false,true,false>::scale( const Other& scalar )
3647 {
3649 
3650  const size_t ibegin( ( IsLower<MT>::value )
3651  ?( ( IsStrictlyLower<MT>::value )
3652  ?( col_+1UL )
3653  :( col_ ) )
3654  :( 0UL ) );
3655  const size_t iend ( ( IsUpper<MT>::value )
3656  ?( ( IsStrictlyUpper<MT>::value )
3657  ?( col_ )
3658  :( col_+1UL ) )
3659  :( size() ) );
3660 
3661  for( size_t i=ibegin; i<iend; ++i ) {
3662  matrix_(i,col_) *= scalar;
3663  }
3664 
3665  return *this;
3666 }
3668 //*************************************************************************************************
3669 
3670 
3671 
3672 
3673 //=================================================================================================
3674 //
3675 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3676 //
3677 //=================================================================================================
3678 
3679 //*************************************************************************************************
3690 template< typename MT > // Type of the dense matrix
3691 template< typename Other > // Data type of the foreign expression
3692 inline bool Column<MT,false,true,false>::canAlias( const Other* alias ) const noexcept
3693 {
3694  return matrix_.isAliased( alias );
3695 }
3697 //*************************************************************************************************
3698 
3699 
3700 //*************************************************************************************************
3711 template< typename MT > // Type of the dense matrix
3712 template< typename MT2 // Data type of the foreign dense column
3713  , bool SO2 // Storage order of the foreign dense column
3714  , bool SF2 > // Symmetry flag of the foreign dense column
3715 inline bool Column<MT,false,true,false>::canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
3716 {
3717  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
3718 }
3720 //*************************************************************************************************
3721 
3722 
3723 //*************************************************************************************************
3734 template< typename MT > // Type of the dense matrix
3735 template< typename Other > // Data type of the foreign expression
3736 inline bool Column<MT,false,true,false>::isAliased( const Other* alias ) const noexcept
3737 {
3738  return matrix_.isAliased( alias );
3739 }
3741 //*************************************************************************************************
3742 
3743 
3744 //*************************************************************************************************
3755 template< typename MT > // Type of the dense matrix
3756 template< typename MT2 // Data type of the foreign dense column
3757  , bool SO2 // Storage order of the foreign dense column
3758  , bool SF2 > // Symmetry flag of the foreign dense column
3759 inline bool Column<MT,false,true,false>::isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
3760 {
3761  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
3762 }
3764 //*************************************************************************************************
3765 
3766 
3767 //*************************************************************************************************
3777 template< typename MT > // Type of the dense matrix
3778 inline bool Column<MT,false,true,false>::isAligned() const noexcept
3779 {
3780  return false;
3781 }
3783 //*************************************************************************************************
3784 
3785 
3786 //*************************************************************************************************
3797 template< typename MT > // Type of the dense matrix
3798 inline bool Column<MT,false,true,false>::canSMPAssign() const noexcept
3799 {
3800  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3801 }
3803 //*************************************************************************************************
3804 
3805 
3806 //*************************************************************************************************
3818 template< typename MT > // Type of the dense matrix
3819 template< typename VT > // Type of the right-hand side dense vector
3820 inline void Column<MT,false,true,false>::assign( const DenseVector<VT,false>& rhs )
3821 {
3822  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3823 
3824  const size_t ipos( (~rhs).size() & size_t(-2) );
3825  for( size_t i=0UL; i<ipos; i+=2UL ) {
3826  matrix_(i ,col_) = (~rhs)[i ];
3827  matrix_(i+1UL,col_) = (~rhs)[i+1UL];
3828  }
3829  if( ipos < (~rhs).size() )
3830  matrix_(ipos,col_) = (~rhs)[ipos];
3831 }
3833 //*************************************************************************************************
3834 
3835 
3836 //*************************************************************************************************
3848 template< typename MT > // Type of the dense matrix
3849 template< typename VT > // Type of the right-hand side sparse vector
3850 inline void Column<MT,false,true,false>::assign( const SparseVector<VT,false>& rhs )
3851 {
3852  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3853 
3854  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3855  matrix_(element->index(),col_) = element->value();
3856 }
3858 //*************************************************************************************************
3859 
3860 
3861 //*************************************************************************************************
3873 template< typename MT > // Type of the dense matrix
3874 template< typename VT > // Type of the right-hand side dense vector
3875 inline void Column<MT,false,true,false>::addAssign( const DenseVector<VT,false>& rhs )
3876 {
3877  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3878 
3879  const size_t ipos( (~rhs).size() & size_t(-2) );
3880  for( size_t i=0UL; i<ipos; i+=2UL ) {
3881  matrix_(i ,col_) += (~rhs)[i ];
3882  matrix_(i+1UL,col_) += (~rhs)[i+1UL];
3883  }
3884  if( ipos < (~rhs).size() )
3885  matrix_(ipos,col_) += (~rhs)[ipos];
3886 }
3888 //*************************************************************************************************
3889 
3890 
3891 //*************************************************************************************************
3903 template< typename MT > // Type of the dense matrix
3904 template< typename VT > // Type of the right-hand side sparse vector
3905 inline void Column<MT,false,true,false>::addAssign( const SparseVector<VT,false>& rhs )
3906 {
3907  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3908 
3909  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3910  matrix_(element->index(),col_) += element->value();
3911 }
3913 //*************************************************************************************************
3914 
3915 
3916 //*************************************************************************************************
3928 template< typename MT > // Type of the dense matrix
3929 template< typename VT > // Type of the right-hand side dense vector
3930 inline void Column<MT,false,true,false>::subAssign( const DenseVector<VT,false>& rhs )
3931 {
3932  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3933 
3934  const size_t ipos( (~rhs).size() & size_t(-2) );
3935  for( size_t i=0UL; i<ipos; i+=2UL ) {
3936  matrix_(i ,col_) -= (~rhs)[i ];
3937  matrix_(i+1UL,col_) -= (~rhs)[i+1UL];
3938  }
3939  if( ipos < (~rhs).size() )
3940  matrix_(ipos,col_) -= (~rhs)[ipos];
3941 }
3943 //*************************************************************************************************
3944 
3945 
3946 //*************************************************************************************************
3958 template< typename MT > // Type of the dense matrix
3959 template< typename VT > // Type of the right-hand side sparse vector
3960 inline void Column<MT,false,true,false>::subAssign( const SparseVector<VT,false>& rhs )
3961 {
3962  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3963 
3964  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3965  matrix_(element->index(),col_) -= element->value();
3966 }
3968 //*************************************************************************************************
3969 
3970 
3971 //*************************************************************************************************
3983 template< typename MT > // Type of the dense matrix
3984 template< typename VT > // Type of the right-hand side dense vector
3985 inline void Column<MT,false,true,false>::multAssign( const DenseVector<VT,false>& rhs )
3986 {
3987  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3988 
3989  const size_t ipos( (~rhs).size() & size_t(-2) );
3990  for( size_t i=0UL; i<ipos; i+=2UL ) {
3991  matrix_(i ,col_) *= (~rhs)[i ];
3992  matrix_(i+1UL,col_) *= (~rhs)[i+1UL];
3993  }
3994  if( ipos < (~rhs).size() )
3995  matrix_(ipos,col_) *= (~rhs)[ipos];
3996 }
3998 //*************************************************************************************************
3999 
4000 
4001 //*************************************************************************************************
4013 template< typename MT > // Type of the dense matrix
4014 template< typename VT > // Type of the right-hand side sparse vector
4015 inline void Column<MT,false,true,false>::multAssign( const SparseVector<VT,false>& rhs )
4016 {
4017  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4018 
4019  const ResultType tmp( serial( *this ) );
4020 
4021  reset();
4022 
4023  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4024  matrix_(element->index(),col_) = tmp[element->index()] * element->value();
4025 }
4027 //*************************************************************************************************
4028 
4029 
4030 //*************************************************************************************************
4042 template< typename MT > // Type of the dense matrix
4043 template< typename VT > // Type of the right-hand side dense vector
4044 inline void Column<MT,false,true,false>::divAssign( const DenseVector<VT,false>& rhs )
4045 {
4046  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4047 
4048  const size_t ipos( (~rhs).size() & size_t(-2) );
4049  for( size_t i=0UL; i<ipos; i+=2UL ) {
4050  matrix_(i ,col_) /= (~rhs)[i ];
4051  matrix_(i+1UL,col_) /= (~rhs)[i+1UL];
4052  }
4053  if( ipos < (~rhs).size() )
4054  matrix_(ipos,col_) /= (~rhs)[ipos];
4055 }
4057 //*************************************************************************************************
4058 
4059 
4060 
4061 
4062 
4063 
4064 
4065 
4066 //=================================================================================================
4067 //
4068 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
4069 //
4070 //=================================================================================================
4071 
4072 //*************************************************************************************************
4080 template< typename MT > // Type of the dense matrix
4081 class Column<MT,false,true,true>
4082  : public View< DenseVector< Column<MT,false,true,true>, false > >
4083 {
4084  private:
4085  //**Type definitions****************************************************************************
4087  using Operand = If_< IsExpression<MT>, MT, MT& >;
4088  //**********************************************************************************************
4089 
4090  public:
4091  //**Type definitions****************************************************************************
4092  using This = Column<MT,false,true,true>;
4093  using BaseType = DenseVector<This,false>;
4094  using ResultType = ColumnTrait_<MT>;
4095  using TransposeType = TransposeType_<ResultType>;
4096  using ElementType = ElementType_<MT>;
4097  using SIMDType = SIMDTrait_<ElementType>;
4098  using ReturnType = ReturnType_<MT>;
4099  using CompositeType = const Column&;
4100 
4102  using ConstReference = ConstReference_<MT>;
4103 
4105  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
4106 
4108  using ConstPointer = const ElementType*;
4109 
4111  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* >;
4112 
4114  using ConstIterator = ConstIterator_<MT>;
4115 
4117  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
4118  //**********************************************************************************************
4119 
4120  //**Compilation flags***************************************************************************
4122  enum : bool { simdEnabled = MT::simdEnabled };
4123 
4125  enum : bool { smpAssignable = MT::smpAssignable };
4126  //**********************************************************************************************
4127 
4128  //**Constructors********************************************************************************
4131  explicit inline Column( Operand matrix, size_t index );
4132  // No explicitly declared copy constructor.
4134  //**********************************************************************************************
4135 
4136  //**Destructor**********************************************************************************
4137  // No explicitly declared destructor.
4138  //**********************************************************************************************
4139 
4140  //**Data access functions***********************************************************************
4143  inline Reference operator[]( size_t index );
4144  inline ConstReference operator[]( size_t index ) const;
4145  inline Reference at( size_t index );
4146  inline ConstReference at( size_t index ) const;
4147  inline Pointer data () noexcept;
4148  inline ConstPointer data () const noexcept;
4149  inline Iterator begin ();
4150  inline ConstIterator begin () const;
4151  inline ConstIterator cbegin() const;
4152  inline Iterator end ();
4153  inline ConstIterator end () const;
4154  inline ConstIterator cend () const;
4156  //**********************************************************************************************
4157 
4158  //**Assignment operators************************************************************************
4161  inline Column& operator=( const ElementType& rhs );
4162  inline Column& operator=( initializer_list<ElementType> list );
4163  inline Column& operator=( const Column& rhs );
4164 
4165  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
4166  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
4167  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
4168  template< typename VT > inline Column& operator*=( const DenseVector<VT,false>& rhs );
4169  template< typename VT > inline Column& operator*=( const SparseVector<VT,false>& rhs );
4170  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
4171  template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
4172 
4173  template< typename Other >
4174  inline EnableIf_< IsNumeric<Other>, Column >& operator*=( Other rhs );
4175 
4176  template< typename Other >
4177  inline EnableIf_< IsNumeric<Other>, Column >& operator/=( Other rhs );
4179  //**********************************************************************************************
4180 
4181  //**Utility functions***************************************************************************
4184  inline Operand operand() const noexcept;
4185  inline size_t column() const noexcept;
4186  inline size_t size() const noexcept;
4187  inline size_t spacing() const noexcept;
4188  inline size_t capacity() const noexcept;
4189  inline size_t nonZeros() const;
4190  inline void reset();
4192  //**********************************************************************************************
4193 
4194  //**Numeric functions***************************************************************************
4197  template< typename Other > inline Column& scale( const Other& scalar );
4199  //**********************************************************************************************
4200 
4201  private:
4202  //**********************************************************************************************
4204  template< typename VT >
4205  struct VectorizedAssign {
4206  enum : bool { value = useOptimizedKernels &&
4207  simdEnabled && VT::simdEnabled &&
4208  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
4209  };
4210  //**********************************************************************************************
4211 
4212  //**********************************************************************************************
4214  template< typename VT >
4215  struct VectorizedAddAssign {
4216  enum : bool { value = useOptimizedKernels &&
4217  simdEnabled && VT::simdEnabled &&
4218  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4219  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
4220  };
4221  //**********************************************************************************************
4222 
4223  //**********************************************************************************************
4225  template< typename VT >
4226  struct VectorizedSubAssign {
4227  enum : bool { value = useOptimizedKernels &&
4228  simdEnabled && VT::simdEnabled &&
4229  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4230  HasSIMDSub< ElementType, ElementType_<VT> >::value };
4231  };
4232  //**********************************************************************************************
4233 
4234  //**********************************************************************************************
4236  template< typename VT >
4237  struct VectorizedMultAssign {
4238  enum : bool { value = useOptimizedKernels &&
4239  simdEnabled && VT::simdEnabled &&
4240  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4241  HasSIMDMult< ElementType, ElementType_<VT> >::value };
4242  };
4243  //**********************************************************************************************
4244 
4245  //**********************************************************************************************
4247  template< typename VT >
4248  struct VectorizedDivAssign {
4249  enum : bool { value = useOptimizedKernels &&
4250  simdEnabled && VT::simdEnabled &&
4251  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4252  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
4253  };
4254  //**********************************************************************************************
4255 
4256  //**SIMD properties*****************************************************************************
4258  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
4259  //**********************************************************************************************
4260 
4261  public:
4262  //**Expression template evaluation functions****************************************************
4265  template< typename Other >
4266  inline bool canAlias( const Other* alias ) const noexcept;
4267 
4268  template< typename MT2, bool SO2, bool SF2 >
4269  inline bool canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
4270 
4271  template< typename Other >
4272  inline bool isAliased( const Other* alias ) const noexcept;
4273 
4274  template< typename MT2, bool SO2, bool SF2 >
4275  inline bool isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
4276 
4277  inline bool isAligned () const noexcept;
4278  inline bool canSMPAssign() const noexcept;
4279 
4280  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4281  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4282  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4283 
4284  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4285  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4286  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4287  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4288 
4289  template< typename VT >
4290  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
4291 
4292  template< typename VT >
4293  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
4294 
4295  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
4296 
4297  template< typename VT >
4298  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
4299 
4300  template< typename VT >
4301  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
4302 
4303  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
4304 
4305  template< typename VT >
4306  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
4307 
4308  template< typename VT >
4309  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
4310 
4311  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
4312 
4313  template< typename VT >
4314  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
4315 
4316  template< typename VT >
4317  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
4318 
4319  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
4320 
4321  template< typename VT >
4322  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
4323 
4324  template< typename VT >
4325  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
4327  //**********************************************************************************************
4328 
4329  private:
4330  //**Member variables****************************************************************************
4333  Operand matrix_;
4334  const size_t col_;
4335 
4336  //**********************************************************************************************
4337 
4338  //**Friend declarations*************************************************************************
4339  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Column;
4340  //**********************************************************************************************
4341 
4342  //**Compile time checks*************************************************************************
4350  //**********************************************************************************************
4351 };
4353 //*************************************************************************************************
4354 
4355 
4356 
4357 
4358 //=================================================================================================
4359 //
4360 // CONSTRUCTOR
4361 //
4362 //=================================================================================================
4363 
4364 //*************************************************************************************************
4372 template< typename MT > // Type of the dense matrix
4373 inline Column<MT,false,true,true>::Column( Operand matrix, size_t index )
4374  : matrix_( matrix ) // The dense matrix containing the column
4375  , col_ ( index ) // The index of the column in the matrix
4376 {
4377  if( matrix_.columns() <= index ) {
4378  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
4379  }
4380 }
4382 //*************************************************************************************************
4383 
4384 
4385 
4386 
4387 //=================================================================================================
4388 //
4389 // DATA ACCESS FUNCTIONS
4390 //
4391 //=================================================================================================
4392 
4393 //*************************************************************************************************
4403 template< typename MT > // Type of the dense matrix
4405  Column<MT,false,true,true>::operator[]( size_t index )
4406 {
4407  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4408  return matrix_(col_,index);
4409 }
4411 //*************************************************************************************************
4412 
4413 
4414 //*************************************************************************************************
4424 template< typename MT > // Type of the dense matrix
4426  Column<MT,false,true,true>::operator[]( size_t index ) const
4427 {
4428  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4429  return const_cast<const MT&>( matrix_ )(index,col_);
4430 }
4432 //*************************************************************************************************
4433 
4434 
4435 //*************************************************************************************************
4446 template< typename MT > // Type of the dense matrix
4448  Column<MT,false,true,true>::at( size_t index )
4449 {
4450  if( index >= size() ) {
4451  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4452  }
4453  return (*this)[index];
4454 }
4456 //*************************************************************************************************
4457 
4458 
4459 //*************************************************************************************************
4470 template< typename MT > // Type of the dense matrix
4472  Column<MT,false,true,true>::at( size_t index ) const
4473 {
4474  if( index >= size() ) {
4475  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4476  }
4477  return (*this)[index];
4478 }
4480 //*************************************************************************************************
4481 
4482 
4483 //*************************************************************************************************
4492 template< typename MT > // Type of the dense matrix
4493 inline typename Column<MT,false,true,true>::Pointer Column<MT,false,true,true>::data() noexcept
4494 {
4495  return matrix_.data( col_ );
4496 }
4498 //*************************************************************************************************
4499 
4500 
4501 //*************************************************************************************************
4510 template< typename MT > // Type of the dense matrix
4511 inline typename Column<MT,false,true,true>::ConstPointer
4512  Column<MT,false,true,true>::data() const noexcept
4513 {
4514  return matrix_.data( col_ );
4515 }
4517 //*************************************************************************************************
4518 
4519 
4520 //*************************************************************************************************
4528 template< typename MT > // Type of the dense matrix
4530 {
4531  return matrix_.begin( col_ );
4532 }
4534 //*************************************************************************************************
4535 
4536 
4537 //*************************************************************************************************
4545 template< typename MT > // Type of the dense matrix
4547 {
4548  return matrix_.cbegin( col_ );
4549 }
4551 //*************************************************************************************************
4552 
4553 
4554 //*************************************************************************************************
4562 template< typename MT > // Type of the dense matrix
4564 {
4565  return matrix_.cbegin( col_ );
4566 }
4568 //*************************************************************************************************
4569 
4570 
4571 //*************************************************************************************************
4579 template< typename MT > // Type of the dense matrix
4581 {
4582  return matrix_.end( col_ );
4583 }
4585 //*************************************************************************************************
4586 
4587 
4588 //*************************************************************************************************
4596 template< typename MT > // Type of the dense matrix
4598 {
4599  return matrix_.cend( col_ );
4600 }
4602 //*************************************************************************************************
4603 
4604 
4605 //*************************************************************************************************
4613 template< typename MT > // Type of the dense matrix
4615 {
4616  return matrix_.cend( col_ );
4617 }
4619 //*************************************************************************************************
4620 
4621 
4622 
4623 
4624 //=================================================================================================
4625 //
4626 // ASSIGNMENT OPERATORS
4627 //
4628 //=================================================================================================
4629 
4630 //*************************************************************************************************
4637 template< typename MT > // Type of the dense matrix
4638 inline Column<MT,false,true,true>& Column<MT,false,true,true>::operator=( const ElementType& rhs )
4639 {
4640  const size_t jbegin( ( IsUpper<MT>::value )
4641  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4642  ?( col_+1UL )
4643  :( col_ ) )
4644  :( 0UL ) );
4645  const size_t jend ( ( IsLower<MT>::value )
4646  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4647  ?( col_ )
4648  :( col_+1UL ) )
4649  :( size() ) );
4650 
4651  for( size_t j=jbegin; j<jend; ++j )
4652  matrix_(col_,j) = rhs;
4653 
4654  return *this;
4655 }
4657 //*************************************************************************************************
4658 
4659 
4660 //*************************************************************************************************
4673 template< typename MT > // Type of the dense matrix
4674 inline Column<MT,false,true,true>&
4675  Column<MT,false,true,true>::operator=( initializer_list<ElementType> list )
4676 {
4677  if( list.size() > size() ) {
4678  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
4679  }
4680 
4681  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
4682 
4683  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4684 
4685  return *this;
4686 }
4688 //*************************************************************************************************
4689 
4690 
4691 //*************************************************************************************************
4705 template< typename MT > // Type of the dense matrix
4706 inline Column<MT,false,true,true>& Column<MT,false,true,true>::operator=( const Column& rhs )
4707 {
4708  if( &rhs == this ) return *this;
4709 
4710  if( size() != rhs.size() ) {
4711  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
4712  }
4713 
4714  if( !tryAssign( matrix_, rhs, 0UL, col_ ) ) {
4715  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4716  }
4717 
4718  decltype(auto) left( derestrict( *this ) );
4719 
4720  smpAssign( left, rhs );
4721 
4722  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4723 
4724  return *this;
4725 }
4727 //*************************************************************************************************
4728 
4729 
4730 //*************************************************************************************************
4744 template< typename MT > // Type of the dense matrix
4745 template< typename VT > // Type of the right-hand side vector
4746 inline Column<MT,false,true,true>&
4747  Column<MT,false,true,true>::operator=( const Vector<VT,false>& rhs )
4748 {
4749  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4751 
4752  if( size() != (~rhs).size() ) {
4753  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4754  }
4755 
4756  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4757  Right right( ~rhs );
4758 
4759  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
4760  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4761  }
4762 
4763  decltype(auto) left( derestrict( *this ) );
4764 
4765  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4766  const ResultType_<VT> tmp( right );
4767  smpAssign( left, tmp );
4768  }
4769  else {
4770  if( IsSparseVector<VT>::value )
4771  reset();
4772  smpAssign( left, right );
4773  }
4774 
4775  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4776 
4777  return *this;
4778 }
4780 //*************************************************************************************************
4781 
4782 
4783 //*************************************************************************************************
4797 template< typename MT > // Type of the dense matrix
4798 template< typename VT > // Type of the right-hand side vector
4799 inline Column<MT,false,true,true>&
4800  Column<MT,false,true,true>::operator+=( const Vector<VT,false>& rhs )
4801 {
4802  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4804 
4805  if( size() != (~rhs).size() ) {
4806  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4807  }
4808 
4809  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4810  Right right( ~rhs );
4811 
4812  if( !tryAddAssign( matrix_, right, 0UL, col_ ) ) {
4813  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4814  }
4815 
4816  decltype(auto) left( derestrict( *this ) );
4817 
4818  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4819  const ResultType_<VT> tmp( right );
4820  smpAddAssign( left, tmp );
4821  }
4822  else {
4823  smpAddAssign( left, right );
4824  }
4825 
4826  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4827 
4828  return *this;
4829 }
4831 //*************************************************************************************************
4832 
4833 
4834 //*************************************************************************************************
4848 template< typename MT > // Type of the dense matrix
4849 template< typename VT > // Type of the right-hand side vector
4850 inline Column<MT,false,true,true>&
4851  Column<MT,false,true,true>::operator-=( const Vector<VT,false>& rhs )
4852 {
4853  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4855 
4856  if( size() != (~rhs).size() ) {
4857  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4858  }
4859 
4860  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4861  Right right( ~rhs );
4862 
4863  if( !trySubAssign( matrix_, right, 0UL, col_ ) ) {
4864  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4865  }
4866 
4867  decltype(auto) left( derestrict( *this ) );
4868 
4869  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4870  const ResultType_<VT> tmp( right );
4871  smpSubAssign( left, tmp );
4872  }
4873  else {
4874  smpSubAssign( left, right );
4875  }
4876 
4877  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4878 
4879  return *this;
4880 }
4882 //*************************************************************************************************
4883 
4884 
4885 //*************************************************************************************************
4898 template< typename MT > // Type of the dense matrix
4899 template< typename VT > // Type of the right-hand side dense vector
4900 inline Column<MT,false,true,true>&
4901  Column<MT,false,true,true>::operator*=( const DenseVector<VT,false>& rhs )
4902 {
4903  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4905 
4906  if( size() != (~rhs).size() ) {
4907  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4908  }
4909 
4910  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4911  Right right( ~rhs );
4912 
4913  if( !tryMultAssign( matrix_, right, 0UL, col_ ) ) {
4914  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4915  }
4916 
4917  decltype(auto) left( derestrict( *this ) );
4918 
4919  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4920  const ResultType_<VT> tmp( right );
4921  smpMultAssign( left, tmp );
4922  }
4923  else {
4924  smpMultAssign( left, right );
4925  }
4926 
4927  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4928 
4929  return *this;
4930 }
4932 //*************************************************************************************************
4933 
4934 
4935 //*************************************************************************************************
4948 template< typename MT > // Type of the dense matrix
4949 template< typename VT > // Type of the right-hand side sparse vector
4950 inline Column<MT,false,true,true>&
4951  Column<MT,false,true,true>::operator*=( const SparseVector<VT,false>& rhs )
4952 {
4956 
4957  if( size() != (~rhs).size() ) {
4958  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4959  }
4960 
4961  const ResultType right( *this * (~rhs) );
4962 
4963  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
4964  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4965  }
4966 
4967  decltype(auto) left( derestrict( *this ) );
4968 
4969  smpAssign( left, right );
4970 
4971  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4972 
4973  return *this;
4974 }
4976 //*************************************************************************************************
4977 
4978 
4979 //*************************************************************************************************
4991 template< typename MT > // Type of the dense matrix
4992 template< typename VT > // Type of the right-hand side dense vector
4993 inline Column<MT,false,true,true>&
4994  Column<MT,false,true,true>::operator/=( const DenseVector<VT,false>& rhs )
4995 {
4996  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4998 
4999  if( size() != (~rhs).size() ) {
5000  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5001  }
5002 
5003  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
5004  Right right( ~rhs );
5005 
5006  if( !tryDivAssign( matrix_, right, 0UL, col_ ) ) {
5007  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5008  }
5009 
5010  decltype(auto) left( derestrict( *this ) );
5011 
5012  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
5013  const ResultType_<VT> tmp( right );
5014  smpDivAssign( left, tmp );
5015  }
5016  else {
5017  smpDivAssign( left, right );
5018  }
5019 
5020  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5021 
5022  return *this;
5023 }
5025 //*************************************************************************************************
5026 
5027 
5028 //*************************************************************************************************
5041 template< typename MT > // Type of the dense matrix
5042 template< typename VT > // Type of the right-hand side vector
5043 inline Column<MT,false,true,true>&
5044  Column<MT,false,true,true>::operator%=( const Vector<VT,false>& rhs )
5045 {
5046  using blaze::assign;
5047 
5048  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
5050 
5051  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
5052 
5056 
5057  if( size() != 3UL || (~rhs).size() != 3UL ) {
5058  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
5059  }
5060 
5061  const CrossType right( *this % (~rhs) );
5062 
5063  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
5064  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5065  }
5066 
5067  decltype(auto) left( derestrict( *this ) );
5068 
5069  assign( left, right );
5070 
5071  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5072 
5073  return *this;
5074 }
5076 //*************************************************************************************************
5077 
5078 
5079 //*************************************************************************************************
5090 template< typename MT > // Type of the dense matrix
5091 template< typename Other > // Data type of the right-hand side scalar
5092 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,true> >&
5093  Column<MT,false,true,true>::operator*=( Other rhs )
5094 {
5096 
5097  return operator=( (*this) * rhs );
5098 }
5100 //*************************************************************************************************
5101 
5102 
5103 //*************************************************************************************************
5116 template< typename MT > // Type of the dense matrix
5117 template< typename Other > // Data type of the right-hand side scalar
5118 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,true> >&
5120 {
5122 
5123  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
5124 
5125  return operator=( (*this) / rhs );
5126 }
5128 //*************************************************************************************************
5129 
5130 
5131 
5132 
5133 //=================================================================================================
5134 //
5135 // UTILITY FUNCTIONS
5136 //
5137 //=================================================================================================
5138 
5139 //*************************************************************************************************
5145 template< typename MT > // Type of the dense matrix
5146 inline typename Column<MT,false,true,true>::Operand
5147  Column<MT,false,true,true>::operand() const noexcept
5148 {
5149  return matrix_;
5150 }
5152 //*************************************************************************************************
5153 
5154 
5155 //*************************************************************************************************
5161 template< typename MT > // Type of the dense matrix
5162 inline size_t Column<MT,false,true,true>::column() const noexcept
5163 {
5164  return col_;
5165 }
5167 //*************************************************************************************************
5168 
5169 
5170 //*************************************************************************************************
5176 template< typename MT > // Type of the dense matrix
5177 inline size_t Column<MT,false,true,true>::size() const noexcept
5178 {
5179  return matrix_.rows();
5180 }
5182 //*************************************************************************************************
5183 
5184 
5185 //*************************************************************************************************
5194 template< typename MT > // Type of the dense matrix
5195 inline size_t Column<MT,false,true,true>::spacing() const noexcept
5196 {
5197  return matrix_.spacing();
5198 }
5200 //*************************************************************************************************
5201 
5202 
5203 //*************************************************************************************************
5209 template< typename MT > // Type of the dense matrix
5210 inline size_t Column<MT,false,true,true>::capacity() const noexcept
5211 {
5212  return matrix_.capacity( col_ );
5213 }
5215 //*************************************************************************************************
5216 
5217 
5218 //*************************************************************************************************
5227 template< typename MT > // Type of the dense matrix
5228 inline size_t Column<MT,false,true,true>::nonZeros() const
5229 {
5230  return matrix_.nonZeros( col_ );
5231 }
5233 //*************************************************************************************************
5234 
5235 
5236 //*************************************************************************************************
5242 template< typename MT > // Type of the dense matrix
5244 {
5245  matrix_.reset( col_ );
5246 }
5248 //*************************************************************************************************
5249 
5250 
5251 
5252 
5253 //=================================================================================================
5254 //
5255 // NUMERIC FUNCTIONS
5256 //
5257 //=================================================================================================
5258 
5259 //*************************************************************************************************
5272 template< typename MT > // Type of the dense matrix
5273 template< typename Other > // Data type of the scalar value
5274 inline Column<MT,false,true,true>& Column<MT,false,true,true>::scale( const Other& scalar )
5275 {
5277 
5278  const size_t jbegin( ( IsUpper<MT>::value )
5279  ?( ( IsStrictlyUpper<MT>::value )
5280  ?( col_+1UL )
5281  :( col_ ) )
5282  :( 0UL ) );
5283  const size_t jend ( ( IsLower<MT>::value )
5284  ?( ( IsStrictlyLower<MT>::value )
5285  ?( col_ )
5286  :( col_+1UL ) )
5287  :( size() ) );
5288 
5289  for( size_t j=jbegin; j<jend; ++j ) {
5290  matrix_(col_,j) *= scalar;
5291  }
5292 
5293  return *this;
5294 }
5296 //*************************************************************************************************
5297 
5298 
5299 
5300 
5301 //=================================================================================================
5302 //
5303 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5304 //
5305 //=================================================================================================
5306 
5307 //*************************************************************************************************
5318 template< typename MT > // Type of the dense matrix
5319 template< typename Other > // Data type of the foreign expression
5320 inline bool Column<MT,false,true,true>::canAlias( const Other* alias ) const noexcept
5321 {
5322  return matrix_.isAliased( alias );
5323 }
5325 //*************************************************************************************************
5326 
5327 
5328 //*************************************************************************************************
5339 template< typename MT > // Type of the dense matrix
5340 template< typename MT2 // Data type of the foreign dense column
5341  , bool SO2 // Storage order of the foreign dense column
5342  , bool SF2 > // Symmetry flag of the foreign dense column
5343 inline bool Column<MT,false,true,true>::canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
5344 {
5345  return matrix_.isAliased( alias->matrix_ ) && ( col_ == alias->col_ );
5346 }
5348 //*************************************************************************************************
5349 
5350 
5351 //*************************************************************************************************
5362 template< typename MT > // Type of the dense matrix
5363 template< typename Other > // Data type of the foreign expression
5364 inline bool Column<MT,false,true,true>::isAliased( const Other* alias ) const noexcept
5365 {
5366  return matrix_.isAliased( alias );
5367 }
5369 //*************************************************************************************************
5370 
5371 
5372 //*************************************************************************************************
5383 template< typename MT > // Type of the dense matrix
5384 template< typename MT2 // Data type of the foreign dense column
5385  , bool SO2 // Storage order of the foreign dense column
5386  , bool SF2 > // Symmetry flag of the foreign dense column
5387 inline bool Column<MT,false,true,true>::isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
5388 {
5389  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
5390 }
5392 //*************************************************************************************************
5393 
5394 
5395 //*************************************************************************************************
5405 template< typename MT > // Type of the dense matrix
5406 inline bool Column<MT,false,true,true>::isAligned() const noexcept
5407 {
5408  return matrix_.isAligned();
5409 }
5411 //*************************************************************************************************
5412 
5413 
5414 //*************************************************************************************************
5425 template< typename MT > // Type of the dense matrix
5426 inline bool Column<MT,false,true,true>::canSMPAssign() const noexcept
5427 {
5428  return ( size() > SMP_DVECASSIGN_THRESHOLD );
5429 }
5431 //*************************************************************************************************
5432 
5433 
5434 //*************************************************************************************************
5446 template< typename MT > // Type of the dense matrix
5447 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true>::SIMDType
5448  Column<MT,false,true,true>::load( size_t index ) const noexcept
5449 {
5450  return matrix_.load( col_, index );
5451 }
5453 //*************************************************************************************************
5454 
5455 
5456 //*************************************************************************************************
5469 template< typename MT > // Type of the dense matrix
5470 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true>::SIMDType
5471  Column<MT,false,true,true>::loada( size_t index ) const noexcept
5472 {
5473  return matrix_.loada( col_, index );
5474 }
5476 //*************************************************************************************************
5477 
5478 
5479 //*************************************************************************************************
5492 template< typename MT > // Type of the dense matrix
5493 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true>::SIMDType
5494  Column<MT,false,true,true>::loadu( size_t index ) const noexcept
5495 {
5496  return matrix_.loadu( col_, index );
5497 }
5499 //*************************************************************************************************
5500 
5501 
5502 //*************************************************************************************************
5515 template< typename MT > // Type of the dense matrix
5517  Column<MT,false,true,true>::store( size_t index, const SIMDType& value ) noexcept
5518 {
5519  matrix_.store( col_, index, value );
5520 }
5522 //*************************************************************************************************
5523 
5524 
5525 //*************************************************************************************************
5539 template< typename MT > // Type of the dense matrix
5541  Column<MT,false,true,true>::storea( size_t index, const SIMDType& value ) noexcept
5542 {
5543  matrix_.storea( col_, index, value );
5544 }
5546 //*************************************************************************************************
5547 
5548 
5549 //*************************************************************************************************
5563 template< typename MT > // Type of the dense matrix
5565  Column<MT,false,true,true>::storeu( size_t index, const SIMDType& value ) noexcept
5566 {
5567  matrix_.storeu( col_, index, value );
5568 }
5570 //*************************************************************************************************
5571 
5572 
5573 //*************************************************************************************************
5587 template< typename MT > // Type of the dense matrix
5589  Column<MT,false,true,true>::stream( size_t index, const SIMDType& value ) noexcept
5590 {
5591  matrix_.stream( col_, index, value );
5592 }
5594 //*************************************************************************************************
5595 
5596 
5597 //*************************************************************************************************
5609 template< typename MT > // Type of the dense matrix
5610 template< typename VT > // Type of the right-hand side dense vector
5611 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5612  Column<MT,false,true,true>::assign( const DenseVector<VT,false>& rhs )
5613 {
5614  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5615 
5616  const size_t jpos( (~rhs).size() & size_t(-2) );
5617  for( size_t j=0UL; j<jpos; j+=2UL ) {
5618  matrix_(col_,j ) = (~rhs)[j ];
5619  matrix_(col_,j+1UL) = (~rhs)[j+1UL];
5620  }
5621  if( jpos < (~rhs).size() )
5622  matrix_(col_,jpos) = (~rhs)[jpos];
5623 }
5625 //*************************************************************************************************
5626 
5627 
5628 //*************************************************************************************************
5640 template< typename MT > // Type of the dense matrix
5641 template< typename VT > // Type of the right-hand side dense vector
5642 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5643  Column<MT,false,true,true>::assign( const DenseVector<VT,false>& rhs )
5644 {
5646 
5647  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5648 
5649  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5650 
5651  const size_t columns( size() );
5652 
5653  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5654  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5655 
5656  size_t j( 0UL );
5657  Iterator left( begin() );
5658  ConstIterator_<VT> right( (~rhs).begin() );
5659 
5660  if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
5661  {
5662  for( ; j<jpos; j+=SIMDSIZE ) {
5663  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5664  }
5665  for( ; remainder && j<columns; ++j ) {
5666  *left = *right; ++left; ++right;
5667  }
5668  }
5669  else
5670  {
5671  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5672  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5673  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5674  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5675  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5676  }
5677  for( ; j<jpos; j+=SIMDSIZE ) {
5678  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5679  }
5680  for( ; remainder && j<columns; ++j ) {
5681  *left = *right; ++left; ++right;
5682  }
5683  }
5684 }
5686 //*************************************************************************************************
5687 
5688 
5689 //*************************************************************************************************
5701 template< typename MT > // Type of the dense matrix
5702 template< typename VT > // Type of the right-hand side sparse vector
5703 inline void Column<MT,false,true,true>::assign( const SparseVector<VT,false>& rhs )
5704 {
5705  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5706 
5707  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5708  matrix_(col_,element->index()) = element->value();
5709 }
5711 //*************************************************************************************************
5712 
5713 
5714 //*************************************************************************************************
5726 template< typename MT > // Type of the dense matrix
5727 template< typename VT > // Type of the right-hand side dense vector
5728 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5729  Column<MT,false,true,true>::addAssign( const DenseVector<VT,false>& rhs )
5730 {
5731  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5732 
5733  const size_t jpos( (~rhs).size() & size_t(-2) );
5734  for( size_t j=0UL; j<jpos; j+=2UL ) {
5735  matrix_(col_,j ) += (~rhs)[j ];
5736  matrix_(col_,j+1UL) += (~rhs)[j+1UL];
5737  }
5738  if( jpos < (~rhs).size() )
5739  matrix_(col_,jpos) += (~rhs)[jpos];
5740 }
5742 //*************************************************************************************************
5743 
5744 
5745 //*************************************************************************************************
5757 template< typename MT > // Type of the dense matrix
5758 template< typename VT > // Type of the right-hand side dense vector
5759 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5760  Column<MT,false,true,true>::addAssign( const DenseVector<VT,false>& rhs )
5761 {
5763 
5764  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5765 
5766  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5767 
5768  const size_t columns( size() );
5769 
5770  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5771  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5772 
5773  size_t j( 0UL );
5774  Iterator left( begin() );
5775  ConstIterator_<VT> right( (~rhs).begin() );
5776 
5777  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5778  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5779  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5780  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5781  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5782  }
5783  for( ; j<jpos; j+=SIMDSIZE ) {
5784  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5785  }
5786  for( ; remainder && j<columns; ++j ) {
5787  *left += *right; ++left; ++right;
5788  }
5789 }
5791 //*************************************************************************************************
5792 
5793 
5794 //*************************************************************************************************
5806 template< typename MT > // Type of the dense matrix
5807 template< typename VT > // Type of the right-hand side sparse vector
5808 inline void Column<MT,false,true,true>::addAssign( const SparseVector<VT,false>& rhs )
5809 {
5810  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5811 
5812  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5813  matrix_(col_,element->index()) += element->value();
5814 }
5816 //*************************************************************************************************
5817 
5818 
5819 //*************************************************************************************************
5831 template< typename MT > // Type of the dense matrix
5832 template< typename VT > // Type of the right-hand side dense vector
5833 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5834  Column<MT,false,true,true>::subAssign( const DenseVector<VT,false>& rhs )
5835 {
5836  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5837 
5838  const size_t jpos( (~rhs).size() & size_t(-2) );
5839  for( size_t j=0UL; j<jpos; j+=2UL ) {
5840  matrix_(col_,j ) -= (~rhs)[j ];
5841  matrix_(col_,j+1UL) -= (~rhs)[j+1UL];
5842  }
5843  if( jpos < (~rhs).size() )
5844  matrix_(col_,jpos) -= (~rhs)[jpos];
5845 }
5847 //*************************************************************************************************
5848 
5849 
5850 //*************************************************************************************************
5862 template< typename MT > // Type of the dense matrix
5863 template< typename VT > // Type of the right-hand side dense vector
5864 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5865  Column<MT,false,true,true>::subAssign( const DenseVector<VT,false>& rhs )
5866 {
5868 
5869  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5870 
5871  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5872 
5873  const size_t columns( size() );
5874 
5875  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5876  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5877 
5878  size_t j( 0UL );
5879  Iterator left( begin() );
5880  ConstIterator_<VT> right( (~rhs).begin() );
5881 
5882  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5883  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5884  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5885  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5886  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5887  }
5888  for( ; j<jpos; j+=SIMDSIZE ) {
5889  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5890  }
5891  for( ; remainder && j<columns; ++j ) {
5892  *left -= *right; ++left; ++right;
5893  }
5894 }
5896 //*************************************************************************************************
5897 
5898 
5899 //*************************************************************************************************
5911 template< typename MT > // Type of the dense matrix
5912 template< typename VT > // Type of the right-hand side sparse vector
5913 inline void Column<MT,false,true,true>::subAssign( const SparseVector<VT,false>& rhs )
5914 {
5915  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5916 
5917  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5918  matrix_(col_,element->index()) -= element->value();
5919 }
5921 //*************************************************************************************************
5922 
5923 
5924 //*************************************************************************************************
5936 template< typename MT > // Type of the dense matrix
5937 template< typename VT > // Type of the right-hand side dense vector
5938 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5939  Column<MT,false,true,true>::multAssign( const DenseVector<VT,false>& rhs )
5940 {
5941  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5942 
5943  const size_t jpos( (~rhs).size() & size_t(-2) );
5944  for( size_t j=0UL; j<jpos; j+=2UL ) {
5945  matrix_(col_,j ) *= (~rhs)[j ];
5946  matrix_(col_,j+1UL) *= (~rhs)[j+1UL];
5947  }
5948  if( jpos < (~rhs).size() )
5949  matrix_(col_,jpos) *= (~rhs)[jpos];
5950 }
5952 //*************************************************************************************************
5953 
5954 
5955 //*************************************************************************************************
5967 template< typename MT > // Type of the dense matrix
5968 template< typename VT > // Type of the right-hand side dense vector
5969 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5970  Column<MT,false,true,true>::multAssign( const DenseVector<VT,false>& rhs )
5971 {
5973 
5974  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5975 
5976  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5977 
5978  const size_t columns( size() );
5979 
5980  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5981  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5982 
5983  size_t j( 0UL );
5984  Iterator left( begin() );
5985  ConstIterator_<VT> right( (~rhs).begin() );
5986 
5987  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5988  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5989  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5990  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5991  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5992  }
5993  for( ; j<jpos; j+=SIMDSIZE ) {
5994  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5995  }
5996  for( ; remainder && j<columns; ++j ) {
5997  *left *= *right; ++left; ++right;
5998  }
5999 }
6001 //*************************************************************************************************
6002 
6003 
6004 //*************************************************************************************************
6016 template< typename MT > // Type of the dense matrix
6017 template< typename VT > // Type of the right-hand side sparse vector
6018 inline void Column<MT,false,true,true>::multAssign( const SparseVector<VT,false>& rhs )
6019 {
6020  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6021 
6022  const ResultType tmp( serial( *this ) );
6023 
6024  reset();
6025 
6026  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
6027  matrix_(col_,element->index()) = tmp[element->index()] * element->value();
6028 }
6030 //*************************************************************************************************
6031 
6032 
6033 //*************************************************************************************************
6045 template< typename MT > // Type of the dense matrix
6046 template< typename VT > // Type of the right-hand side dense vector
6047 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
6048  Column<MT,false,true,true>::divAssign( const DenseVector<VT,false>& rhs )
6049 {
6050  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6051 
6052  const size_t jpos( (~rhs).size() & size_t(-2) );
6053  for( size_t j=0UL; j<jpos; j+=2UL ) {
6054  matrix_(col_,j ) /= (~rhs)[j ];
6055  matrix_(col_,j+1UL) /= (~rhs)[j+1UL];
6056  }
6057  if( jpos < (~rhs).size() )
6058  matrix_(col_,jpos) /= (~rhs)[jpos];
6059 }
6061 //*************************************************************************************************
6062 
6063 
6064 //*************************************************************************************************
6076 template< typename MT > // Type of the dense matrix
6077 template< typename VT > // Type of the right-hand side dense vector
6078 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
6079  Column<MT,false,true,true>::divAssign( const DenseVector<VT,false>& rhs )
6080 {
6082 
6083  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6084 
6085  const size_t columns( size() );
6086 
6087  const size_t jpos( columns & size_t(-SIMDSIZE) );
6088  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
6089 
6090  size_t j( 0UL );
6091  Iterator left( begin() );
6092  ConstIterator_<VT> right( (~rhs).begin() );
6093 
6094  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
6095  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6096  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6097  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6098  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6099  }
6100  for( ; j<jpos; j+=SIMDSIZE ) {
6101  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6102  }
6103  for( ; j<columns; ++j ) {
6104  *left /= *right; ++left; ++right;
6105  }
6106 }
6108 //*************************************************************************************************
6109 
6110 } // namespace blaze
6111 
6112 #endif
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the IsUniUpper type trait.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:356
Header file for basic type definitions.
Header file for the View base class.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a column dense or sparse vector type...
Definition: ColumnVector.h:61
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:61
BLAZE_ALWAYS_INLINE T1 & operator/=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Division assignment operator for the division of two SIMD packs.
Definition: BasicTypes.h:1411
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3078
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:198
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
Header file for the implementation of the Column base template.
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:560
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:699
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3080
Header file for the DenseVector base class.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3085
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:394
Column< MT > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:124
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a symmetric matrix type...
Definition: Symmetric.h:60
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:731
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3086
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
System settings for performance optimizations.
BLAZE_ALWAYS_INLINE T1 & operator*=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Multiplication assignment operator for the multiplication of two SIMD packs.
Definition: BasicTypes.h:1393
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
Header file for the IsUniLower type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
BLAZE_ALWAYS_INLINE 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:308
BLAZE_ALWAYS_INLINE 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:242
Constraint on the data type.
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:110
Header file for the std::initializer_list aliases.
Constraint on the transpose flag of vector types.
Row< MT > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:124
Constraint on the data type.
Header file for the DisableIf class template.
Header file for the IsStrictlyUpper type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3084
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:57
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
Header file for nested template disabiguation.
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3077
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3081
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
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:367
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:443
Header file for the Not class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3087
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for all SIMD functionality.
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:340
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE 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:264
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:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:580
Header file for the IsPadded type trait.
Constraint on the data type.
Header file for the IsNumeric type trait.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< 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:75
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the cross product trait.
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
Header file for the cache size of the target architecture.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the column trait.
Header file for the isDefault shim.
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
Constraints on the storage order of matrix types.
decltype(auto) serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:819
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
Header file for the RemoveReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:324
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3082
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type...
Definition: DenseVector.h:61
Header file for the HasSIMDDiv type trait.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3083
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:252
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:600
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
Header file for the IsRestricted type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the TrueType type/value trait base class.
Header file for the IsExpression type trait class.