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 DenseVector< Column<MT,true,true,SF>, false >
123  , private View
124 {
125  private:
126  //**Type definitions****************************************************************************
128  typedef If_< IsExpression<MT>, MT, MT& > Operand;
129  //**********************************************************************************************
130 
131  public:
132  //**Type definitions****************************************************************************
133  typedef Column<MT,true,true,SF> This;
134  typedef DenseVector<This,false> BaseType;
135  typedef ColumnTrait_<MT> ResultType;
136  typedef TransposeType_<ResultType> TransposeType;
137  typedef ElementType_<MT> ElementType;
138  typedef SIMDTrait_<ElementType> SIMDType;
139  typedef ReturnType_<MT> ReturnType;
140  typedef const Column& CompositeType;
141 
143  typedef ConstReference_<MT> ConstReference;
144 
146  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
147 
149  typedef const ElementType* ConstPointer;
150 
152  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
153 
155  typedef ConstIterator_<MT> ConstIterator;
156 
158  typedef If_< IsConst<MT>, ConstIterator, Iterator_<MT> > Iterator;
159  //**********************************************************************************************
160 
161  //**Compilation flags***************************************************************************
163  enum : bool { simdEnabled = MT::simdEnabled };
164 
166  enum : bool { smpAssignable = MT::smpAssignable };
167  //**********************************************************************************************
168 
169  //**Constructors********************************************************************************
172  explicit inline Column( Operand matrix, size_t index );
173  // No explicitly declared copy constructor.
175  //**********************************************************************************************
176 
177  //**Destructor**********************************************************************************
178  // No explicitly declared destructor.
179  //**********************************************************************************************
180 
181  //**Data access functions***********************************************************************
184  inline Reference operator[]( size_t index );
185  inline ConstReference operator[]( size_t index ) const;
186  inline Reference at( size_t index );
187  inline ConstReference at( size_t index ) const;
188  inline Pointer data () noexcept;
189  inline ConstPointer data () const noexcept;
190  inline Iterator begin ();
191  inline ConstIterator begin () const;
192  inline ConstIterator cbegin() const;
193  inline Iterator end ();
194  inline ConstIterator end () const;
195  inline ConstIterator cend () const;
197  //**********************************************************************************************
198 
199  //**Assignment operators************************************************************************
202  inline Column& operator=( const ElementType& rhs );
203  inline Column& operator=( initializer_list<ElementType> list );
204  inline Column& operator=( const Column& rhs );
205 
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 Vector<VT,false>& rhs );
209  template< typename VT > inline Column& operator*=( const DenseVector<VT,false>& rhs );
210  template< typename VT > inline Column& operator*=( const SparseVector<VT,false>& rhs );
211  template< typename VT > inline Column& operator/=( const DenseVector<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 size_t size() const noexcept;
225  inline size_t capacity() const noexcept;
226  inline size_t nonZeros() const;
227  inline void reset();
229  //**********************************************************************************************
230 
231  //**Numeric functions***************************************************************************
234  template< typename Other > inline Column& scale( const Other& scalar );
236  //**********************************************************************************************
237 
238  private:
239  //**********************************************************************************************
241  template< typename VT >
242  struct VectorizedAssign {
243  enum : bool { value = useOptimizedKernels &&
244  simdEnabled && VT::simdEnabled &&
245  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
246  };
247  //**********************************************************************************************
248 
249  //**********************************************************************************************
251  template< typename VT >
252  struct VectorizedAddAssign {
253  enum : bool { value = useOptimizedKernels &&
254  simdEnabled && VT::simdEnabled &&
255  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
256  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
257  };
258  //**********************************************************************************************
259 
260  //**********************************************************************************************
262  template< typename VT >
263  struct VectorizedSubAssign {
264  enum : bool { value = useOptimizedKernels &&
265  simdEnabled && VT::simdEnabled &&
266  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
267  HasSIMDSub< ElementType, ElementType_<VT> >::value };
268  };
269  //**********************************************************************************************
270 
271  //**********************************************************************************************
273  template< typename VT >
274  struct VectorizedMultAssign {
275  enum : bool { value = useOptimizedKernels &&
276  simdEnabled && VT::simdEnabled &&
277  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
278  HasSIMDMult< ElementType, ElementType_<VT> >::value };
279  };
280  //**********************************************************************************************
281 
282  //**********************************************************************************************
284  template< typename VT >
285  struct VectorizedDivAssign {
286  enum : bool { value = useOptimizedKernels &&
287  simdEnabled && VT::simdEnabled &&
288  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
289  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
290  };
291  //**********************************************************************************************
292 
293  //**SIMD properties*****************************************************************************
295  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
296  //**********************************************************************************************
297 
298  public:
299  //**Expression template evaluation functions****************************************************
302  template< typename Other >
303  inline bool canAlias( const Other* alias ) const noexcept;
304 
305  template< typename MT2, bool SO2, bool SF2 >
306  inline bool canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
307 
308  template< typename Other >
309  inline bool isAliased( const Other* alias ) const noexcept;
310 
311  template< typename MT2, bool SO2, bool SF2 >
312  inline bool isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
313 
314  inline bool isAligned () const noexcept;
315  inline bool canSMPAssign() const noexcept;
316 
317  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
318  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
319  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
320 
321  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
322  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
323  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
324  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
325 
326  template< typename VT >
327  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
328 
329  template< typename VT >
330  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
331 
332  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
333 
334  template< typename VT >
335  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
336 
337  template< typename VT >
338  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
339 
340  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
341 
342  template< typename VT >
343  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
344 
345  template< typename VT >
346  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
347 
348  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
349 
350  template< typename VT >
351  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
352 
353  template< typename VT >
354  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
355 
356  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
357 
358  template< typename VT >
359  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
360 
361  template< typename VT >
362  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
364  //**********************************************************************************************
365 
366  private:
367  //**Member variables****************************************************************************
370  Operand matrix_;
371  const size_t col_;
372 
373  //**********************************************************************************************
374 
375  //**Friend declarations*************************************************************************
376  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Column;
377 
378  template< typename MT2, bool SO2, bool DF2, bool SF2 >
379  friend bool isIntact( const Column<MT2,SO2,DF2,SF2>& column ) noexcept;
380 
381  template< typename MT2, bool SO2, bool DF2, bool SF2 >
382  friend bool isSame( const Column<MT2,SO2,DF2,SF2>& a, const Column<MT2,SO2,DF2,SF2>& b ) noexcept;
383 
384  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
385  friend bool tryAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
386 
387  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
388  friend bool tryAddAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
389 
390  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
391  friend bool trySubAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
392 
393  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
394  friend bool tryMultAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
395 
396  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
397  friend bool tryDivAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
398 
399  template< typename MT2, bool SO2, bool DF2, bool SF2 >
400  friend DerestrictTrait_< Column<MT2,SO2,DF2,SF2> > derestrict( Column<MT2,SO2,DF2,SF2>& column );
401  //**********************************************************************************************
402 
403  //**Compile time checks*************************************************************************
410  //**********************************************************************************************
411 };
413 //*************************************************************************************************
414 
415 
416 
417 
418 //=================================================================================================
419 //
420 // CONSTRUCTOR
421 //
422 //=================================================================================================
423 
424 //*************************************************************************************************
432 template< typename MT // Type of the dense matrix
433  , bool SF > // Symmetry flag
434 inline Column<MT,true,true,SF>::Column( Operand matrix, size_t index )
435  : matrix_( matrix ) // The dense matrix containing the column
436  , col_ ( index ) // The index of the column in the matrix
437 {
438  if( matrix_.columns() <= index ) {
439  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
440  }
441 }
443 //*************************************************************************************************
444 
445 
446 
447 
448 //=================================================================================================
449 //
450 // DATA ACCESS FUNCTIONS
451 //
452 //=================================================================================================
453 
454 //*************************************************************************************************
464 template< typename MT // Type of the dense matrix
465  , bool SF > // Symmetry flag
466 inline typename Column<MT,true,true,SF>::Reference Column<MT,true,true,SF>::operator[]( size_t index )
467 {
468  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
469  return matrix_(index,col_);
470 }
472 //*************************************************************************************************
473 
474 
475 //*************************************************************************************************
485 template< typename MT // Type of the dense matrix
486  , bool SF > // Symmetry flag
488  Column<MT,true,true,SF>::operator[]( size_t index ) const
489 {
490  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
491  return const_cast<const MT&>( matrix_ )(index,col_);
492 }
494 //*************************************************************************************************
495 
496 
497 //*************************************************************************************************
508 template< typename MT // Type of the dense matrix
509  , bool SF > // Symmetry flag
510 inline typename Column<MT,true,true,SF>::Reference Column<MT,true,true,SF>::at( size_t index )
511 {
512  if( index >= size() ) {
513  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
514  }
515  return (*this)[index];
516 }
518 //*************************************************************************************************
519 
520 
521 //*************************************************************************************************
532 template< typename MT // Type of the dense matrix
533  , bool SF > // Symmetry flag
535  Column<MT,true,true,SF>::at( size_t index ) const
536 {
537  if( index >= size() ) {
538  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
539  }
540  return (*this)[index];
541 }
543 //*************************************************************************************************
544 
545 
546 //*************************************************************************************************
555 template< typename MT // Type of the dense matrix
556  , bool SF > // Symmetry flag
557 inline typename Column<MT,true,true,SF>::Pointer Column<MT,true,true,SF>::data() noexcept
558 {
559  return matrix_.data( col_ );
560 }
562 //*************************************************************************************************
563 
564 
565 //*************************************************************************************************
574 template< typename MT // Type of the dense matrix
575  , bool SF > // Symmetry flag
576 inline typename Column<MT,true,true,SF>::ConstPointer Column<MT,true,true,SF>::data() const noexcept
577 {
578  return matrix_.data( col_ );
579 }
581 //*************************************************************************************************
582 
583 
584 //*************************************************************************************************
592 template< typename MT // Type of the dense matrix
593  , bool SF > // Symmetry flag
595 {
596  return matrix_.begin( col_ );
597 }
599 //*************************************************************************************************
600 
601 
602 //*************************************************************************************************
610 template< typename MT // Type of the dense matrix
611  , bool SF > // Symmetry flag
613 {
614  return matrix_.cbegin( col_ );
615 }
617 //*************************************************************************************************
618 
619 
620 //*************************************************************************************************
628 template< typename MT // Type of the dense matrix
629  , bool SF > // Symmetry flag
631 {
632  return matrix_.cbegin( col_ );
633 }
635 //*************************************************************************************************
636 
637 
638 //*************************************************************************************************
646 template< typename MT // Type of the dense matrix
647  , bool SF > // Symmetry flag
649 {
650  return matrix_.end( col_ );
651 }
653 //*************************************************************************************************
654 
655 
656 //*************************************************************************************************
664 template< typename MT // Type of the dense matrix
665  , bool SF > // Symmetry flag
667 {
668  return matrix_.cend( col_ );
669 }
671 //*************************************************************************************************
672 
673 
674 //*************************************************************************************************
682 template< typename MT // Type of the dense matrix
683  , bool SF > // Symmetry flag
685 {
686  return matrix_.cend( col_ );
687 }
689 //*************************************************************************************************
690 
691 
692 
693 
694 //=================================================================================================
695 //
696 // ASSIGNMENT OPERATORS
697 //
698 //=================================================================================================
699 
700 //*************************************************************************************************
711 template< typename MT // Type of the dense matrix
712  , bool SF > // Symmetry flag
713 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( const ElementType& rhs )
714 {
715  const size_t ibegin( ( IsLower<MT>::value )
716  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
717  ?( col_+1UL )
718  :( col_ ) )
719  :( 0UL ) );
720  const size_t iend ( ( IsUpper<MT>::value )
721  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
722  ?( col_ )
723  :( col_+1UL ) )
724  :( size() ) );
725 
726  for( size_t i=ibegin; i<iend; ++i )
727  matrix_(i,col_) = rhs;
728 
729  return *this;
730 }
732 //*************************************************************************************************
733 
734 
735 //*************************************************************************************************
748 template< typename MT // Type of the dense matrix
749  , bool SF > // Symmetry flag
750 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( initializer_list<ElementType> list )
751 {
752  if( list.size() > size() ) {
753  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
754  }
755 
756  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
757 
758  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
759 
760  return *this;
761 }
763 //*************************************************************************************************
764 
765 
766 //*************************************************************************************************
780 template< typename MT // Type of the dense matrix
781  , bool SF > // Symmetry flag
782 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( const Column& rhs )
783 {
784  if( &rhs == this ) return *this;
785 
786  if( size() != rhs.size() ) {
787  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
788  }
789 
790  if( !tryAssign( matrix_, rhs, 0UL, col_ ) ) {
791  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
792  }
793 
794  DerestrictTrait_<This> left( derestrict( *this ) );
795 
796  smpAssign( left, rhs );
797 
798  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
799 
800  return *this;
801 }
803 //*************************************************************************************************
804 
805 
806 //*************************************************************************************************
820 template< typename MT // Type of the dense matrix
821  , bool SF > // Symmetry flag
822 template< typename VT > // Type of the right-hand side vector
823 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( const Vector<VT,false>& rhs )
824 {
827 
828  if( size() != (~rhs).size() ) {
829  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
830  }
831 
832  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
833  Right right( ~rhs );
834 
835  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
836  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
837  }
838 
839  DerestrictTrait_<This> left( derestrict( *this ) );
840 
841  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
842  const ResultType_<VT> tmp( right );
843  smpAssign( left, tmp );
844  }
845  else {
846  if( IsSparseVector<VT>::value )
847  reset();
848  smpAssign( left, right );
849  }
850 
851  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
852 
853  return *this;
854 }
856 //*************************************************************************************************
857 
858 
859 //*************************************************************************************************
873 template< typename MT // Type of the dense matrix
874  , bool SF > // Symmetry flag
875 template< typename VT > // Type of the right-hand side vector
876 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator+=( const Vector<VT,false>& rhs )
877 {
880 
881  if( size() != (~rhs).size() ) {
882  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
883  }
884 
885  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
886  Right right( ~rhs );
887 
888  if( !tryAddAssign( matrix_, right, 0UL, col_ ) ) {
889  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
890  }
891 
892  DerestrictTrait_<This> left( derestrict( *this ) );
893 
894  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
895  const ResultType_<VT> tmp( right );
896  smpAddAssign( left, tmp );
897  }
898  else {
899  smpAddAssign( left, right );
900  }
901 
902  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
903 
904  return *this;
905 }
907 //*************************************************************************************************
908 
909 
910 //*************************************************************************************************
924 template< typename MT // Type of the dense matrix
925  , bool SF > // Symmetry flag
926 template< typename VT > // Type of the right-hand side vector
927 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator-=( const Vector<VT,false>& rhs )
928 {
931 
932  if( size() != (~rhs).size() ) {
933  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
934  }
935 
936  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
937  Right right( ~rhs );
938 
939  if( !trySubAssign( matrix_, right, 0UL, col_ ) ) {
940  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
941  }
942 
943  DerestrictTrait_<This> left( derestrict( *this ) );
944 
945  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
946  const ResultType_<VT> tmp( right );
947  smpSubAssign( left, tmp );
948  }
949  else {
950  smpSubAssign( left, right );
951  }
952 
953  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
954 
955  return *this;
956 }
958 //*************************************************************************************************
959 
960 
961 //*************************************************************************************************
974 template< typename MT // Type of the dense matrix
975  , bool SF > // Symmetry flag
976 template< typename VT > // Type of the right-hand side dense vector
977 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator*=( const DenseVector<VT,false>& rhs )
978 {
981 
982  if( size() != (~rhs).size() ) {
983  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
984  }
985 
986  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
987  Right right( ~rhs );
988 
989  if( !tryMultAssign( matrix_, right, 0UL, col_ ) ) {
990  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
991  }
992 
993  DerestrictTrait_<This> left( derestrict( *this ) );
994 
995  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
996  const ResultType_<VT> tmp( right );
997  smpMultAssign( left, tmp );
998  }
999  else {
1000  smpMultAssign( left, right );
1001  }
1002 
1003  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1004 
1005  return *this;
1006 }
1008 //*************************************************************************************************
1009 
1010 
1011 //*************************************************************************************************
1024 template< typename MT // Type of the dense matrix
1025  , bool SF > // Symmetry flag
1026 template< typename VT > // Type of the right-hand side sparse vector
1027 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator*=( const SparseVector<VT,false>& rhs )
1028 {
1032 
1033  if( size() != (~rhs).size() ) {
1034  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1035  }
1036 
1037  const ResultType right( *this * (~rhs) );
1038 
1039  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
1040  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1041  }
1042 
1043  DerestrictTrait_<This> left( derestrict( *this ) );
1044 
1045  smpAssign( left, right );
1046 
1047  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1048 
1049  return *this;
1050 }
1052 //*************************************************************************************************
1053 
1054 
1055 //*************************************************************************************************
1067 template< typename MT // Type of the dense matrix
1068  , bool SF > // Symmetry flag
1069 template< typename VT > // Type of the right-hand side dense vector
1070 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator/=( const DenseVector<VT,false>& rhs )
1071 {
1072  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
1074 
1075  if( size() != (~rhs).size() ) {
1076  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1077  }
1078 
1079  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
1080  Right right( ~rhs );
1081 
1082  if( !tryDivAssign( matrix_, right, 0UL, col_ ) ) {
1083  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1084  }
1085 
1086  DerestrictTrait_<This> left( derestrict( *this ) );
1087 
1088  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1089  const ResultType_<VT> tmp( right );
1090  smpDivAssign( left, tmp );
1091  }
1092  else {
1093  smpDivAssign( left, right );
1094  }
1095 
1096  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1097 
1098  return *this;
1099 }
1101 //*************************************************************************************************
1102 
1103 
1104 //*************************************************************************************************
1115 template< typename MT // Type of the dense matrix
1116  , bool SF > // Symmetry flag
1117 template< typename Other > // Data type of the right-hand side scalar
1118 inline EnableIf_< IsNumeric<Other>, Column<MT,true,true,SF> >&
1120 {
1122 
1123  return operator=( (*this) * rhs );
1124 }
1126 //*************************************************************************************************
1127 
1128 
1129 //*************************************************************************************************
1142 template< typename MT // Type of the dense matrix
1143  , bool SF > // Symmetry flag
1144 template< typename Other > // Data type of the right-hand side scalar
1145 inline EnableIf_< IsNumeric<Other>, Column<MT,true,true,SF> >&
1147 {
1149 
1150  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1151 
1152  return operator=( (*this) / rhs );
1153 }
1155 //*************************************************************************************************
1156 
1157 
1158 
1159 
1160 //=================================================================================================
1161 //
1162 // UTILITY FUNCTIONS
1163 //
1164 //=================================================================================================
1165 
1166 //*************************************************************************************************
1172 template< typename MT // Type of the dense matrix
1173  , bool SF > // Symmetry flag
1174 inline size_t Column<MT,true,true,SF>::size() const noexcept
1175 {
1176  return matrix_.rows();
1177 }
1179 //*************************************************************************************************
1180 
1181 
1182 //*************************************************************************************************
1188 template< typename MT // Type of the dense matrix
1189  , bool SF > // Symmetry flag
1190 inline size_t Column<MT,true,true,SF>::capacity() const noexcept
1191 {
1192  return matrix_.capacity( col_ );
1193 }
1195 //*************************************************************************************************
1196 
1197 
1198 //*************************************************************************************************
1207 template< typename MT // Type of the dense matrix
1208  , bool SF > // Symmetry flag
1209 inline size_t Column<MT,true,true,SF>::nonZeros() const
1210 {
1211  return matrix_.nonZeros( col_ );
1212 }
1214 //*************************************************************************************************
1215 
1216 
1217 //*************************************************************************************************
1223 template< typename MT // Type of the dense matrix
1224  , bool SF > // Symmetry flag
1225 inline void Column<MT,true,true,SF>::reset()
1226 {
1227  matrix_.reset( col_ );
1228 }
1230 //*************************************************************************************************
1231 
1232 
1233 
1234 
1235 //=================================================================================================
1236 //
1237 // NUMERIC FUNCTIONS
1238 //
1239 //=================================================================================================
1240 
1241 //*************************************************************************************************
1252 template< typename MT // Type of the dense matrix
1253  , bool SF > // Symmetry flag
1254 template< typename Other > // Data type of the scalar value
1255 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::scale( const Other& scalar )
1256 {
1258 
1259  const size_t ibegin( ( IsLower<MT>::value )
1260  ?( ( IsStrictlyLower<MT>::value )
1261  ?( col_+1UL )
1262  :( col_ ) )
1263  :( 0UL ) );
1264  const size_t iend ( ( IsUpper<MT>::value )
1265  ?( ( IsStrictlyUpper<MT>::value )
1266  ?( col_ )
1267  :( col_+1UL ) )
1268  :( size() ) );
1269 
1270  for( size_t i=ibegin; i<iend; ++i ) {
1271  matrix_(i,col_) *= scalar;
1272  }
1273 
1274  return *this;
1275 }
1277 //*************************************************************************************************
1278 
1279 
1280 
1281 
1282 //=================================================================================================
1283 //
1284 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1285 //
1286 //=================================================================================================
1287 
1288 //*************************************************************************************************
1299 template< typename MT // Type of the dense matrix
1300  , bool SF > // Symmetry flag
1301 template< typename Other > // Data type of the foreign expression
1302 inline bool Column<MT,true,true,SF>::canAlias( const Other* alias ) const noexcept
1303 {
1304  return matrix_.isAliased( alias );
1305 }
1307 //*************************************************************************************************
1308 
1309 
1310 //*************************************************************************************************
1321 template< typename MT // Type of the dense matrix
1322  , bool SF > // Symmetry flag
1323 template< typename MT2 // Data type of the foreign dense column
1324  , bool SO2 // Storage order of the foreign dense column
1325  , bool SF2 > // Symmetry flag of the foreign dense column
1326 inline bool Column<MT,true,true,SF>::canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
1327 {
1328  return matrix_.isAliased( alias->matrix_ ) && ( col_ == alias->col_ );
1329 }
1331 //*************************************************************************************************
1332 
1333 
1334 //*************************************************************************************************
1345 template< typename MT // Type of the dense matrix
1346  , bool SF > // Symmetry flag
1347 template< typename Other > // Data type of the foreign expression
1348 inline bool Column<MT,true,true,SF>::isAliased( const Other* alias ) const noexcept
1349 {
1350  return matrix_.isAliased( alias );
1351 }
1353 //*************************************************************************************************
1354 
1355 
1356 //*************************************************************************************************
1367 template< typename MT // Type of the dense matrix
1368  , bool SF > // Symmetry flag
1369 template< typename MT2 // Data type of the foreign dense column
1370  , bool SO2 // Storage order of the foreign dense column
1371  , bool SF2 > // Symmetry flag of the foreign dense column
1372 inline bool Column<MT,true,true,SF>::isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
1373 {
1374  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
1375 }
1377 //*************************************************************************************************
1378 
1379 
1380 //*************************************************************************************************
1390 template< typename MT // Type of the dense matrix
1391  , bool SF > // Symmetry flag
1392 inline bool Column<MT,true,true,SF>::isAligned() const noexcept
1393 {
1394  return matrix_.isAligned();
1395 }
1397 //*************************************************************************************************
1398 
1399 
1400 //*************************************************************************************************
1411 template< typename MT // Type of the dense matrix
1412  , bool SF > // Symmetry flag
1413 inline bool Column<MT,true,true,SF>::canSMPAssign() const noexcept
1414 {
1415  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1416 }
1418 //*************************************************************************************************
1419 
1420 
1421 //*************************************************************************************************
1433 template< typename MT // Type of the dense matrix
1434  , bool SF > // Symmetry flag
1435 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF>::SIMDType
1436  Column<MT,true,true,SF>::load( size_t index ) const noexcept
1437 {
1438  return matrix_.load( index, col_ );
1439 }
1441 //*************************************************************************************************
1442 
1443 
1444 //*************************************************************************************************
1457 template< typename MT // Type of the dense matrix
1458  , bool SF > // Symmetry flag
1459 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF>::SIMDType
1460  Column<MT,true,true,SF>::loada( size_t index ) const noexcept
1461 {
1462  return matrix_.loada( index, col_ );
1463 }
1465 //*************************************************************************************************
1466 
1467 
1468 //*************************************************************************************************
1481 template< typename MT // Type of the dense matrix
1482  , bool SF > // Symmetry flag
1483 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF>::SIMDType
1484  Column<MT,true,true,SF>::loadu( size_t index ) const noexcept
1485 {
1486  return matrix_.loadu( index, col_ );
1487 }
1489 //*************************************************************************************************
1490 
1491 
1492 //*************************************************************************************************
1505 template< typename MT // Type of the dense matrix
1506  , bool SF > // Symmetry flag
1508  Column<MT,true,true,SF>::store( size_t index, const SIMDType& value ) noexcept
1509 {
1510  matrix_.store( index, col_, value );
1511 }
1513 //*************************************************************************************************
1514 
1515 
1516 //*************************************************************************************************
1530 template< typename MT // Type of the dense matrix
1531  , bool SF > // Symmetry flag
1533  Column<MT,true,true,SF>::storea( size_t index, const SIMDType& value ) noexcept
1534 {
1535  matrix_.storea( index, col_, value );
1536 }
1538 //*************************************************************************************************
1539 
1540 
1541 //*************************************************************************************************
1555 template< typename MT // Type of the dense matrix
1556  , bool SF > // Symmetry flag
1558  Column<MT,true,true,SF>::storeu( size_t index, const SIMDType& value ) noexcept
1559 {
1560  matrix_.storeu( index, col_, value );
1561 }
1563 //*************************************************************************************************
1564 
1565 
1566 //*************************************************************************************************
1580 template< typename MT // Type of the dense matrix
1581  , bool SF > // Symmetry flag
1583  Column<MT,true,true,SF>::stream( size_t index, const SIMDType& value ) noexcept
1584 {
1585  matrix_.stream( index, col_, value );
1586 }
1588 //*************************************************************************************************
1589 
1590 
1591 //*************************************************************************************************
1603 template< typename MT // Type of the dense matrix
1604  , bool SF > // Symmetry flag
1605 template< typename VT > // Type of the right-hand side dense vector
1606 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1607  Column<MT,true,true,SF>::assign( const DenseVector<VT,false>& rhs )
1608 {
1609  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1610 
1611  const size_t ipos( (~rhs).size() & size_t(-2) );
1612  for( size_t i=0UL; i<ipos; i+=2UL ) {
1613  matrix_(i ,col_) = (~rhs)[i ];
1614  matrix_(i+1UL,col_) = (~rhs)[i+1UL];
1615  }
1616  if( ipos < (~rhs).size() )
1617  matrix_(ipos,col_) = (~rhs)[ipos];
1618 }
1620 //*************************************************************************************************
1621 
1622 
1623 //*************************************************************************************************
1635 template< typename MT // Type of the dense matrix
1636  , bool SF > // Symmetry flag
1637 template< typename VT > // Type of the right-hand side dense vector
1638 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1639  Column<MT,true,true,SF>::assign( const DenseVector<VT,false>& rhs )
1640 {
1642 
1643  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1644 
1645  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1646 
1647  const size_t rows( size() );
1648 
1649  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1650  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1651 
1652  size_t i( 0UL );
1653  Iterator left( begin() );
1654  ConstIterator_<VT> right( (~rhs).begin() );
1655 
1656  if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
1657  {
1658  for( ; i<ipos; i+=SIMDSIZE ) {
1659  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1660  }
1661  for( ; remainder && i<rows; ++i ) {
1662  *left = *right; ++left; ++right;
1663  }
1664  }
1665  else
1666  {
1667  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1668  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1669  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1670  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1671  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1672  }
1673  for( ; i<ipos; i+=SIMDSIZE ) {
1674  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1675  }
1676  for( ; remainder && i<rows; ++i ) {
1677  *left = *right; ++left; ++right;
1678  }
1679  }
1680 }
1682 //*************************************************************************************************
1683 
1684 
1685 //*************************************************************************************************
1697 template< typename MT // Type of the dense matrix
1698  , bool SF > // Symmetry flag
1699 template< typename VT > // Type of the right-hand side sparse vector
1700 inline void Column<MT,true,true,SF>::assign( const SparseVector<VT,false>& rhs )
1701 {
1702  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1703 
1704  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1705  matrix_(element->index(),col_) = element->value();
1706 }
1708 //*************************************************************************************************
1709 
1710 
1711 //*************************************************************************************************
1723 template< typename MT // Type of the dense matrix
1724  , bool SF > // Symmetry flag
1725 template< typename VT > // Type of the right-hand side dense vector
1726 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1727  Column<MT,true,true,SF>::addAssign( const DenseVector<VT,false>& rhs )
1728 {
1729  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1730 
1731  const size_t ipos( (~rhs).size() & size_t(-2) );
1732  for( size_t i=0UL; i<ipos; i+=2UL ) {
1733  matrix_(i ,col_) += (~rhs)[i ];
1734  matrix_(i+1UL,col_) += (~rhs)[i+1UL];
1735  }
1736  if( ipos < (~rhs).size() )
1737  matrix_(ipos,col_) += (~rhs)[ipos];
1738 }
1740 //*************************************************************************************************
1741 
1742 
1743 //*************************************************************************************************
1755 template< typename MT // Type of the dense matrix
1756  , bool SF > // Symmetry flag
1757 template< typename VT > // Type of the right-hand side dense vector
1758 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1759  Column<MT,true,true,SF>::addAssign( const DenseVector<VT,false>& rhs )
1760 {
1762 
1763  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1764 
1765  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1766 
1767  const size_t rows( size() );
1768 
1769  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1770  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1771 
1772  size_t i( 0UL );
1773  Iterator left( begin() );
1774  ConstIterator_<VT> right( (~rhs).begin() );
1775 
1776  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1777  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1778  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1779  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1780  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1781  }
1782  for( ; i<ipos; i+=SIMDSIZE ) {
1783  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1784  }
1785  for( ; remainder && i<rows; ++i ) {
1786  *left += *right; ++left; ++right;
1787  }
1788 }
1790 //*************************************************************************************************
1791 
1792 
1793 //*************************************************************************************************
1805 template< typename MT // Type of the dense matrix
1806  , bool SF > // Symmetry flag
1807 template< typename VT > // Type of the right-hand side sparse vector
1808 inline void Column<MT,true,true,SF>::addAssign( const SparseVector<VT,false>& rhs )
1809 {
1810  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1811 
1812  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1813  matrix_(element->index(),col_) += element->value();
1814 }
1816 //*************************************************************************************************
1817 
1818 
1819 //*************************************************************************************************
1831 template< typename MT // Type of the dense matrix
1832  , bool SF > // Symmetry flag
1833 template< typename VT > // Type of the right-hand side dense vector
1834 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1835  Column<MT,true,true,SF>::subAssign( const DenseVector<VT,false>& rhs )
1836 {
1837  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1838 
1839  const size_t ipos( (~rhs).size() & size_t(-2) );
1840  for( size_t i=0UL; i<ipos; i+=2UL ) {
1841  matrix_(i ,col_) -= (~rhs)[i ];
1842  matrix_(i+1UL,col_) -= (~rhs)[i+1UL];
1843  }
1844  if( ipos < (~rhs).size() )
1845  matrix_(ipos,col_) -= (~rhs)[ipos];
1846 }
1848 //*************************************************************************************************
1849 
1850 
1851 //*************************************************************************************************
1863 template< typename MT // Type of the dense matrix
1864  , bool SF > // Symmetry flag
1865 template< typename VT > // Type of the right-hand side dense vector
1866 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1867  Column<MT,true,true,SF>::subAssign( const DenseVector<VT,false>& rhs )
1868 {
1870 
1871  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1872 
1873  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1874 
1875  const size_t rows( size() );
1876 
1877  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1878  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1879 
1880  size_t i( 0UL );
1881  Iterator left( begin() );
1882  ConstIterator_<VT> right( (~rhs).begin() );
1883 
1884  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1885  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1886  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1887  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1888  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1889  }
1890  for( ; i<ipos; i+=SIMDSIZE ) {
1891  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1892  }
1893  for( ; remainder && i<rows; ++i ) {
1894  *left -= *right; ++left; ++right;
1895  }
1896 }
1898 //*************************************************************************************************
1899 
1900 
1901 //*************************************************************************************************
1913 template< typename MT // Type of the dense matrix
1914  , bool SF > // Symmetry flag
1915 template< typename VT > // Type of the right-hand side sparse vector
1916 inline void Column<MT,true,true,SF>::subAssign( const SparseVector<VT,false>& rhs )
1917 {
1918  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1919 
1920  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1921  matrix_(element->index(),col_) -= element->value();
1922 }
1924 //*************************************************************************************************
1925 
1926 
1927 //*************************************************************************************************
1939 template< typename MT // Type of the dense matrix
1940  , bool SF > // Symmetry flag
1941 template< typename VT > // Type of the right-hand side dense vector
1942 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
1943  Column<MT,true,true,SF>::multAssign( const DenseVector<VT,false>& rhs )
1944 {
1945  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1946 
1947  const size_t ipos( (~rhs).size() & size_t(-2) );
1948  for( size_t i=0UL; i<ipos; i+=2UL ) {
1949  matrix_(i ,col_) *= (~rhs)[i ];
1950  matrix_(i+1UL,col_) *= (~rhs)[i+1UL];
1951  }
1952  if( ipos < (~rhs).size() )
1953  matrix_(ipos,col_) *= (~rhs)[ipos];
1954 }
1956 //*************************************************************************************************
1957 
1958 
1959 //*************************************************************************************************
1971 template< typename MT // Type of the dense matrix
1972  , bool SF > // Symmetry flag
1973 template< typename VT > // Type of the right-hand side dense vector
1974 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
1975  Column<MT,true,true,SF>::multAssign( const DenseVector<VT,false>& rhs )
1976 {
1978 
1979  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1980 
1981  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1982 
1983  const size_t rows( size() );
1984 
1985  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1986  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1987 
1988  size_t i( 0UL );
1989  Iterator left( begin() );
1990  ConstIterator_<VT> right( (~rhs).begin() );
1991 
1992  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1993  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1994  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1995  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1996  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1997  }
1998  for( ; i<ipos; i+=SIMDSIZE ) {
1999  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2000  }
2001  for( ; remainder && i<rows; ++i ) {
2002  *left *= *right; ++left, ++right;
2003  }
2004 }
2006 //*************************************************************************************************
2007 
2008 
2009 //*************************************************************************************************
2021 template< typename MT // Type of the dense matrix
2022  , bool SF > // Symmetry flag
2023 template< typename VT > // Type of the right-hand side sparse vector
2024 inline void Column<MT,true,true,SF>::multAssign( const SparseVector<VT,false>& rhs )
2025 {
2026  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2027 
2028  const ResultType tmp( serial( *this ) );
2029 
2030  reset();
2031 
2032  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2033  matrix_(element->index(),col_) = tmp[element->index()] * element->value();
2034 }
2036 //*************************************************************************************************
2037 
2038 
2039 //*************************************************************************************************
2051 template< typename MT // Type of the dense matrix
2052  , bool SF > // Symmetry flag
2053 template< typename VT > // Type of the right-hand side dense vector
2054 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2055  Column<MT,true,true,SF>::divAssign( const DenseVector<VT,false>& rhs )
2056 {
2057  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2058 
2059  const size_t ipos( (~rhs).size() & size_t(-2) );
2060  for( size_t i=0UL; i<ipos; i+=2UL ) {
2061  matrix_(i ,col_) /= (~rhs)[i ];
2062  matrix_(i+1UL,col_) /= (~rhs)[i+1UL];
2063  }
2064  if( ipos < (~rhs).size() )
2065  matrix_(ipos,col_) /= (~rhs)[ipos];
2066 }
2068 //*************************************************************************************************
2069 
2070 
2071 //*************************************************************************************************
2083 template< typename MT // Type of the dense matrix
2084  , bool SF > // Symmetry flag
2085 template< typename VT > // Type of the right-hand side dense vector
2086 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2087  Column<MT,true,true,SF>::divAssign( const DenseVector<VT,false>& rhs )
2088 {
2090 
2091  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2092 
2093  const size_t rows( size() );
2094 
2095  const size_t ipos( rows & size_t(-SIMDSIZE) );
2096  BLAZE_INTERNAL_ASSERT( ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2097 
2098  size_t i( 0UL );
2099  Iterator left( begin() );
2100  ConstIterator_<VT> right( (~rhs).begin() );
2101 
2102  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2103  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2104  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2105  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2106  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2107  }
2108  for( ; i<ipos; i+=SIMDSIZE ) {
2109  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2110  }
2111  for( ; i<rows; ++i ) {
2112  *left /= *right; ++left; ++right;
2113  }
2114 }
2116 //*************************************************************************************************
2117 
2118 
2119 
2120 
2121 
2122 
2123 
2124 
2125 //=================================================================================================
2126 //
2127 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
2128 //
2129 //=================================================================================================
2130 
2131 //*************************************************************************************************
2139 template< typename MT > // Type of the dense matrix
2140 class Column<MT,false,true,false>
2141  : public DenseVector< Column<MT,false,true,false>, false >
2142  , private View
2143 {
2144  private:
2145  //**Type definitions****************************************************************************
2147  typedef If_< IsExpression<MT>, MT, MT& > Operand;
2148  //**********************************************************************************************
2149 
2150  public:
2151  //**Type definitions****************************************************************************
2152  typedef Column<MT,false,true,false> This;
2153  typedef DenseVector<This,false> BaseType;
2154  typedef ColumnTrait_<MT> ResultType;
2155  typedef TransposeType_<ResultType> TransposeType;
2156  typedef ElementType_<MT> ElementType;
2157  typedef ReturnType_<MT> ReturnType;
2158  typedef const Column& CompositeType;
2159 
2161  typedef ConstReference_<MT> ConstReference;
2162 
2164  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
2165 
2167  typedef const ElementType* ConstPointer;
2168 
2170  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
2171  //**********************************************************************************************
2172 
2173  //**ColumnIterator class definition*************************************************************
2176  template< typename MatrixType > // Type of the dense matrix
2177  class ColumnIterator
2178  {
2179  public:
2180  //**Type definitions*************************************************************************
2182  typedef If_< IsConst<MatrixType>, ConstReference_<MatrixType>, Reference_<MatrixType> > Reference;
2183 
2184  typedef std::random_access_iterator_tag IteratorCategory;
2185  typedef RemoveReference_<Reference> ValueType;
2186  typedef ValueType* PointerType;
2187  typedef Reference ReferenceType;
2188  typedef ptrdiff_t DifferenceType;
2189 
2190  // STL iterator requirements
2191  typedef IteratorCategory iterator_category;
2192  typedef ValueType value_type;
2193  typedef PointerType pointer;
2194  typedef ReferenceType reference;
2195  typedef DifferenceType difference_type;
2196  //*******************************************************************************************
2197 
2198  //**Constructor******************************************************************************
2201  inline ColumnIterator() noexcept
2202  : matrix_( nullptr ) // The dense matrix containing the column.
2203  , row_ ( 0UL ) // The current row index.
2204  , column_( 0UL ) // The current column index.
2205  {}
2206  //*******************************************************************************************
2207 
2208  //**Constructor******************************************************************************
2215  inline ColumnIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2216  : matrix_( &matrix ) // The dense matrix containing the column.
2217  , row_ ( row ) // The current row index.
2218  , column_( column ) // The current column index.
2219  {}
2220  //*******************************************************************************************
2221 
2222  //**Constructor******************************************************************************
2227  template< typename MatrixType2 >
2228  inline ColumnIterator( const ColumnIterator<MatrixType2>& it ) noexcept
2229  : matrix_( it.matrix_ ) // The dense matrix containing the column.
2230  , row_ ( it.row_ ) // The current row index.
2231  , column_( it.column_ ) // The current column index.
2232  {}
2233  //*******************************************************************************************
2234 
2235  //**Addition assignment operator*************************************************************
2241  inline ColumnIterator& operator+=( size_t inc ) noexcept {
2242  row_ += inc;
2243  return *this;
2244  }
2245  //*******************************************************************************************
2246 
2247  //**Subtraction assignment operator**********************************************************
2253  inline ColumnIterator& operator-=( size_t dec ) noexcept {
2254  row_ -= dec;
2255  return *this;
2256  }
2257  //*******************************************************************************************
2258 
2259  //**Prefix increment operator****************************************************************
2264  inline ColumnIterator& operator++() noexcept {
2265  ++row_;
2266  return *this;
2267  }
2268  //*******************************************************************************************
2269 
2270  //**Postfix increment operator***************************************************************
2275  inline const ColumnIterator operator++( int ) noexcept {
2276  const ColumnIterator tmp( *this );
2277  ++(*this);
2278  return tmp;
2279  }
2280  //*******************************************************************************************
2281 
2282  //**Prefix decrement operator****************************************************************
2287  inline ColumnIterator& operator--() noexcept {
2288  --row_;
2289  return *this;
2290  }
2291  //*******************************************************************************************
2292 
2293  //**Postfix decrement operator***************************************************************
2298  inline const ColumnIterator operator--( int ) noexcept {
2299  const ColumnIterator tmp( *this );
2300  --(*this);
2301  return tmp;
2302  }
2303  //*******************************************************************************************
2304 
2305  //**Subscript operator***********************************************************************
2311  inline ReferenceType operator[]( size_t index ) const {
2312  return (*matrix_)(row_+index,column_);
2313  }
2314  //*******************************************************************************************
2315 
2316  //**Element access operator******************************************************************
2321  inline ReferenceType operator*() const {
2322  return (*matrix_)(row_,column_);
2323  }
2324  //*******************************************************************************************
2325 
2326  //**Element access operator******************************************************************
2331  inline PointerType operator->() const {
2332  return &(*matrix_)(row_,column_);
2333  }
2334  //*******************************************************************************************
2335 
2336  //**Equality operator************************************************************************
2342  template< typename MatrixType2 >
2343  inline bool operator==( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2344  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
2345  }
2346  //*******************************************************************************************
2347 
2348  //**Inequality operator**********************************************************************
2354  template< typename MatrixType2 >
2355  inline bool operator!=( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2356  return !( *this == rhs );
2357  }
2358  //*******************************************************************************************
2359 
2360  //**Less-than operator***********************************************************************
2366  template< typename MatrixType2 >
2367  inline bool operator<( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2368  return ( matrix_ == rhs.matrix_ ) && ( row_ < rhs.row_ ) && ( column_ == rhs.column_ );
2369  }
2370  //*******************************************************************************************
2371 
2372  //**Greater-than operator********************************************************************
2378  template< typename MatrixType2 >
2379  inline bool operator>( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2380  return ( matrix_ == rhs.matrix_ ) && ( row_ > rhs.row_ ) && ( column_ == rhs.column_ );
2381  }
2382  //*******************************************************************************************
2383 
2384  //**Less-or-equal-than operator**************************************************************
2390  template< typename MatrixType2 >
2391  inline bool operator<=( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2392  return ( matrix_ == rhs.matrix_ ) && ( row_ <= rhs.row_ ) && ( column_ == rhs.column_ );
2393  }
2394  //*******************************************************************************************
2395 
2396  //**Greater-or-equal-than operator***********************************************************
2402  template< typename MatrixType2 >
2403  inline bool operator>=( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2404  return ( matrix_ == rhs.matrix_ ) && ( row_ >= rhs.row_ ) && ( column_ == rhs.column_ );
2405  }
2406  //*******************************************************************************************
2407 
2408  //**Subtraction operator*********************************************************************
2414  inline DifferenceType operator-( const ColumnIterator& rhs ) const noexcept {
2415  return row_ - rhs.row_;
2416  }
2417  //*******************************************************************************************
2418 
2419  //**Addition operator************************************************************************
2426  friend inline const ColumnIterator operator+( const ColumnIterator& it, size_t inc ) noexcept {
2427  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2428  }
2429  //*******************************************************************************************
2430 
2431  //**Addition operator************************************************************************
2438  friend inline const ColumnIterator operator+( size_t inc, const ColumnIterator& it ) noexcept {
2439  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2440  }
2441  //*******************************************************************************************
2442 
2443  //**Subtraction operator*********************************************************************
2450  friend inline const ColumnIterator operator-( const ColumnIterator& it, size_t dec ) noexcept {
2451  return ColumnIterator( *it.matrix_, it.row_-dec, it.column_ );
2452  }
2453  //*******************************************************************************************
2454 
2455  private:
2456  //**Member variables*************************************************************************
2457  MatrixType* matrix_;
2458  size_t row_;
2459  size_t column_;
2460  //*******************************************************************************************
2461 
2462  //**Friend declarations**********************************************************************
2463  template< typename MatrixType2 > friend class ColumnIterator;
2464  //*******************************************************************************************
2465  };
2466  //**********************************************************************************************
2467 
2468  //**Type definitions****************************************************************************
2470  typedef ColumnIterator<const MT> ConstIterator;
2471 
2473  typedef If_< IsConst<MT>, ConstIterator, ColumnIterator<MT> > Iterator;
2474  //**********************************************************************************************
2475 
2476  //**Compilation flags***************************************************************************
2478  enum : bool { simdEnabled = false };
2479 
2481  enum : bool { smpAssignable = MT::smpAssignable };
2482  //**********************************************************************************************
2483 
2484  //**Constructors********************************************************************************
2487  explicit inline Column( Operand matrix, size_t index );
2488  // No explicitly declared copy constructor.
2490  //**********************************************************************************************
2491 
2492  //**Destructor**********************************************************************************
2493  // No explicitly declared destructor.
2494  //**********************************************************************************************
2495 
2496  //**Data access functions***********************************************************************
2499  inline Reference operator[]( size_t index );
2500  inline ConstReference operator[]( size_t index ) const;
2501  inline Reference at( size_t index );
2502  inline ConstReference at( size_t index ) const;
2503  inline Pointer data () noexcept;
2504  inline ConstPointer data () const noexcept;
2505  inline Iterator begin ();
2506  inline ConstIterator begin () const;
2507  inline ConstIterator cbegin() const;
2508  inline Iterator end ();
2509  inline ConstIterator end () const;
2510  inline ConstIterator cend () const;
2512  //**********************************************************************************************
2513 
2514  //**Assignment operators************************************************************************
2517  inline Column& operator=( const ElementType& rhs );
2518  inline Column& operator=( initializer_list<ElementType> list );
2519  inline Column& operator=( const Column& rhs );
2520 
2521  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
2522  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
2523  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
2524  template< typename VT > inline Column& operator*=( const DenseVector<VT,false>& rhs );
2525  template< typename VT > inline Column& operator*=( const SparseVector<VT,false>& rhs );
2526  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
2527 
2528  template< typename Other >
2529  inline EnableIf_< IsNumeric<Other>, Column >& operator*=( Other rhs );
2530 
2531  template< typename Other >
2532  inline EnableIf_< IsNumeric<Other>, Column >& operator/=( Other rhs );
2534  //**********************************************************************************************
2535 
2536  //**Utility functions***************************************************************************
2539  inline size_t size() const noexcept;
2540  inline size_t capacity() const noexcept;
2541  inline size_t nonZeros() const;
2542  inline void reset();
2544  //**********************************************************************************************
2545 
2546  //**Numeric functions***************************************************************************
2549  template< typename Other > inline Column& scale( const Other& scalar );
2551  //**********************************************************************************************
2552 
2553  public:
2554  //**Expression template evaluation functions****************************************************
2557  template< typename Other >
2558  inline bool canAlias ( const Other* alias ) const noexcept;
2559 
2560  template< typename MT2, bool SO2, bool SF2 >
2561  inline bool canAlias ( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
2562 
2563  template< typename Other >
2564  inline bool isAliased( const Other* alias ) const noexcept;
2565 
2566  template< typename MT2, bool SO2, bool SF2 >
2567  inline bool isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
2568 
2569  inline bool isAligned () const noexcept;
2570  inline bool canSMPAssign() const noexcept;
2571 
2572  template< typename VT > inline void assign ( const DenseVector <VT,false>& rhs );
2573  template< typename VT > inline void assign ( const SparseVector<VT,false>& rhs );
2574  template< typename VT > inline void addAssign ( const DenseVector <VT,false>& rhs );
2575  template< typename VT > inline void addAssign ( const SparseVector<VT,false>& rhs );
2576  template< typename VT > inline void subAssign ( const DenseVector <VT,false>& rhs );
2577  template< typename VT > inline void subAssign ( const SparseVector<VT,false>& rhs );
2578  template< typename VT > inline void multAssign( const DenseVector <VT,false>& rhs );
2579  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
2580  template< typename VT > inline void divAssign ( const DenseVector <VT,false>& rhs );
2582  //**********************************************************************************************
2583 
2584  private:
2585  //**Member variables****************************************************************************
2588  Operand matrix_;
2589  const size_t col_;
2590 
2591  //**********************************************************************************************
2592 
2593  //**Friend declarations*************************************************************************
2594  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Column;
2595 
2596  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2597  friend bool isIntact( const Column<MT2,SO2,DF2,SF2>& column ) noexcept;
2598 
2599  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2600  friend bool isSame( const Column<MT2,SO2,DF2,SF2>& a, const Column<MT2,SO2,DF2,SF2>& b ) noexcept;
2601 
2602  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2603  friend bool tryAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2604 
2605  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2606  friend bool tryAddAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2607 
2608  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2609  friend bool trySubAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2610 
2611  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2612  friend bool tryMultAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2613 
2614  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2615  friend bool tryDivAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2616 
2617  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2618  friend DerestrictTrait_< Column<MT2,SO2,DF2,SF2> > derestrict( Column<MT2,SO2,DF2,SF2>& column );
2619  //**********************************************************************************************
2620 
2621  //**Compile time checks*************************************************************************
2629  //**********************************************************************************************
2630 };
2632 //*************************************************************************************************
2633 
2634 
2635 
2636 
2637 //=================================================================================================
2638 //
2639 // CONSTRUCTOR
2640 //
2641 //=================================================================================================
2642 
2643 //*************************************************************************************************
2651 template< typename MT > // Type of the dense matrix
2652 inline Column<MT,false,true,false>::Column( Operand matrix, size_t index )
2653  : matrix_( matrix ) // The dense matrix containing the column
2654  , col_ ( index ) // The index of the column in the matrix
2655 {
2656  if( matrix_.columns() <= index ) {
2657  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2658  }
2659 }
2661 //*************************************************************************************************
2662 
2663 
2664 
2665 
2666 //=================================================================================================
2667 //
2668 // DATA ACCESS FUNCTIONS
2669 //
2670 //=================================================================================================
2671 
2672 //*************************************************************************************************
2682 template< typename MT > // Type of the dense matrix
2684  Column<MT,false,true,false>::operator[]( size_t index )
2685 {
2686  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2687  return matrix_(index,col_);
2688 }
2690 //*************************************************************************************************
2691 
2692 
2693 //*************************************************************************************************
2703 template< typename MT > // Type of the dense matrix
2705  Column<MT,false,true,false>::operator[]( size_t index ) const
2706 {
2707  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2708  return const_cast<const MT&>( matrix_ )(index,col_);
2709 }
2711 //*************************************************************************************************
2712 
2713 
2714 //*************************************************************************************************
2725 template< typename MT > // Type of the dense matrix
2727  Column<MT,false,true,false>::at( size_t index )
2728 {
2729  if( index >= size() ) {
2730  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2731  }
2732  return (*this)[index];
2733 }
2735 //*************************************************************************************************
2736 
2737 
2738 //*************************************************************************************************
2749 template< typename MT > // Type of the dense matrix
2751  Column<MT,false,true,false>::at( size_t index ) const
2752 {
2753  if( index >= size() ) {
2754  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2755  }
2756  return (*this)[index];
2757 }
2759 //*************************************************************************************************
2760 
2761 
2762 //*************************************************************************************************
2771 template< typename MT > // Type of the dense matrix
2772 inline typename Column<MT,false,true,false>::Pointer Column<MT,false,true,false>::data() noexcept
2773 {
2774  return matrix_.data() + col_;
2775 }
2777 //*************************************************************************************************
2778 
2779 
2780 //*************************************************************************************************
2789 template< typename MT > // Type of the dense matrix
2790 inline typename Column<MT,false,true,false>::ConstPointer Column<MT,false,true,false>::data() const noexcept
2791 {
2792  return matrix_.data() + col_;
2793 }
2795 //*************************************************************************************************
2796 
2797 
2798 //*************************************************************************************************
2806 template< typename MT > // Type of the dense matrix
2808 {
2809  return Iterator( matrix_, 0UL, col_ );
2810 }
2812 //*************************************************************************************************
2813 
2814 
2815 //*************************************************************************************************
2823 template< typename MT > // Type of the dense matrix
2826 {
2827  return ConstIterator( matrix_, 0UL, col_ );
2828 }
2830 //*************************************************************************************************
2831 
2832 
2833 //*************************************************************************************************
2841 template< typename MT > // Type of the dense matrix
2844 {
2845  return ConstIterator( matrix_, 0UL, col_ );
2846 }
2848 //*************************************************************************************************
2849 
2850 
2851 //*************************************************************************************************
2859 template< typename MT > // Type of the dense matrix
2861 {
2862  return Iterator( matrix_, size(), col_ );
2863 }
2865 //*************************************************************************************************
2866 
2867 
2868 //*************************************************************************************************
2876 template< typename MT > // Type of the dense matrix
2879 {
2880  return ConstIterator( matrix_, size(), col_ );
2881 }
2883 //*************************************************************************************************
2884 
2885 
2886 //*************************************************************************************************
2894 template< typename MT > // Type of the dense matrix
2897 {
2898  return ConstIterator( matrix_, size(), col_ );
2899 }
2901 //*************************************************************************************************
2902 
2903 
2904 
2905 
2906 //=================================================================================================
2907 //
2908 // ASSIGNMENT OPERATORS
2909 //
2910 //=================================================================================================
2911 
2912 //*************************************************************************************************
2923 template< typename MT > // Type of the dense matrix
2924 inline Column<MT,false,true,false>&
2925  Column<MT,false,true,false>::operator=( const ElementType& rhs )
2926 {
2927  const size_t ibegin( ( IsLower<MT>::value )
2928  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
2929  ?( col_+1UL )
2930  :( col_ ) )
2931  :( 0UL ) );
2932  const size_t iend ( ( IsUpper<MT>::value )
2933  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
2934  ?( col_ )
2935  :( col_+1UL ) )
2936  :( size() ) );
2937 
2938  for( size_t i=ibegin; i<iend; ++i )
2939  matrix_(i,col_) = rhs;
2940 
2941  return *this;
2942 }
2944 //*************************************************************************************************
2945 
2946 
2947 //*************************************************************************************************
2960 template< typename MT > // Type of the dense matrix
2961 inline Column<MT,false,true,false>&
2962  Column<MT,false,true,false>::operator=( initializer_list<ElementType> list )
2963 {
2964  if( list.size() > size() ) {
2965  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
2966  }
2967 
2968  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
2969 
2970  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2971 
2972  return *this;
2973 }
2975 //*************************************************************************************************
2976 
2977 
2978 //*************************************************************************************************
2992 template< typename MT > // Type of the dense matrix
2993 inline Column<MT,false,true,false>&
2994  Column<MT,false,true,false>::operator=( const Column& rhs )
2995 {
2996  if( &rhs == this ) return *this;
2997 
2998  if( size() != rhs.size() ) {
2999  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
3000  }
3001 
3002  if( !tryAssign( matrix_, rhs, 0UL, col_ ) ) {
3003  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3004  }
3005 
3006  DerestrictTrait_<This> left( derestrict( *this ) );
3007 
3008  smpAssign( left, rhs );
3009 
3010  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3011 
3012  return *this;
3013 }
3015 //*************************************************************************************************
3016 
3017 
3018 //*************************************************************************************************
3032 template< typename MT > // Type of the dense matrix
3033 template< typename VT > // Type of the right-hand side vector
3034 inline Column<MT,false,true,false>&
3035  Column<MT,false,true,false>::operator=( const Vector<VT,false>& rhs )
3036 {
3040 
3041  if( size() != (~rhs).size() ) {
3042  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3043  }
3044 
3045  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3046  Right right( ~rhs );
3047 
3048  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
3049  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3050  }
3051 
3052  DerestrictTrait_<This> left( derestrict( *this ) );
3053 
3054  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3055  const ResultType tmp( right );
3056  smpAssign( left, tmp );
3057  }
3058  else {
3059  if( IsSparseVector<VT>::value )
3060  reset();
3061  smpAssign( left, right );
3062  }
3063 
3064  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3065 
3066  return *this;
3067 }
3069 //*************************************************************************************************
3070 
3071 
3072 //*************************************************************************************************
3086 template< typename MT > // Type of the dense matrix
3087 template< typename VT > // Type of the right-hand side vector
3088 inline Column<MT,false,true,false>&
3089  Column<MT,false,true,false>::operator+=( const Vector<VT,false>& rhs )
3090 {
3091  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3093 
3094  if( size() != (~rhs).size() ) {
3095  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3096  }
3097 
3098  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3099  Right right( ~rhs );
3100 
3101  if( !tryAddAssign( matrix_, right, 0UL, col_ ) ) {
3102  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3103  }
3104 
3105  DerestrictTrait_<This> left( derestrict( *this ) );
3106 
3107  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3108  const ResultType_<VT> tmp( right );
3109  smpAddAssign( left, tmp );
3110  }
3111  else {
3112  smpAddAssign( left, right );
3113  }
3114 
3115  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3116 
3117  return *this;
3118 }
3120 //*************************************************************************************************
3121 
3122 
3123 //*************************************************************************************************
3137 template< typename MT > // Type of the dense matrix
3138 template< typename VT > // Type of the right-hand side vector
3139 inline Column<MT,false,true,false>&
3140  Column<MT,false,true,false>::operator-=( const Vector<VT,false>& rhs )
3141 {
3142  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3144 
3145  if( size() != (~rhs).size() ) {
3146  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3147  }
3148 
3149  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3150  Right right( ~rhs );
3151 
3152  if( !trySubAssign( matrix_, right, 0UL, col_ ) ) {
3153  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3154  }
3155 
3156  DerestrictTrait_<This> left( derestrict( *this ) );
3157 
3158  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3159  const ResultType_<VT> tmp( right );
3160  smpSubAssign( left, tmp );
3161  }
3162  else {
3163  smpSubAssign( left, right );
3164  }
3165 
3166  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3167 
3168  return *this;
3169 }
3171 //*************************************************************************************************
3172 
3173 
3174 //*************************************************************************************************
3187 template< typename MT > // Type of the dense matrix
3188 template< typename VT > // Type of the right-hand side dense vector
3189 inline Column<MT,false,true,false>&
3190  Column<MT,false,true,false>::operator*=( const DenseVector<VT,false>& rhs )
3191 {
3192  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3194 
3195  if( size() != (~rhs).size() ) {
3196  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3197  }
3198 
3199  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3200  Right right( ~rhs );
3201 
3202  if( !tryMultAssign( matrix_, right, 0UL, col_ ) ) {
3203  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3204  }
3205 
3206  DerestrictTrait_<This> left( derestrict( *this ) );
3207 
3208  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3209  const ResultType_<VT> tmp( right );
3210  smpMultAssign( left, tmp );
3211  }
3212  else {
3213  smpMultAssign( left, right );
3214  }
3215 
3216  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3217 
3218  return *this;
3219 }
3221 //*************************************************************************************************
3222 
3223 
3224 //*************************************************************************************************
3237 template< typename MT > // Type of the dense matrix
3238 template< typename VT > // Type of the right-hand side sparse vector
3239 inline Column<MT,false,true,false>&
3240  Column<MT,false,true,false>::operator*=( const SparseVector<VT,false>& rhs )
3241 {
3245 
3246  if( size() != (~rhs).size() ) {
3247  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3248  }
3249 
3250  const ResultType right( *this * (~rhs) );
3251 
3252  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
3253  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3254  }
3255 
3256  DerestrictTrait_<This> left( derestrict( *this ) );
3257 
3258  smpAssign( left, right );
3259 
3260  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3261 
3262  return *this;
3263 }
3265 //*************************************************************************************************
3266 
3267 
3268 //*************************************************************************************************
3280 template< typename MT > // Type of the dense matrix
3281 template< typename VT > // Type of the right-hand side dense vector
3282 inline Column<MT,false,true,false>&
3283  Column<MT,false,true,false>::operator/=( const DenseVector<VT,false>& rhs )
3284 {
3285  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3287 
3288  if( size() != (~rhs).size() ) {
3289  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3290  }
3291 
3292  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3293  Right right( ~rhs );
3294 
3295  if( !tryDivAssign( matrix_, right, 0UL, col_ ) ) {
3296  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3297  }
3298 
3299  DerestrictTrait_<This> left( derestrict( *this ) );
3300 
3301  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3302  const ResultType_<VT> tmp( right );
3303  smpDivAssign( left, tmp );
3304  }
3305  else {
3306  smpDivAssign( left, right );
3307  }
3308 
3309  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3310 
3311  return *this;
3312 }
3314 //*************************************************************************************************
3315 
3316 
3317 //*************************************************************************************************
3328 template< typename MT > // Type of the dense matrix
3329 template< typename Other > // Data type of the right-hand side scalar
3330 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,false> >&
3332 {
3334 
3335  return operator=( (*this) * rhs );
3336 }
3338 //*************************************************************************************************
3339 
3340 
3341 //*************************************************************************************************
3354 template< typename MT > // Type of the dense matrix
3355 template< typename Other > // Data type of the right-hand side scalar
3356 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,false> >&
3358 {
3360 
3361  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3362 
3363  return operator=( (*this) / rhs );
3364 }
3366 //*************************************************************************************************
3367 
3368 
3369 
3370 
3371 //=================================================================================================
3372 //
3373 // UTILITY FUNCTIONS
3374 //
3375 //=================================================================================================
3376 
3377 //*************************************************************************************************
3383 template< typename MT > // Type of the dense matrix
3384 inline size_t Column<MT,false,true,false>::size() const noexcept
3385 {
3386  return matrix_.rows();
3387 }
3389 //*************************************************************************************************
3390 
3391 
3392 //*************************************************************************************************
3398 template< typename MT > // Type of the dense matrix
3399 inline size_t Column<MT,false,true,false>::capacity() const noexcept
3400 {
3401  return matrix_.rows();
3402 }
3404 //*************************************************************************************************
3405 
3406 
3407 //*************************************************************************************************
3416 template< typename MT > // Type of the dense matrix
3417 inline size_t Column<MT,false,true,false>::nonZeros() const
3418 {
3419  const size_t rows( size() );
3420  size_t nonzeros( 0UL );
3421 
3422  for( size_t i=0UL; i<rows; ++i )
3423  if( !isDefault( matrix_(i,col_) ) )
3424  ++nonzeros;
3425 
3426  return nonzeros;
3427 }
3429 //*************************************************************************************************
3430 
3431 
3432 //*************************************************************************************************
3438 template< typename MT > // Type of the dense matrix
3440 {
3441  using blaze::clear;
3442 
3443  const size_t ibegin( ( IsLower<MT>::value )
3444  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3445  ?( col_+1UL )
3446  :( col_ ) )
3447  :( 0UL ) );
3448  const size_t iend ( ( IsUpper<MT>::value )
3449  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3450  ?( col_ )
3451  :( col_+1UL ) )
3452  :( size() ) );
3453 
3454  for( size_t i=ibegin; i<iend; ++i )
3455  clear( matrix_(i,col_) );
3456 }
3458 //*************************************************************************************************
3459 
3460 
3461 
3462 
3463 //=================================================================================================
3464 //
3465 // NUMERIC FUNCTIONS
3466 //
3467 //=================================================================================================
3468 
3469 //*************************************************************************************************
3480 template< typename MT > // Type of the dense matrix
3481 template< typename Other > // Data type of the scalar value
3482 inline Column<MT,false,true,false>& Column<MT,false,true,false>::scale( const Other& scalar )
3483 {
3485 
3486  const size_t ibegin( ( IsLower<MT>::value )
3487  ?( ( IsStrictlyLower<MT>::value )
3488  ?( col_+1UL )
3489  :( col_ ) )
3490  :( 0UL ) );
3491  const size_t iend ( ( IsUpper<MT>::value )
3492  ?( ( IsStrictlyUpper<MT>::value )
3493  ?( col_ )
3494  :( col_+1UL ) )
3495  :( size() ) );
3496 
3497  for( size_t i=ibegin; i<iend; ++i ) {
3498  matrix_(i,col_) *= scalar;
3499  }
3500 
3501  return *this;
3502 }
3504 //*************************************************************************************************
3505 
3506 
3507 
3508 
3509 //=================================================================================================
3510 //
3511 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3512 //
3513 //=================================================================================================
3514 
3515 //*************************************************************************************************
3526 template< typename MT > // Type of the dense matrix
3527 template< typename Other > // Data type of the foreign expression
3528 inline bool Column<MT,false,true,false>::canAlias( const Other* alias ) const noexcept
3529 {
3530  return matrix_.isAliased( alias );
3531 }
3533 //*************************************************************************************************
3534 
3535 
3536 //*************************************************************************************************
3547 template< typename MT > // Type of the dense matrix
3548 template< typename MT2 // Data type of the foreign dense column
3549  , bool SO2 // Storage order of the foreign dense column
3550  , bool SF2 > // Symmetry flag of the foreign dense column
3551 inline bool Column<MT,false,true,false>::canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
3552 {
3553  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
3554 }
3556 //*************************************************************************************************
3557 
3558 
3559 //*************************************************************************************************
3570 template< typename MT > // Type of the dense matrix
3571 template< typename Other > // Data type of the foreign expression
3572 inline bool Column<MT,false,true,false>::isAliased( const Other* alias ) const noexcept
3573 {
3574  return matrix_.isAliased( alias );
3575 }
3577 //*************************************************************************************************
3578 
3579 
3580 //*************************************************************************************************
3591 template< typename MT > // Type of the dense matrix
3592 template< typename MT2 // Data type of the foreign dense column
3593  , bool SO2 // Storage order of the foreign dense column
3594  , bool SF2 > // Symmetry flag of the foreign dense column
3595 inline bool Column<MT,false,true,false>::isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
3596 {
3597  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
3598 }
3600 //*************************************************************************************************
3601 
3602 
3603 //*************************************************************************************************
3613 template< typename MT > // Type of the dense matrix
3614 inline bool Column<MT,false,true,false>::isAligned() const noexcept
3615 {
3616  return false;
3617 }
3619 //*************************************************************************************************
3620 
3621 
3622 //*************************************************************************************************
3633 template< typename MT > // Type of the dense matrix
3634 inline bool Column<MT,false,true,false>::canSMPAssign() const noexcept
3635 {
3636  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3637 }
3639 //*************************************************************************************************
3640 
3641 
3642 //*************************************************************************************************
3654 template< typename MT > // Type of the dense matrix
3655 template< typename VT > // Type of the right-hand side dense vector
3656 inline void Column<MT,false,true,false>::assign( const DenseVector<VT,false>& rhs )
3657 {
3658  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3659 
3660  const size_t ipos( (~rhs).size() & size_t(-2) );
3661  for( size_t i=0UL; i<ipos; i+=2UL ) {
3662  matrix_(i ,col_) = (~rhs)[i ];
3663  matrix_(i+1UL,col_) = (~rhs)[i+1UL];
3664  }
3665  if( ipos < (~rhs).size() )
3666  matrix_(ipos,col_) = (~rhs)[ipos];
3667 }
3669 //*************************************************************************************************
3670 
3671 
3672 //*************************************************************************************************
3684 template< typename MT > // Type of the dense matrix
3685 template< typename VT > // Type of the right-hand side sparse vector
3686 inline void Column<MT,false,true,false>::assign( const SparseVector<VT,false>& rhs )
3687 {
3688  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3689 
3690  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3691  matrix_(element->index(),col_) = element->value();
3692 }
3694 //*************************************************************************************************
3695 
3696 
3697 //*************************************************************************************************
3709 template< typename MT > // Type of the dense matrix
3710 template< typename VT > // Type of the right-hand side dense vector
3711 inline void Column<MT,false,true,false>::addAssign( const DenseVector<VT,false>& rhs )
3712 {
3713  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3714 
3715  const size_t ipos( (~rhs).size() & size_t(-2) );
3716  for( size_t i=0UL; i<ipos; i+=2UL ) {
3717  matrix_(i ,col_) += (~rhs)[i ];
3718  matrix_(i+1UL,col_) += (~rhs)[i+1UL];
3719  }
3720  if( ipos < (~rhs).size() )
3721  matrix_(ipos,col_) += (~rhs)[ipos];
3722 }
3724 //*************************************************************************************************
3725 
3726 
3727 //*************************************************************************************************
3739 template< typename MT > // Type of the dense matrix
3740 template< typename VT > // Type of the right-hand side sparse vector
3741 inline void Column<MT,false,true,false>::addAssign( const SparseVector<VT,false>& rhs )
3742 {
3743  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3744 
3745  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3746  matrix_(element->index(),col_) += element->value();
3747 }
3749 //*************************************************************************************************
3750 
3751 
3752 //*************************************************************************************************
3764 template< typename MT > // Type of the dense matrix
3765 template< typename VT > // Type of the right-hand side dense vector
3766 inline void Column<MT,false,true,false>::subAssign( const DenseVector<VT,false>& rhs )
3767 {
3768  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3769 
3770  const size_t ipos( (~rhs).size() & size_t(-2) );
3771  for( size_t i=0UL; i<ipos; i+=2UL ) {
3772  matrix_(i ,col_) -= (~rhs)[i ];
3773  matrix_(i+1UL,col_) -= (~rhs)[i+1UL];
3774  }
3775  if( ipos < (~rhs).size() )
3776  matrix_(ipos,col_) -= (~rhs)[ipos];
3777 }
3779 //*************************************************************************************************
3780 
3781 
3782 //*************************************************************************************************
3794 template< typename MT > // Type of the dense matrix
3795 template< typename VT > // Type of the right-hand side sparse vector
3796 inline void Column<MT,false,true,false>::subAssign( const SparseVector<VT,false>& rhs )
3797 {
3798  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3799 
3800  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3801  matrix_(element->index(),col_) -= element->value();
3802 }
3804 //*************************************************************************************************
3805 
3806 
3807 //*************************************************************************************************
3819 template< typename MT > // Type of the dense matrix
3820 template< typename VT > // Type of the right-hand side dense vector
3821 inline void Column<MT,false,true,false>::multAssign( const DenseVector<VT,false>& rhs )
3822 {
3823  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3824 
3825  const size_t ipos( (~rhs).size() & size_t(-2) );
3826  for( size_t i=0UL; i<ipos; i+=2UL ) {
3827  matrix_(i ,col_) *= (~rhs)[i ];
3828  matrix_(i+1UL,col_) *= (~rhs)[i+1UL];
3829  }
3830  if( ipos < (~rhs).size() )
3831  matrix_(ipos,col_) *= (~rhs)[ipos];
3832 }
3834 //*************************************************************************************************
3835 
3836 
3837 //*************************************************************************************************
3849 template< typename MT > // Type of the dense matrix
3850 template< typename VT > // Type of the right-hand side sparse vector
3851 inline void Column<MT,false,true,false>::multAssign( const SparseVector<VT,false>& rhs )
3852 {
3853  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3854 
3855  const ResultType tmp( serial( *this ) );
3856 
3857  reset();
3858 
3859  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3860  matrix_(element->index(),col_) = tmp[element->index()] * element->value();
3861 }
3863 //*************************************************************************************************
3864 
3865 
3866 //*************************************************************************************************
3878 template< typename MT > // Type of the dense matrix
3879 template< typename VT > // Type of the right-hand side dense vector
3880 inline void Column<MT,false,true,false>::divAssign( const DenseVector<VT,false>& rhs )
3881 {
3882  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3883 
3884  const size_t ipos( (~rhs).size() & size_t(-2) );
3885  for( size_t i=0UL; i<ipos; i+=2UL ) {
3886  matrix_(i ,col_) /= (~rhs)[i ];
3887  matrix_(i+1UL,col_) /= (~rhs)[i+1UL];
3888  }
3889  if( ipos < (~rhs).size() )
3890  matrix_(ipos,col_) /= (~rhs)[ipos];
3891 }
3893 //*************************************************************************************************
3894 
3895 
3896 
3897 
3898 
3899 
3900 
3901 
3902 //=================================================================================================
3903 //
3904 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
3905 //
3906 //=================================================================================================
3907 
3908 //*************************************************************************************************
3916 template< typename MT > // Type of the dense matrix
3917 class Column<MT,false,true,true>
3918  : public DenseVector< Column<MT,false,true,true>, false >
3919  , private View
3920 {
3921  private:
3922  //**Type definitions****************************************************************************
3924  typedef If_< IsExpression<MT>, MT, MT& > Operand;
3925  //**********************************************************************************************
3926 
3927  public:
3928  //**Type definitions****************************************************************************
3929  typedef Column<MT,false,true,true> This;
3930  typedef DenseVector<This,false> BaseType;
3931  typedef ColumnTrait_<MT> ResultType;
3932  typedef TransposeType_<ResultType> TransposeType;
3933  typedef ElementType_<MT> ElementType;
3934  typedef SIMDTrait_<ElementType> SIMDType;
3935  typedef ReturnType_<MT> ReturnType;
3936  typedef const Column& CompositeType;
3937 
3939  typedef ConstReference_<MT> ConstReference;
3940 
3942  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
3943 
3945  typedef const ElementType* ConstPointer;
3946 
3948  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
3949 
3951  typedef ConstIterator_<MT> ConstIterator;
3952 
3954  typedef If_< IsConst<MT>, ConstIterator, Iterator_<MT> > Iterator;
3955  //**********************************************************************************************
3956 
3957  //**Compilation flags***************************************************************************
3959  enum : bool { simdEnabled = MT::simdEnabled };
3960 
3962  enum : bool { smpAssignable = MT::smpAssignable };
3963  //**********************************************************************************************
3964 
3965  //**Constructors********************************************************************************
3968  explicit inline Column( Operand matrix, size_t index );
3969  // No explicitly declared copy constructor.
3971  //**********************************************************************************************
3972 
3973  //**Destructor**********************************************************************************
3974  // No explicitly declared destructor.
3975  //**********************************************************************************************
3976 
3977  //**Data access functions***********************************************************************
3980  inline Reference operator[]( size_t index );
3981  inline ConstReference operator[]( size_t index ) const;
3982  inline Reference at( size_t index );
3983  inline ConstReference at( size_t index ) const;
3984  inline Pointer data () noexcept;
3985  inline ConstPointer data () const noexcept;
3986  inline Iterator begin ();
3987  inline ConstIterator begin () const;
3988  inline ConstIterator cbegin() const;
3989  inline Iterator end ();
3990  inline ConstIterator end () const;
3991  inline ConstIterator cend () const;
3993  //**********************************************************************************************
3994 
3995  //**Assignment operators************************************************************************
3998  inline Column& operator=( const ElementType& rhs );
3999  inline Column& operator=( initializer_list<ElementType> list );
4000  inline Column& operator=( const Column& rhs );
4001 
4002  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
4003  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
4004  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
4005  template< typename VT > inline Column& operator*=( const DenseVector<VT,false>& rhs );
4006  template< typename VT > inline Column& operator*=( const SparseVector<VT,false>& rhs );
4007  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
4008 
4009  template< typename Other >
4010  inline EnableIf_< IsNumeric<Other>, Column >& operator*=( Other rhs );
4011 
4012  template< typename Other >
4013  inline EnableIf_< IsNumeric<Other>, Column >& operator/=( Other rhs );
4015  //**********************************************************************************************
4016 
4017  //**Utility functions***************************************************************************
4020  inline size_t size() const noexcept;
4021  inline size_t capacity() const noexcept;
4022  inline size_t nonZeros() const;
4023  inline void reset();
4025  //**********************************************************************************************
4026 
4027  //**Numeric functions***************************************************************************
4030  template< typename Other > inline Column& scale( const Other& scalar );
4032  //**********************************************************************************************
4033 
4034  private:
4035  //**********************************************************************************************
4037  template< typename VT >
4038  struct VectorizedAssign {
4039  enum : bool { value = useOptimizedKernels &&
4040  simdEnabled && VT::simdEnabled &&
4041  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
4042  };
4043  //**********************************************************************************************
4044 
4045  //**********************************************************************************************
4047  template< typename VT >
4048  struct VectorizedAddAssign {
4049  enum : bool { value = useOptimizedKernels &&
4050  simdEnabled && VT::simdEnabled &&
4051  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4052  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
4053  };
4054  //**********************************************************************************************
4055 
4056  //**********************************************************************************************
4058  template< typename VT >
4059  struct VectorizedSubAssign {
4060  enum : bool { value = useOptimizedKernels &&
4061  simdEnabled && VT::simdEnabled &&
4062  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4063  HasSIMDSub< ElementType, ElementType_<VT> >::value };
4064  };
4065  //**********************************************************************************************
4066 
4067  //**********************************************************************************************
4069  template< typename VT >
4070  struct VectorizedMultAssign {
4071  enum : bool { value = useOptimizedKernels &&
4072  simdEnabled && VT::simdEnabled &&
4073  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4074  HasSIMDMult< ElementType, ElementType_<VT> >::value };
4075  };
4076  //**********************************************************************************************
4077 
4078  //**********************************************************************************************
4080  template< typename VT >
4081  struct VectorizedDivAssign {
4082  enum : bool { value = useOptimizedKernels &&
4083  simdEnabled && VT::simdEnabled &&
4084  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4085  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
4086  };
4087  //**********************************************************************************************
4088 
4089  //**SIMD properties*****************************************************************************
4091  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
4092  //**********************************************************************************************
4093 
4094  public:
4095  //**Expression template evaluation functions****************************************************
4098  template< typename Other >
4099  inline bool canAlias( const Other* alias ) const noexcept;
4100 
4101  template< typename MT2, bool SO2, bool SF2 >
4102  inline bool canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
4103 
4104  template< typename Other >
4105  inline bool isAliased( const Other* alias ) const noexcept;
4106 
4107  template< typename MT2, bool SO2, bool SF2 >
4108  inline bool isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
4109 
4110  inline bool isAligned () const noexcept;
4111  inline bool canSMPAssign() const noexcept;
4112 
4113  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4114  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4115  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4116 
4117  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4118  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4119  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4120  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4121 
4122  template< typename VT >
4123  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
4124 
4125  template< typename VT >
4126  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
4127 
4128  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
4129 
4130  template< typename VT >
4131  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
4132 
4133  template< typename VT >
4134  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
4135 
4136  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
4137 
4138  template< typename VT >
4139  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
4140 
4141  template< typename VT >
4142  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
4143 
4144  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
4145 
4146  template< typename VT >
4147  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
4148 
4149  template< typename VT >
4150  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
4151 
4152  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
4153 
4154  template< typename VT >
4155  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
4156 
4157  template< typename VT >
4158  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
4160  //**********************************************************************************************
4161 
4162  private:
4163  //**Member variables****************************************************************************
4166  Operand matrix_;
4167  const size_t col_;
4168 
4169  //**********************************************************************************************
4170 
4171  //**Friend declarations*************************************************************************
4172  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Column;
4173 
4174  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4175  friend bool isIntact( const Column<MT2,SO2,DF2,SF2>& column ) noexcept;
4176 
4177  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4178  friend bool isSame( const Column<MT2,SO2,DF2,SF2>& a, const Column<MT2,SO2,DF2,SF2>& b ) noexcept;
4179 
4180  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4181  friend bool tryAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4182 
4183  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4184  friend bool tryAddAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4185 
4186  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4187  friend bool trySubAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4188 
4189  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4190  friend bool tryMultAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4191 
4192  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4193  friend bool tryDivAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4194 
4195  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4196  friend DerestrictTrait_< Column<MT2,SO2,DF2,SF2> > derestrict( Column<MT2,SO2,DF2,SF2>& column );
4197  //**********************************************************************************************
4198 
4199  //**Compile time checks*************************************************************************
4207  //**********************************************************************************************
4208 };
4210 //*************************************************************************************************
4211 
4212 
4213 
4214 
4215 //=================================================================================================
4216 //
4217 // CONSTRUCTOR
4218 //
4219 //=================================================================================================
4220 
4221 //*************************************************************************************************
4229 template< typename MT > // Type of the dense matrix
4230 inline Column<MT,false,true,true>::Column( Operand matrix, size_t index )
4231  : matrix_( matrix ) // The dense matrix containing the column
4232  , col_ ( index ) // The index of the column in the matrix
4233 {
4234  if( matrix_.columns() <= index ) {
4235  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
4236  }
4237 }
4239 //*************************************************************************************************
4240 
4241 
4242 
4243 
4244 //=================================================================================================
4245 //
4246 // DATA ACCESS FUNCTIONS
4247 //
4248 //=================================================================================================
4249 
4250 //*************************************************************************************************
4260 template< typename MT > // Type of the dense matrix
4262  Column<MT,false,true,true>::operator[]( size_t index )
4263 {
4264  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4265  return matrix_(col_,index);
4266 }
4268 //*************************************************************************************************
4269 
4270 
4271 //*************************************************************************************************
4281 template< typename MT > // Type of the dense matrix
4283  Column<MT,false,true,true>::operator[]( size_t index ) const
4284 {
4285  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4286  return const_cast<const MT&>( matrix_ )(index,col_);
4287 }
4289 //*************************************************************************************************
4290 
4291 
4292 //*************************************************************************************************
4303 template< typename MT > // Type of the dense matrix
4305  Column<MT,false,true,true>::at( size_t index )
4306 {
4307  if( index >= size() ) {
4308  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4309  }
4310  return (*this)[index];
4311 }
4313 //*************************************************************************************************
4314 
4315 
4316 //*************************************************************************************************
4327 template< typename MT > // Type of the dense matrix
4329  Column<MT,false,true,true>::at( size_t index ) const
4330 {
4331  if( index >= size() ) {
4332  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4333  }
4334  return (*this)[index];
4335 }
4337 //*************************************************************************************************
4338 
4339 
4340 //*************************************************************************************************
4349 template< typename MT > // Type of the dense matrix
4350 inline typename Column<MT,false,true,true>::Pointer Column<MT,false,true,true>::data() noexcept
4351 {
4352  return matrix_.data( col_ );
4353 }
4355 //*************************************************************************************************
4356 
4357 
4358 //*************************************************************************************************
4367 template< typename MT > // Type of the dense matrix
4368 inline typename Column<MT,false,true,true>::ConstPointer
4369  Column<MT,false,true,true>::data() const noexcept
4370 {
4371  return matrix_.data( col_ );
4372 }
4374 //*************************************************************************************************
4375 
4376 
4377 //*************************************************************************************************
4385 template< typename MT > // Type of the dense matrix
4387 {
4388  return matrix_.begin( col_ );
4389 }
4391 //*************************************************************************************************
4392 
4393 
4394 //*************************************************************************************************
4402 template< typename MT > // Type of the dense matrix
4404 {
4405  return matrix_.cbegin( col_ );
4406 }
4408 //*************************************************************************************************
4409 
4410 
4411 //*************************************************************************************************
4419 template< typename MT > // Type of the dense matrix
4421 {
4422  return matrix_.cbegin( col_ );
4423 }
4425 //*************************************************************************************************
4426 
4427 
4428 //*************************************************************************************************
4436 template< typename MT > // Type of the dense matrix
4438 {
4439  return matrix_.end( col_ );
4440 }
4442 //*************************************************************************************************
4443 
4444 
4445 //*************************************************************************************************
4453 template< typename MT > // Type of the dense matrix
4455 {
4456  return matrix_.cend( col_ );
4457 }
4459 //*************************************************************************************************
4460 
4461 
4462 //*************************************************************************************************
4470 template< typename MT > // Type of the dense matrix
4472 {
4473  return matrix_.cend( col_ );
4474 }
4476 //*************************************************************************************************
4477 
4478 
4479 
4480 
4481 //=================================================================================================
4482 //
4483 // ASSIGNMENT OPERATORS
4484 //
4485 //=================================================================================================
4486 
4487 //*************************************************************************************************
4494 template< typename MT > // Type of the dense matrix
4495 inline Column<MT,false,true,true>& Column<MT,false,true,true>::operator=( const ElementType& rhs )
4496 {
4497  const size_t jbegin( ( IsUpper<MT>::value )
4498  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4499  ?( col_+1UL )
4500  :( col_ ) )
4501  :( 0UL ) );
4502  const size_t jend ( ( IsLower<MT>::value )
4503  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4504  ?( col_ )
4505  :( col_+1UL ) )
4506  :( size() ) );
4507 
4508  for( size_t j=jbegin; j<jend; ++j )
4509  matrix_(col_,j) = rhs;
4510 
4511  return *this;
4512 }
4514 //*************************************************************************************************
4515 
4516 
4517 //*************************************************************************************************
4530 template< typename MT > // Type of the dense matrix
4531 inline Column<MT,false,true,true>&
4532  Column<MT,false,true,true>::operator=( initializer_list<ElementType> list )
4533 {
4534  if( list.size() > size() ) {
4535  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
4536  }
4537 
4538  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
4539 
4540  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4541 
4542  return *this;
4543 }
4545 //*************************************************************************************************
4546 
4547 
4548 //*************************************************************************************************
4562 template< typename MT > // Type of the dense matrix
4563 inline Column<MT,false,true,true>& Column<MT,false,true,true>::operator=( const Column& rhs )
4564 {
4565  if( &rhs == this ) return *this;
4566 
4567  if( size() != rhs.size() ) {
4568  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
4569  }
4570 
4571  if( !tryAssign( matrix_, rhs, 0UL, col_ ) ) {
4572  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4573  }
4574 
4575  DerestrictTrait_<This> left( derestrict( *this ) );
4576 
4577  smpAssign( left, rhs );
4578 
4579  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4580 
4581  return *this;
4582 }
4584 //*************************************************************************************************
4585 
4586 
4587 //*************************************************************************************************
4601 template< typename MT > // Type of the dense matrix
4602 template< typename VT > // Type of the right-hand side vector
4603 inline Column<MT,false,true,true>&
4604  Column<MT,false,true,true>::operator=( const Vector<VT,false>& rhs )
4605 {
4606  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4608 
4609  if( size() != (~rhs).size() ) {
4610  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4611  }
4612 
4613  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4614  Right right( ~rhs );
4615 
4616  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
4617  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4618  }
4619 
4620  DerestrictTrait_<This> left( derestrict( *this ) );
4621 
4622  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4623  const ResultType_<VT> tmp( right );
4624  smpAssign( left, tmp );
4625  }
4626  else {
4627  if( IsSparseVector<VT>::value )
4628  reset();
4629  smpAssign( left, right );
4630  }
4631 
4632  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4633 
4634  return *this;
4635 }
4637 //*************************************************************************************************
4638 
4639 
4640 //*************************************************************************************************
4654 template< typename MT > // Type of the dense matrix
4655 template< typename VT > // Type of the right-hand side vector
4656 inline Column<MT,false,true,true>&
4657  Column<MT,false,true,true>::operator+=( const Vector<VT,false>& rhs )
4658 {
4659  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4661 
4662  if( size() != (~rhs).size() ) {
4663  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4664  }
4665 
4666  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4667  Right right( ~rhs );
4668 
4669  if( !tryAddAssign( matrix_, right, 0UL, col_ ) ) {
4670  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4671  }
4672 
4673  DerestrictTrait_<This> left( derestrict( *this ) );
4674 
4675  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4676  const ResultType_<VT> tmp( right );
4677  smpAddAssign( left, tmp );
4678  }
4679  else {
4680  smpAddAssign( left, right );
4681  }
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 template< typename VT > // Type of the right-hand side vector
4707 inline Column<MT,false,true,true>&
4708  Column<MT,false,true,true>::operator-=( const Vector<VT,false>& rhs )
4709 {
4710  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4712 
4713  if( size() != (~rhs).size() ) {
4714  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4715  }
4716 
4717  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4718  Right right( ~rhs );
4719 
4720  if( !trySubAssign( matrix_, right, 0UL, col_ ) ) {
4721  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4722  }
4723 
4724  DerestrictTrait_<This> left( derestrict( *this ) );
4725 
4726  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4727  const ResultType_<VT> tmp( right );
4728  smpSubAssign( left, tmp );
4729  }
4730  else {
4731  smpSubAssign( left, right );
4732  }
4733 
4734  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4735 
4736  return *this;
4737 }
4739 //*************************************************************************************************
4740 
4741 
4742 //*************************************************************************************************
4755 template< typename MT > // Type of the dense matrix
4756 template< typename VT > // Type of the right-hand side dense vector
4757 inline Column<MT,false,true,true>&
4758  Column<MT,false,true,true>::operator*=( const DenseVector<VT,false>& rhs )
4759 {
4760  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4762 
4763  if( size() != (~rhs).size() ) {
4764  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4765  }
4766 
4767  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4768  Right right( ~rhs );
4769 
4770  if( !tryMultAssign( matrix_, right, 0UL, col_ ) ) {
4771  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4772  }
4773 
4774  DerestrictTrait_<This> left( derestrict( *this ) );
4775 
4776  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4777  const ResultType_<VT> tmp( right );
4778  smpMultAssign( left, tmp );
4779  }
4780  else {
4781  smpMultAssign( left, right );
4782  }
4783 
4784  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4785 
4786  return *this;
4787 }
4789 //*************************************************************************************************
4790 
4791 
4792 //*************************************************************************************************
4805 template< typename MT > // Type of the dense matrix
4806 template< typename VT > // Type of the right-hand side sparse vector
4807 inline Column<MT,false,true,true>&
4808  Column<MT,false,true,true>::operator*=( const SparseVector<VT,false>& rhs )
4809 {
4813 
4814  if( size() != (~rhs).size() ) {
4815  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4816  }
4817 
4818  const ResultType right( *this * (~rhs) );
4819 
4820  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
4821  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4822  }
4823 
4824  DerestrictTrait_<This> left( derestrict( *this ) );
4825 
4826  smpAssign( left, right );
4827 
4828  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4829 
4830  return *this;
4831 }
4833 //*************************************************************************************************
4834 
4835 
4836 //*************************************************************************************************
4848 template< typename MT > // Type of the dense matrix
4849 template< typename VT > // Type of the right-hand side dense vector
4850 inline Column<MT,false,true,true>&
4851  Column<MT,false,true,true>::operator/=( const DenseVector<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  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4861  Right right( ~rhs );
4862 
4863  if( !tryDivAssign( matrix_, right, 0UL, col_ ) ) {
4864  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4865  }
4866 
4867  DerestrictTrait_<This> left( derestrict( *this ) );
4868 
4869  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4870  const ResultType_<VT> tmp( right );
4871  smpDivAssign( left, tmp );
4872  }
4873  else {
4874  smpDivAssign( left, right );
4875  }
4876 
4877  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4878 
4879  return *this;
4880 }
4882 //*************************************************************************************************
4883 
4884 
4885 //*************************************************************************************************
4896 template< typename MT > // Type of the dense matrix
4897 template< typename Other > // Data type of the right-hand side scalar
4898 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,true> >&
4900 {
4902 
4903  return operator=( (*this) * rhs );
4904 }
4906 //*************************************************************************************************
4907 
4908 
4909 //*************************************************************************************************
4922 template< typename MT > // Type of the dense matrix
4923 template< typename Other > // Data type of the right-hand side scalar
4924 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,true> >&
4926 {
4928 
4929  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4930 
4931  return operator=( (*this) / rhs );
4932 }
4934 //*************************************************************************************************
4935 
4936 
4937 
4938 
4939 //=================================================================================================
4940 //
4941 // UTILITY FUNCTIONS
4942 //
4943 //=================================================================================================
4944 
4945 //*************************************************************************************************
4951 template< typename MT > // Type of the dense matrix
4952 inline size_t Column<MT,false,true,true>::size() const noexcept
4953 {
4954  return matrix_.rows();
4955 }
4957 //*************************************************************************************************
4958 
4959 
4960 //*************************************************************************************************
4966 template< typename MT > // Type of the dense matrix
4967 inline size_t Column<MT,false,true,true>::capacity() const noexcept
4968 {
4969  return matrix_.capacity( col_ );
4970 }
4972 //*************************************************************************************************
4973 
4974 
4975 //*************************************************************************************************
4984 template< typename MT > // Type of the dense matrix
4985 inline size_t Column<MT,false,true,true>::nonZeros() const
4986 {
4987  return matrix_.nonZeros( col_ );
4988 }
4990 //*************************************************************************************************
4991 
4992 
4993 //*************************************************************************************************
4999 template< typename MT > // Type of the dense matrix
5001 {
5002  matrix_.reset( col_ );
5003 }
5005 //*************************************************************************************************
5006 
5007 
5008 
5009 
5010 //=================================================================================================
5011 //
5012 // NUMERIC FUNCTIONS
5013 //
5014 //=================================================================================================
5015 
5016 //*************************************************************************************************
5027 template< typename MT > // Type of the dense matrix
5028 template< typename Other > // Data type of the scalar value
5029 inline Column<MT,false,true,true>& Column<MT,false,true,true>::scale( const Other& scalar )
5030 {
5032 
5033  const size_t jbegin( ( IsUpper<MT>::value )
5034  ?( ( IsStrictlyUpper<MT>::value )
5035  ?( col_+1UL )
5036  :( col_ ) )
5037  :( 0UL ) );
5038  const size_t jend ( ( IsLower<MT>::value )
5039  ?( ( IsStrictlyLower<MT>::value )
5040  ?( col_ )
5041  :( col_+1UL ) )
5042  :( size() ) );
5043 
5044  for( size_t j=jbegin; j<jend; ++j ) {
5045  matrix_(col_,j) *= scalar;
5046  }
5047 
5048  return *this;
5049 }
5051 //*************************************************************************************************
5052 
5053 
5054 
5055 
5056 //=================================================================================================
5057 //
5058 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5059 //
5060 //=================================================================================================
5061 
5062 //*************************************************************************************************
5073 template< typename MT > // Type of the dense matrix
5074 template< typename Other > // Data type of the foreign expression
5075 inline bool Column<MT,false,true,true>::canAlias( const Other* alias ) const noexcept
5076 {
5077  return matrix_.isAliased( alias );
5078 }
5080 //*************************************************************************************************
5081 
5082 
5083 //*************************************************************************************************
5094 template< typename MT > // Type of the dense matrix
5095 template< typename MT2 // Data type of the foreign dense column
5096  , bool SO2 // Storage order of the foreign dense column
5097  , bool SF2 > // Symmetry flag of the foreign dense column
5098 inline bool Column<MT,false,true,true>::canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
5099 {
5100  return matrix_.isAliased( alias->matrix_ ) && ( col_ == alias->col_ );
5101 }
5103 //*************************************************************************************************
5104 
5105 
5106 //*************************************************************************************************
5117 template< typename MT > // Type of the dense matrix
5118 template< typename Other > // Data type of the foreign expression
5119 inline bool Column<MT,false,true,true>::isAliased( const Other* alias ) const noexcept
5120 {
5121  return matrix_.isAliased( alias );
5122 }
5124 //*************************************************************************************************
5125 
5126 
5127 //*************************************************************************************************
5138 template< typename MT > // Type of the dense matrix
5139 template< typename MT2 // Data type of the foreign dense column
5140  , bool SO2 // Storage order of the foreign dense column
5141  , bool SF2 > // Symmetry flag of the foreign dense column
5142 inline bool Column<MT,false,true,true>::isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
5143 {
5144  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
5145 }
5147 //*************************************************************************************************
5148 
5149 
5150 //*************************************************************************************************
5160 template< typename MT > // Type of the dense matrix
5161 inline bool Column<MT,false,true,true>::isAligned() const noexcept
5162 {
5163  return matrix_.isAligned();
5164 }
5166 //*************************************************************************************************
5167 
5168 
5169 //*************************************************************************************************
5180 template< typename MT > // Type of the dense matrix
5181 inline bool Column<MT,false,true,true>::canSMPAssign() const noexcept
5182 {
5183  return ( size() > SMP_DVECASSIGN_THRESHOLD );
5184 }
5186 //*************************************************************************************************
5187 
5188 
5189 //*************************************************************************************************
5201 template< typename MT > // Type of the dense matrix
5202 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true>::SIMDType
5203  Column<MT,false,true,true>::load( size_t index ) const noexcept
5204 {
5205  return matrix_.load( col_, index );
5206 }
5208 //*************************************************************************************************
5209 
5210 
5211 //*************************************************************************************************
5224 template< typename MT > // Type of the dense matrix
5225 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true>::SIMDType
5226  Column<MT,false,true,true>::loada( size_t index ) const noexcept
5227 {
5228  return matrix_.loada( col_, index );
5229 }
5231 //*************************************************************************************************
5232 
5233 
5234 //*************************************************************************************************
5247 template< typename MT > // Type of the dense matrix
5248 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true>::SIMDType
5249  Column<MT,false,true,true>::loadu( size_t index ) const noexcept
5250 {
5251  return matrix_.loadu( col_, index );
5252 }
5254 //*************************************************************************************************
5255 
5256 
5257 //*************************************************************************************************
5270 template< typename MT > // Type of the dense matrix
5272  Column<MT,false,true,true>::store( size_t index, const SIMDType& value ) noexcept
5273 {
5274  matrix_.store( col_, index, value );
5275 }
5277 //*************************************************************************************************
5278 
5279 
5280 //*************************************************************************************************
5294 template< typename MT > // Type of the dense matrix
5296  Column<MT,false,true,true>::storea( size_t index, const SIMDType& value ) noexcept
5297 {
5298  matrix_.storea( col_, index, value );
5299 }
5301 //*************************************************************************************************
5302 
5303 
5304 //*************************************************************************************************
5318 template< typename MT > // Type of the dense matrix
5320  Column<MT,false,true,true>::storeu( size_t index, const SIMDType& value ) noexcept
5321 {
5322  matrix_.storeu( col_, index, value );
5323 }
5325 //*************************************************************************************************
5326 
5327 
5328 //*************************************************************************************************
5342 template< typename MT > // Type of the dense matrix
5344  Column<MT,false,true,true>::stream( size_t index, const SIMDType& value ) noexcept
5345 {
5346  matrix_.stream( col_, index, value );
5347 }
5349 //*************************************************************************************************
5350 
5351 
5352 //*************************************************************************************************
5364 template< typename MT > // Type of the dense matrix
5365 template< typename VT > // Type of the right-hand side dense vector
5366 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5367  Column<MT,false,true,true>::assign( const DenseVector<VT,false>& rhs )
5368 {
5369  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5370 
5371  const size_t jpos( (~rhs).size() & size_t(-2) );
5372  for( size_t j=0UL; j<jpos; j+=2UL ) {
5373  matrix_(col_,j ) = (~rhs)[j ];
5374  matrix_(col_,j+1UL) = (~rhs)[j+1UL];
5375  }
5376  if( jpos < (~rhs).size() )
5377  matrix_(col_,jpos) = (~rhs)[jpos];
5378 }
5380 //*************************************************************************************************
5381 
5382 
5383 //*************************************************************************************************
5395 template< typename MT > // Type of the dense matrix
5396 template< typename VT > // Type of the right-hand side dense vector
5397 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5398  Column<MT,false,true,true>::assign( const DenseVector<VT,false>& rhs )
5399 {
5401 
5402  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5403 
5404  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5405 
5406  const size_t columns( size() );
5407 
5408  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5409  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5410 
5411  size_t j( 0UL );
5412  Iterator left( begin() );
5413  ConstIterator_<VT> right( (~rhs).begin() );
5414 
5415  if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
5416  {
5417  for( ; j<jpos; j+=SIMDSIZE ) {
5418  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5419  }
5420  for( ; remainder && j<columns; ++j ) {
5421  *left = *right; ++left; ++right;
5422  }
5423  }
5424  else
5425  {
5426  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5427  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5428  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5429  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5430  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5431  }
5432  for( ; j<jpos; j+=SIMDSIZE ) {
5433  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5434  }
5435  for( ; remainder && j<columns; ++j ) {
5436  *left = *right; ++left; ++right;
5437  }
5438  }
5439 }
5441 //*************************************************************************************************
5442 
5443 
5444 //*************************************************************************************************
5456 template< typename MT > // Type of the dense matrix
5457 template< typename VT > // Type of the right-hand side sparse vector
5458 inline void Column<MT,false,true,true>::assign( const SparseVector<VT,false>& rhs )
5459 {
5460  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5461 
5462  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5463  matrix_(col_,element->index()) = element->value();
5464 }
5466 //*************************************************************************************************
5467 
5468 
5469 //*************************************************************************************************
5481 template< typename MT > // Type of the dense matrix
5482 template< typename VT > // Type of the right-hand side dense vector
5483 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5484  Column<MT,false,true,true>::addAssign( const DenseVector<VT,false>& rhs )
5485 {
5486  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5487 
5488  const size_t jpos( (~rhs).size() & size_t(-2) );
5489  for( size_t j=0UL; j<jpos; j+=2UL ) {
5490  matrix_(col_,j ) += (~rhs)[j ];
5491  matrix_(col_,j+1UL) += (~rhs)[j+1UL];
5492  }
5493  if( jpos < (~rhs).size() )
5494  matrix_(col_,jpos) += (~rhs)[jpos];
5495 }
5497 //*************************************************************************************************
5498 
5499 
5500 //*************************************************************************************************
5512 template< typename MT > // Type of the dense matrix
5513 template< typename VT > // Type of the right-hand side dense vector
5514 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5515  Column<MT,false,true,true>::addAssign( const DenseVector<VT,false>& rhs )
5516 {
5518 
5519  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5520 
5521  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5522 
5523  const size_t columns( size() );
5524 
5525  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5526  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5527 
5528  size_t j( 0UL );
5529  Iterator left( begin() );
5530  ConstIterator_<VT> right( (~rhs).begin() );
5531 
5532  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5533  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5534  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5535  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5536  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5537  }
5538  for( ; j<jpos; j+=SIMDSIZE ) {
5539  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5540  }
5541  for( ; remainder && j<columns; ++j ) {
5542  *left += *right; ++left; ++right;
5543  }
5544 }
5546 //*************************************************************************************************
5547 
5548 
5549 //*************************************************************************************************
5561 template< typename MT > // Type of the dense matrix
5562 template< typename VT > // Type of the right-hand side sparse vector
5563 inline void Column<MT,false,true,true>::addAssign( const SparseVector<VT,false>& rhs )
5564 {
5565  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5566 
5567  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5568  matrix_(col_,element->index()) += element->value();
5569 }
5571 //*************************************************************************************************
5572 
5573 
5574 //*************************************************************************************************
5586 template< typename MT > // Type of the dense matrix
5587 template< typename VT > // Type of the right-hand side dense vector
5588 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5589  Column<MT,false,true,true>::subAssign( const DenseVector<VT,false>& rhs )
5590 {
5591  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5592 
5593  const size_t jpos( (~rhs).size() & size_t(-2) );
5594  for( size_t j=0UL; j<jpos; j+=2UL ) {
5595  matrix_(col_,j ) -= (~rhs)[j ];
5596  matrix_(col_,j+1UL) -= (~rhs)[j+1UL];
5597  }
5598  if( jpos < (~rhs).size() )
5599  matrix_(col_,jpos) -= (~rhs)[jpos];
5600 }
5602 //*************************************************************************************************
5603 
5604 
5605 //*************************************************************************************************
5617 template< typename MT > // Type of the dense matrix
5618 template< typename VT > // Type of the right-hand side dense vector
5619 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5620  Column<MT,false,true,true>::subAssign( const DenseVector<VT,false>& rhs )
5621 {
5623 
5624  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5625 
5626  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5627 
5628  const size_t columns( size() );
5629 
5630  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5631  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5632 
5633  size_t j( 0UL );
5634  Iterator left( begin() );
5635  ConstIterator_<VT> right( (~rhs).begin() );
5636 
5637  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5638  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5639  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5640  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5641  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5642  }
5643  for( ; j<jpos; j+=SIMDSIZE ) {
5644  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5645  }
5646  for( ; remainder && j<columns; ++j ) {
5647  *left -= *right; ++left; ++right;
5648  }
5649 }
5651 //*************************************************************************************************
5652 
5653 
5654 //*************************************************************************************************
5666 template< typename MT > // Type of the dense matrix
5667 template< typename VT > // Type of the right-hand side sparse vector
5668 inline void Column<MT,false,true,true>::subAssign( const SparseVector<VT,false>& rhs )
5669 {
5670  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5671 
5672  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5673  matrix_(col_,element->index()) -= element->value();
5674 }
5676 //*************************************************************************************************
5677 
5678 
5679 //*************************************************************************************************
5691 template< typename MT > // Type of the dense matrix
5692 template< typename VT > // Type of the right-hand side dense vector
5693 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5694  Column<MT,false,true,true>::multAssign( const DenseVector<VT,false>& rhs )
5695 {
5696  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5697 
5698  const size_t jpos( (~rhs).size() & size_t(-2) );
5699  for( size_t j=0UL; j<jpos; j+=2UL ) {
5700  matrix_(col_,j ) *= (~rhs)[j ];
5701  matrix_(col_,j+1UL) *= (~rhs)[j+1UL];
5702  }
5703  if( jpos < (~rhs).size() )
5704  matrix_(col_,jpos) *= (~rhs)[jpos];
5705 }
5707 //*************************************************************************************************
5708 
5709 
5710 //*************************************************************************************************
5722 template< typename MT > // Type of the dense matrix
5723 template< typename VT > // Type of the right-hand side dense vector
5724 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5725  Column<MT,false,true,true>::multAssign( const DenseVector<VT,false>& rhs )
5726 {
5728 
5729  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5730 
5731  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5732 
5733  const size_t columns( size() );
5734 
5735  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5736  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5737 
5738  size_t j( 0UL );
5739  Iterator left( begin() );
5740  ConstIterator_<VT> right( (~rhs).begin() );
5741 
5742  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5743  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5744  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5745  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5746  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5747  }
5748  for( ; j<jpos; j+=SIMDSIZE ) {
5749  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5750  }
5751  for( ; remainder && j<columns; ++j ) {
5752  *left *= *right; ++left; ++right;
5753  }
5754 }
5756 //*************************************************************************************************
5757 
5758 
5759 //*************************************************************************************************
5771 template< typename MT > // Type of the dense matrix
5772 template< typename VT > // Type of the right-hand side sparse vector
5773 inline void Column<MT,false,true,true>::multAssign( const SparseVector<VT,false>& rhs )
5774 {
5775  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5776 
5777  const ResultType tmp( serial( *this ) );
5778 
5779  reset();
5780 
5781  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5782  matrix_(col_,element->index()) = tmp[element->index()] * element->value();
5783 }
5785 //*************************************************************************************************
5786 
5787 
5788 //*************************************************************************************************
5800 template< typename MT > // Type of the dense matrix
5801 template< typename VT > // Type of the right-hand side dense vector
5802 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
5803  Column<MT,false,true,true>::divAssign( const DenseVector<VT,false>& rhs )
5804 {
5805  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5806 
5807  const size_t jpos( (~rhs).size() & size_t(-2) );
5808  for( size_t j=0UL; j<jpos; j+=2UL ) {
5809  matrix_(col_,j ) /= (~rhs)[j ];
5810  matrix_(col_,j+1UL) /= (~rhs)[j+1UL];
5811  }
5812  if( jpos < (~rhs).size() )
5813  matrix_(col_,jpos) /= (~rhs)[jpos];
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 EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
5834  Column<MT,false,true,true>::divAssign( const DenseVector<VT,false>& rhs )
5835 {
5837 
5838  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5839 
5840  const size_t columns( size() );
5841 
5842  const size_t jpos( columns & size_t(-SIMDSIZE) );
5843  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5844 
5845  size_t j( 0UL );
5846  Iterator left( begin() );
5847  ConstIterator_<VT> right( (~rhs).begin() );
5848 
5849  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5850  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5851  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5852  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5853  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5854  }
5855  for( ; j<jpos; j+=SIMDSIZE ) {
5856  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5857  }
5858  for( ; j<columns; ++j ) {
5859  *left /= *right; ++left; ++right;
5860  }
5861 }
5863 //*************************************************************************************************
5864 
5865 } // namespace blaze
5866 
5867 #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.
constexpr bool useOptimizedKernels
Configuration switch for optimized kernels.This configuration switch enables/disables all optimized c...
Definition: Optimizations.h:84
typename DerestrictTrait< T >::Type DerestrictTrait_
Auxiliary alias declaration for the DerestrictTrait type trait.The DerestrictTrait_ alias declaration...
Definition: DerestrictTrait.h:110
#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:352
BLAZE_ALWAYS_INLINE bool isSame(const Matrix< MT1, SO1 > &a, const Matrix< MT2, SO2 > &b) noexcept
Returns whether the two given matrices represent the same observable state.
Definition: Matrix.h:721
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:160
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:261
#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
constexpr size_t cacheSize
Cache size of the target architecture.This setting specifies the available cache size in Byte of the ...
Definition: CacheSize.h:48
#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:1339
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:194
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:533
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
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2935
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:223
Header file for the DenseVector base class.
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2928
#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 DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:721
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:390
#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
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:1321
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:129
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:304
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:238
Constraint on the data type.
Header file for the std::initializer_list aliases.
Constraint on the transpose flag of vector types.
Constraint on the data type.
Header file for the DisableIf class template.
Header file for the IsStrictlyUpper type trait.
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.
constexpr bool useStreaming
Configuration of the streaming behavior.For large vectors and matrices non-temporal stores can provid...
Definition: Optimizations.h:68
#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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2939
#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:98
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.
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:336
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.
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< MT > >, RowExprTrait_< MT > > row(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific row of the given matrix.
Definition: Row.h:128
#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
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2932
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:260
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:2933
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.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2937
DisableIf_< Or< IsComputation< MT >, IsTransExpr< MT >, IsDeclExpr< MT > >, ColumnExprTrait_< MT > > column(Matrix< MT, SO > &matrix, size_t index)
Creating a view on a specific column of the given matrix.
Definition: Column.h:128
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:553
Header file for the IsPadded type trait.
Header file for the DerestrictTrait class template.
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.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2934
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:1285
Header file for run time assertion macros.
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
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:2938
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.
#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:223
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:320
#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
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2929
Header file for the HasSIMDDiv type trait.
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2930
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:249
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2936
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:1303
Header file for the IsUpper type trait.
Header file for the IsRestricted type trait.
const DMatDMatMultExpr< T1, T2, false, false, false, false > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:7505
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.