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();
228  template< typename Other > inline Column& scale( const Other& scalar );
230  //**********************************************************************************************
231 
232  private:
233  //**********************************************************************************************
235  template< typename VT >
236  struct VectorizedAssign {
237  enum : bool { value = useOptimizedKernels &&
238  simdEnabled && VT::simdEnabled &&
239  AreSIMDCombinable< ElementType, ElementType_<VT> >::value };
240  };
241  //**********************************************************************************************
242 
243  //**********************************************************************************************
245  template< typename VT >
246  struct VectorizedAddAssign {
247  enum : bool { value = useOptimizedKernels &&
248  simdEnabled && VT::simdEnabled &&
249  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
250  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
251  };
252  //**********************************************************************************************
253 
254  //**********************************************************************************************
256  template< typename VT >
257  struct VectorizedSubAssign {
258  enum : bool { value = useOptimizedKernels &&
259  simdEnabled && VT::simdEnabled &&
260  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
261  HasSIMDSub< ElementType, ElementType_<VT> >::value };
262  };
263  //**********************************************************************************************
264 
265  //**********************************************************************************************
267  template< typename VT >
268  struct VectorizedMultAssign {
269  enum : bool { value = useOptimizedKernels &&
270  simdEnabled && VT::simdEnabled &&
271  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
272  HasSIMDMult< ElementType, ElementType_<VT> >::value };
273  };
274  //**********************************************************************************************
275 
276  //**********************************************************************************************
278  template< typename VT >
279  struct VectorizedDivAssign {
280  enum : bool { value = useOptimizedKernels &&
281  simdEnabled && VT::simdEnabled &&
282  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
283  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
284  };
285  //**********************************************************************************************
286 
287  //**SIMD properties*****************************************************************************
289  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
290  //**********************************************************************************************
291 
292  public:
293  //**Expression template evaluation functions****************************************************
296  template< typename Other >
297  inline bool canAlias( const Other* alias ) const noexcept;
298 
299  template< typename MT2, bool SO2, bool SF2 >
300  inline bool canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
301 
302  template< typename Other >
303  inline bool isAliased( const Other* alias ) const noexcept;
304 
305  template< typename MT2, bool SO2, bool SF2 >
306  inline bool isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
307 
308  inline bool isAligned () const noexcept;
309  inline bool canSMPAssign() const noexcept;
310 
311  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
312  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
313  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
314 
315  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
316  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
317  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
318  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
319 
320  template< typename VT >
321  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
322 
323  template< typename VT >
324  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
325 
326  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
327 
328  template< typename VT >
329  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
330 
331  template< typename VT >
332  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
333 
334  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
335 
336  template< typename VT >
337  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
338 
339  template< typename VT >
340  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
341 
342  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
343 
344  template< typename VT >
345  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
346 
347  template< typename VT >
348  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
349 
350  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
351 
352  template< typename VT >
353  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
354 
355  template< typename VT >
356  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
358  //**********************************************************************************************
359 
360  private:
361  //**Member variables****************************************************************************
364  Operand matrix_;
365  const size_t col_;
366 
367  //**********************************************************************************************
368 
369  //**Friend declarations*************************************************************************
370  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Column;
371 
372  template< typename MT2, bool SO2, bool DF2, bool SF2 >
373  friend bool isIntact( const Column<MT2,SO2,DF2,SF2>& column ) noexcept;
374 
375  template< typename MT2, bool SO2, bool DF2, bool SF2 >
376  friend bool isSame( const Column<MT2,SO2,DF2,SF2>& a, const Column<MT2,SO2,DF2,SF2>& b ) noexcept;
377 
378  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
379  friend bool tryAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
380 
381  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
382  friend bool tryAddAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
383 
384  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
385  friend bool trySubAssign( 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 tryMultAssign( 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 tryDivAssign( 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 >
394  friend DerestrictTrait_< Column<MT2,SO2,DF2,SF2> > derestrict( Column<MT2,SO2,DF2,SF2>& column );
395  //**********************************************************************************************
396 
397  //**Compile time checks*************************************************************************
404  //**********************************************************************************************
405 };
407 //*************************************************************************************************
408 
409 
410 
411 
412 //=================================================================================================
413 //
414 // CONSTRUCTOR
415 //
416 //=================================================================================================
417 
418 //*************************************************************************************************
426 template< typename MT // Type of the dense matrix
427  , bool SF > // Symmetry flag
428 inline Column<MT,true,true,SF>::Column( Operand matrix, size_t index )
429  : matrix_( matrix ) // The dense matrix containing the column
430  , col_ ( index ) // The index of the column in the matrix
431 {
432  if( matrix_.columns() <= index ) {
433  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
434  }
435 }
437 //*************************************************************************************************
438 
439 
440 
441 
442 //=================================================================================================
443 //
444 // DATA ACCESS FUNCTIONS
445 //
446 //=================================================================================================
447 
448 //*************************************************************************************************
458 template< typename MT // Type of the dense matrix
459  , bool SF > // Symmetry flag
460 inline typename Column<MT,true,true,SF>::Reference Column<MT,true,true,SF>::operator[]( size_t index )
461 {
462  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
463  return matrix_(index,col_);
464 }
466 //*************************************************************************************************
467 
468 
469 //*************************************************************************************************
479 template< typename MT // Type of the dense matrix
480  , bool SF > // Symmetry flag
482  Column<MT,true,true,SF>::operator[]( size_t index ) const
483 {
484  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
485  return const_cast<const MT&>( matrix_ )(index,col_);
486 }
488 //*************************************************************************************************
489 
490 
491 //*************************************************************************************************
502 template< typename MT // Type of the dense matrix
503  , bool SF > // Symmetry flag
504 inline typename Column<MT,true,true,SF>::Reference Column<MT,true,true,SF>::at( size_t index )
505 {
506  if( index >= size() ) {
507  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
508  }
509  return (*this)[index];
510 }
512 //*************************************************************************************************
513 
514 
515 //*************************************************************************************************
526 template< typename MT // Type of the dense matrix
527  , bool SF > // Symmetry flag
529  Column<MT,true,true,SF>::at( size_t index ) const
530 {
531  if( index >= size() ) {
532  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
533  }
534  return (*this)[index];
535 }
537 //*************************************************************************************************
538 
539 
540 //*************************************************************************************************
549 template< typename MT // Type of the dense matrix
550  , bool SF > // Symmetry flag
551 inline typename Column<MT,true,true,SF>::Pointer Column<MT,true,true,SF>::data() noexcept
552 {
553  return matrix_.data( col_ );
554 }
556 //*************************************************************************************************
557 
558 
559 //*************************************************************************************************
568 template< typename MT // Type of the dense matrix
569  , bool SF > // Symmetry flag
570 inline typename Column<MT,true,true,SF>::ConstPointer Column<MT,true,true,SF>::data() const noexcept
571 {
572  return matrix_.data( col_ );
573 }
575 //*************************************************************************************************
576 
577 
578 //*************************************************************************************************
586 template< typename MT // Type of the dense matrix
587  , bool SF > // Symmetry flag
589 {
590  return matrix_.begin( col_ );
591 }
593 //*************************************************************************************************
594 
595 
596 //*************************************************************************************************
604 template< typename MT // Type of the dense matrix
605  , bool SF > // Symmetry flag
607 {
608  return matrix_.cbegin( col_ );
609 }
611 //*************************************************************************************************
612 
613 
614 //*************************************************************************************************
622 template< typename MT // Type of the dense matrix
623  , bool SF > // Symmetry flag
625 {
626  return matrix_.cbegin( col_ );
627 }
629 //*************************************************************************************************
630 
631 
632 //*************************************************************************************************
640 template< typename MT // Type of the dense matrix
641  , bool SF > // Symmetry flag
643 {
644  return matrix_.end( col_ );
645 }
647 //*************************************************************************************************
648 
649 
650 //*************************************************************************************************
658 template< typename MT // Type of the dense matrix
659  , bool SF > // Symmetry flag
661 {
662  return matrix_.cend( col_ );
663 }
665 //*************************************************************************************************
666 
667 
668 //*************************************************************************************************
676 template< typename MT // Type of the dense matrix
677  , bool SF > // Symmetry flag
679 {
680  return matrix_.cend( col_ );
681 }
683 //*************************************************************************************************
684 
685 
686 
687 
688 //=================================================================================================
689 //
690 // ASSIGNMENT OPERATORS
691 //
692 //=================================================================================================
693 
694 //*************************************************************************************************
705 template< typename MT // Type of the dense matrix
706  , bool SF > // Symmetry flag
707 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( const ElementType& rhs )
708 {
709  const size_t ibegin( ( IsLower<MT>::value )
710  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
711  ?( col_+1UL )
712  :( col_ ) )
713  :( 0UL ) );
714  const size_t iend ( ( IsUpper<MT>::value )
715  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
716  ?( col_ )
717  :( col_+1UL ) )
718  :( size() ) );
719 
720  for( size_t i=ibegin; i<iend; ++i )
721  matrix_(i,col_) = rhs;
722 
723  return *this;
724 }
726 //*************************************************************************************************
727 
728 
729 //*************************************************************************************************
742 template< typename MT // Type of the dense matrix
743  , bool SF > // Symmetry flag
744 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( initializer_list<ElementType> list )
745 {
746  if( list.size() > size() ) {
747  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
748  }
749 
750  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
751 
752  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
753 
754  return *this;
755 }
757 //*************************************************************************************************
758 
759 
760 //*************************************************************************************************
774 template< typename MT // Type of the dense matrix
775  , bool SF > // Symmetry flag
776 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( const Column& rhs )
777 {
778  if( &rhs == this ) return *this;
779 
780  if( size() != rhs.size() ) {
781  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
782  }
783 
784  if( !tryAssign( matrix_, rhs, 0UL, col_ ) ) {
785  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
786  }
787 
788  DerestrictTrait_<This> left( derestrict( *this ) );
789 
790  smpAssign( left, rhs );
791 
792  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
793 
794  return *this;
795 }
797 //*************************************************************************************************
798 
799 
800 //*************************************************************************************************
814 template< typename MT // Type of the dense matrix
815  , bool SF > // Symmetry flag
816 template< typename VT > // Type of the right-hand side vector
817 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator=( const Vector<VT,false>& rhs )
818 {
821 
822  if( size() != (~rhs).size() ) {
823  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
824  }
825 
826  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
827  Right right( ~rhs );
828 
829  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
830  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
831  }
832 
833  DerestrictTrait_<This> left( derestrict( *this ) );
834 
835  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
836  const ResultType_<VT> tmp( right );
837  smpAssign( left, tmp );
838  }
839  else {
840  if( IsSparseVector<VT>::value )
841  reset();
842  smpAssign( left, right );
843  }
844 
845  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
846 
847  return *this;
848 }
850 //*************************************************************************************************
851 
852 
853 //*************************************************************************************************
867 template< typename MT // Type of the dense matrix
868  , bool SF > // Symmetry flag
869 template< typename VT > // Type of the right-hand side vector
870 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator+=( const Vector<VT,false>& rhs )
871 {
874 
875  if( size() != (~rhs).size() ) {
876  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
877  }
878 
879  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
880  Right right( ~rhs );
881 
882  if( !tryAddAssign( matrix_, right, 0UL, col_ ) ) {
883  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
884  }
885 
886  DerestrictTrait_<This> left( derestrict( *this ) );
887 
888  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
889  const ResultType_<VT> tmp( right );
890  smpAddAssign( left, tmp );
891  }
892  else {
893  smpAddAssign( left, right );
894  }
895 
896  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
897 
898  return *this;
899 }
901 //*************************************************************************************************
902 
903 
904 //*************************************************************************************************
918 template< typename MT // Type of the dense matrix
919  , bool SF > // Symmetry flag
920 template< typename VT > // Type of the right-hand side vector
921 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator-=( const Vector<VT,false>& rhs )
922 {
925 
926  if( size() != (~rhs).size() ) {
927  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
928  }
929 
930  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
931  Right right( ~rhs );
932 
933  if( !trySubAssign( matrix_, right, 0UL, col_ ) ) {
934  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
935  }
936 
937  DerestrictTrait_<This> left( derestrict( *this ) );
938 
939  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
940  const ResultType_<VT> tmp( right );
941  smpSubAssign( left, tmp );
942  }
943  else {
944  smpSubAssign( left, right );
945  }
946 
947  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
948 
949  return *this;
950 }
952 //*************************************************************************************************
953 
954 
955 //*************************************************************************************************
968 template< typename MT // Type of the dense matrix
969  , bool SF > // Symmetry flag
970 template< typename VT > // Type of the right-hand side dense vector
971 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator*=( const DenseVector<VT,false>& rhs )
972 {
975 
976  if( size() != (~rhs).size() ) {
977  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
978  }
979 
980  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
981  Right right( ~rhs );
982 
983  if( !tryMultAssign( matrix_, right, 0UL, col_ ) ) {
984  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
985  }
986 
987  DerestrictTrait_<This> left( derestrict( *this ) );
988 
989  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
990  const ResultType_<VT> tmp( right );
991  smpMultAssign( left, tmp );
992  }
993  else {
994  smpMultAssign( left, right );
995  }
996 
997  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
998 
999  return *this;
1000 }
1002 //*************************************************************************************************
1003 
1004 
1005 //*************************************************************************************************
1018 template< typename MT // Type of the dense matrix
1019  , bool SF > // Symmetry flag
1020 template< typename VT > // Type of the right-hand side sparse vector
1021 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator*=( const SparseVector<VT,false>& rhs )
1022 {
1026 
1027  if( size() != (~rhs).size() ) {
1028  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1029  }
1030 
1031  const ResultType right( *this * (~rhs) );
1032 
1033  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
1034  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1035  }
1036 
1037  DerestrictTrait_<This> left( derestrict( *this ) );
1038 
1039  smpAssign( left, right );
1040 
1041  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1042 
1043  return *this;
1044 }
1046 //*************************************************************************************************
1047 
1048 
1049 //*************************************************************************************************
1061 template< typename MT // Type of the dense matrix
1062  , bool SF > // Symmetry flag
1063 template< typename VT > // Type of the right-hand side dense vector
1064 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::operator/=( const DenseVector<VT,false>& rhs )
1065 {
1066  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
1068 
1069  if( size() != (~rhs).size() ) {
1070  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1071  }
1072 
1073  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
1074  Right right( ~rhs );
1075 
1076  if( !tryDivAssign( matrix_, right, 0UL, col_ ) ) {
1077  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1078  }
1079 
1080  DerestrictTrait_<This> left( derestrict( *this ) );
1081 
1082  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1083  const ResultType_<VT> tmp( right );
1084  smpDivAssign( left, tmp );
1085  }
1086  else {
1087  smpDivAssign( left, right );
1088  }
1089 
1090  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1091 
1092  return *this;
1093 }
1095 //*************************************************************************************************
1096 
1097 
1098 //*************************************************************************************************
1109 template< typename MT // Type of the dense matrix
1110  , bool SF > // Symmetry flag
1111 template< typename Other > // Data type of the right-hand side scalar
1112 inline EnableIf_< IsNumeric<Other>, Column<MT,true,true,SF> >&
1114 {
1116 
1117  return operator=( (*this) * rhs );
1118 }
1120 //*************************************************************************************************
1121 
1122 
1123 //*************************************************************************************************
1136 template< typename MT // Type of the dense matrix
1137  , bool SF > // Symmetry flag
1138 template< typename Other > // Data type of the right-hand side scalar
1139 inline EnableIf_< IsNumeric<Other>, Column<MT,true,true,SF> >&
1141 {
1143 
1144  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
1145 
1146  return operator=( (*this) / rhs );
1147 }
1149 //*************************************************************************************************
1150 
1151 
1152 
1153 
1154 //=================================================================================================
1155 //
1156 // UTILITY FUNCTIONS
1157 //
1158 //=================================================================================================
1159 
1160 //*************************************************************************************************
1166 template< typename MT // Type of the dense matrix
1167  , bool SF > // Symmetry flag
1168 inline size_t Column<MT,true,true,SF>::size() const noexcept
1169 {
1170  return matrix_.rows();
1171 }
1173 //*************************************************************************************************
1174 
1175 
1176 //*************************************************************************************************
1182 template< typename MT // Type of the dense matrix
1183  , bool SF > // Symmetry flag
1184 inline size_t Column<MT,true,true,SF>::capacity() const noexcept
1185 {
1186  return matrix_.capacity( col_ );
1187 }
1189 //*************************************************************************************************
1190 
1191 
1192 //*************************************************************************************************
1201 template< typename MT // Type of the dense matrix
1202  , bool SF > // Symmetry flag
1203 inline size_t Column<MT,true,true,SF>::nonZeros() const
1204 {
1205  return matrix_.nonZeros( col_ );
1206 }
1208 //*************************************************************************************************
1209 
1210 
1211 //*************************************************************************************************
1217 template< typename MT // Type of the dense matrix
1218  , bool SF > // Symmetry flag
1219 inline void Column<MT,true,true,SF>::reset()
1220 {
1221  matrix_.reset( col_ );
1222 }
1224 //*************************************************************************************************
1225 
1226 
1227 //*************************************************************************************************
1238 template< typename MT // Type of the dense matrix
1239  , bool SF > // Symmetry flag
1240 template< typename Other > // Data type of the scalar value
1241 inline Column<MT,true,true,SF>& Column<MT,true,true,SF>::scale( const Other& scalar )
1242 {
1244 
1245  const size_t ibegin( ( IsLower<MT>::value )
1246  ?( ( IsStrictlyLower<MT>::value )
1247  ?( col_+1UL )
1248  :( col_ ) )
1249  :( 0UL ) );
1250  const size_t iend ( ( IsUpper<MT>::value )
1251  ?( ( IsStrictlyUpper<MT>::value )
1252  ?( col_ )
1253  :( col_+1UL ) )
1254  :( size() ) );
1255 
1256  for( size_t i=ibegin; i<iend; ++i ) {
1257  matrix_(i,col_) *= scalar;
1258  }
1259 
1260  return *this;
1261 }
1263 //*************************************************************************************************
1264 
1265 
1266 
1267 
1268 //=================================================================================================
1269 //
1270 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1271 //
1272 //=================================================================================================
1273 
1274 //*************************************************************************************************
1285 template< typename MT // Type of the dense matrix
1286  , bool SF > // Symmetry flag
1287 template< typename Other > // Data type of the foreign expression
1288 inline bool Column<MT,true,true,SF>::canAlias( const Other* alias ) const noexcept
1289 {
1290  return matrix_.isAliased( alias );
1291 }
1293 //*************************************************************************************************
1294 
1295 
1296 //*************************************************************************************************
1307 template< typename MT // Type of the dense matrix
1308  , bool SF > // Symmetry flag
1309 template< typename MT2 // Data type of the foreign dense column
1310  , bool SO2 // Storage order of the foreign dense column
1311  , bool SF2 > // Symmetry flag of the foreign dense column
1312 inline bool Column<MT,true,true,SF>::canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
1313 {
1314  return matrix_.isAliased( alias->matrix_ ) && ( col_ == alias->col_ );
1315 }
1317 //*************************************************************************************************
1318 
1319 
1320 //*************************************************************************************************
1331 template< typename MT // Type of the dense matrix
1332  , bool SF > // Symmetry flag
1333 template< typename Other > // Data type of the foreign expression
1334 inline bool Column<MT,true,true,SF>::isAliased( const Other* alias ) const noexcept
1335 {
1336  return matrix_.isAliased( alias );
1337 }
1339 //*************************************************************************************************
1340 
1341 
1342 //*************************************************************************************************
1353 template< typename MT // Type of the dense matrix
1354  , bool SF > // Symmetry flag
1355 template< typename MT2 // Data type of the foreign dense column
1356  , bool SO2 // Storage order of the foreign dense column
1357  , bool SF2 > // Symmetry flag of the foreign dense column
1358 inline bool Column<MT,true,true,SF>::isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
1359 {
1360  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
1361 }
1363 //*************************************************************************************************
1364 
1365 
1366 //*************************************************************************************************
1376 template< typename MT // Type of the dense matrix
1377  , bool SF > // Symmetry flag
1378 inline bool Column<MT,true,true,SF>::isAligned() const noexcept
1379 {
1380  return matrix_.isAligned();
1381 }
1383 //*************************************************************************************************
1384 
1385 
1386 //*************************************************************************************************
1397 template< typename MT // Type of the dense matrix
1398  , bool SF > // Symmetry flag
1399 inline bool Column<MT,true,true,SF>::canSMPAssign() const noexcept
1400 {
1401  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1402 }
1404 //*************************************************************************************************
1405 
1406 
1407 //*************************************************************************************************
1419 template< typename MT // Type of the dense matrix
1420  , bool SF > // Symmetry flag
1421 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF>::SIMDType
1422  Column<MT,true,true,SF>::load( size_t index ) const noexcept
1423 {
1424  return matrix_.load( index, col_ );
1425 }
1427 //*************************************************************************************************
1428 
1429 
1430 //*************************************************************************************************
1443 template< typename MT // Type of the dense matrix
1444  , bool SF > // Symmetry flag
1445 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF>::SIMDType
1446  Column<MT,true,true,SF>::loada( size_t index ) const noexcept
1447 {
1448  return matrix_.loada( index, col_ );
1449 }
1451 //*************************************************************************************************
1452 
1453 
1454 //*************************************************************************************************
1467 template< typename MT // Type of the dense matrix
1468  , bool SF > // Symmetry flag
1469 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF>::SIMDType
1470  Column<MT,true,true,SF>::loadu( size_t index ) const noexcept
1471 {
1472  return matrix_.loadu( index, col_ );
1473 }
1475 //*************************************************************************************************
1476 
1477 
1478 //*************************************************************************************************
1491 template< typename MT // Type of the dense matrix
1492  , bool SF > // Symmetry flag
1494  Column<MT,true,true,SF>::store( size_t index, const SIMDType& value ) noexcept
1495 {
1496  matrix_.store( index, col_, value );
1497 }
1499 //*************************************************************************************************
1500 
1501 
1502 //*************************************************************************************************
1516 template< typename MT // Type of the dense matrix
1517  , bool SF > // Symmetry flag
1519  Column<MT,true,true,SF>::storea( size_t index, const SIMDType& value ) noexcept
1520 {
1521  matrix_.storea( index, col_, value );
1522 }
1524 //*************************************************************************************************
1525 
1526 
1527 //*************************************************************************************************
1541 template< typename MT // Type of the dense matrix
1542  , bool SF > // Symmetry flag
1544  Column<MT,true,true,SF>::storeu( size_t index, const SIMDType& value ) noexcept
1545 {
1546  matrix_.storeu( index, col_, value );
1547 }
1549 //*************************************************************************************************
1550 
1551 
1552 //*************************************************************************************************
1566 template< typename MT // Type of the dense matrix
1567  , bool SF > // Symmetry flag
1569  Column<MT,true,true,SF>::stream( size_t index, const SIMDType& value ) noexcept
1570 {
1571  matrix_.stream( index, col_, value );
1572 }
1574 //*************************************************************************************************
1575 
1576 
1577 //*************************************************************************************************
1589 template< typename MT // Type of the dense matrix
1590  , bool SF > // Symmetry flag
1591 template< typename VT > // Type of the right-hand side dense vector
1592 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1593  Column<MT,true,true,SF>::assign( const DenseVector<VT,false>& rhs )
1594 {
1595  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1596 
1597  const size_t ipos( (~rhs).size() & size_t(-2) );
1598  for( size_t i=0UL; i<ipos; i+=2UL ) {
1599  matrix_(i ,col_) = (~rhs)[i ];
1600  matrix_(i+1UL,col_) = (~rhs)[i+1UL];
1601  }
1602  if( ipos < (~rhs).size() )
1603  matrix_(ipos,col_) = (~rhs)[ipos];
1604 }
1606 //*************************************************************************************************
1607 
1608 
1609 //*************************************************************************************************
1621 template< typename MT // Type of the dense matrix
1622  , bool SF > // Symmetry flag
1623 template< typename VT > // Type of the right-hand side dense vector
1624 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1625  Column<MT,true,true,SF>::assign( const DenseVector<VT,false>& rhs )
1626 {
1628 
1629  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1630 
1631  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1632  const size_t rows( size() );
1633 
1634  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1635  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1636 
1637  size_t i( 0UL );
1638  Iterator left( begin() );
1639  ConstIterator_<VT> right( (~rhs).begin() );
1640 
1641  if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
1642  {
1643  for( ; i<ipos; i+=SIMDSIZE ) {
1644  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1645  }
1646  for( ; remainder && i<rows; ++i ) {
1647  *left = *right; ++left; ++right;
1648  }
1649  }
1650  else
1651  {
1652  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1653  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1654  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1655  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1656  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1657  }
1658  for( ; i<ipos; i+=SIMDSIZE ) {
1659  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1660  }
1661  for( ; remainder && i<rows; ++i ) {
1662  *left = *right; ++left; ++right;
1663  }
1664  }
1665 }
1667 //*************************************************************************************************
1668 
1669 
1670 //*************************************************************************************************
1682 template< typename MT // Type of the dense matrix
1683  , bool SF > // Symmetry flag
1684 template< typename VT > // Type of the right-hand side sparse vector
1685 inline void Column<MT,true,true,SF>::assign( const SparseVector<VT,false>& rhs )
1686 {
1687  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1688 
1689  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1690  matrix_(element->index(),col_) = element->value();
1691 }
1693 //*************************************************************************************************
1694 
1695 
1696 //*************************************************************************************************
1708 template< typename MT // Type of the dense matrix
1709  , bool SF > // Symmetry flag
1710 template< typename VT > // Type of the right-hand side dense vector
1711 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1712  Column<MT,true,true,SF>::addAssign( const DenseVector<VT,false>& rhs )
1713 {
1714  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1715 
1716  const size_t ipos( (~rhs).size() & size_t(-2) );
1717  for( size_t i=0UL; i<ipos; i+=2UL ) {
1718  matrix_(i ,col_) += (~rhs)[i ];
1719  matrix_(i+1UL,col_) += (~rhs)[i+1UL];
1720  }
1721  if( ipos < (~rhs).size() )
1722  matrix_(ipos,col_) += (~rhs)[ipos];
1723 }
1725 //*************************************************************************************************
1726 
1727 
1728 //*************************************************************************************************
1740 template< typename MT // Type of the dense matrix
1741  , bool SF > // Symmetry flag
1742 template< typename VT > // Type of the right-hand side dense vector
1743 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1744  Column<MT,true,true,SF>::addAssign( const DenseVector<VT,false>& rhs )
1745 {
1747 
1748  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1749 
1750  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1751  const size_t rows( size() );
1752 
1753  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1754  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1755 
1756  size_t i( 0UL );
1757  Iterator left( begin() );
1758  ConstIterator_<VT> right( (~rhs).begin() );
1759 
1760  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1761  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1762  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1763  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1764  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1765  }
1766  for( ; i<ipos; i+=SIMDSIZE ) {
1767  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1768  }
1769  for( ; remainder && i<rows; ++i ) {
1770  *left += *right; ++left; ++right;
1771  }
1772 }
1774 //*************************************************************************************************
1775 
1776 
1777 //*************************************************************************************************
1789 template< typename MT // Type of the dense matrix
1790  , bool SF > // Symmetry flag
1791 template< typename VT > // Type of the right-hand side sparse vector
1792 inline void Column<MT,true,true,SF>::addAssign( const SparseVector<VT,false>& rhs )
1793 {
1794  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1795 
1796  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1797  matrix_(element->index(),col_) += element->value();
1798 }
1800 //*************************************************************************************************
1801 
1802 
1803 //*************************************************************************************************
1815 template< typename MT // Type of the dense matrix
1816  , bool SF > // Symmetry flag
1817 template< typename VT > // Type of the right-hand side dense vector
1818 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1819  Column<MT,true,true,SF>::subAssign( const DenseVector<VT,false>& rhs )
1820 {
1821  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1822 
1823  const size_t ipos( (~rhs).size() & size_t(-2) );
1824  for( size_t i=0UL; i<ipos; i+=2UL ) {
1825  matrix_(i ,col_) -= (~rhs)[i ];
1826  matrix_(i+1UL,col_) -= (~rhs)[i+1UL];
1827  }
1828  if( ipos < (~rhs).size() )
1829  matrix_(ipos,col_) -= (~rhs)[ipos];
1830 }
1832 //*************************************************************************************************
1833 
1834 
1835 //*************************************************************************************************
1847 template< typename MT // Type of the dense matrix
1848  , bool SF > // Symmetry flag
1849 template< typename VT > // Type of the right-hand side dense vector
1850 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1851  Column<MT,true,true,SF>::subAssign( const DenseVector<VT,false>& rhs )
1852 {
1854 
1855  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1856 
1857  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1858  const size_t rows( size() );
1859 
1860  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1861  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1862 
1863  size_t i( 0UL );
1864  Iterator left( begin() );
1865  ConstIterator_<VT> right( (~rhs).begin() );
1866 
1867  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1868  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1869  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1870  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1871  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1872  }
1873  for( ; i<ipos; i+=SIMDSIZE ) {
1874  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1875  }
1876  for( ; remainder && i<rows; ++i ) {
1877  *left -= *right; ++left; ++right;
1878  }
1879 }
1881 //*************************************************************************************************
1882 
1883 
1884 //*************************************************************************************************
1896 template< typename MT // Type of the dense matrix
1897  , bool SF > // Symmetry flag
1898 template< typename VT > // Type of the right-hand side sparse vector
1899 inline void Column<MT,true,true,SF>::subAssign( const SparseVector<VT,false>& rhs )
1900 {
1901  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1902 
1903  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1904  matrix_(element->index(),col_) -= element->value();
1905 }
1907 //*************************************************************************************************
1908 
1909 
1910 //*************************************************************************************************
1922 template< typename MT // Type of the dense matrix
1923  , bool SF > // Symmetry flag
1924 template< typename VT > // Type of the right-hand side dense vector
1925 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
1926  Column<MT,true,true,SF>::multAssign( const DenseVector<VT,false>& rhs )
1927 {
1928  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1929 
1930  const size_t ipos( (~rhs).size() & size_t(-2) );
1931  for( size_t i=0UL; i<ipos; i+=2UL ) {
1932  matrix_(i ,col_) *= (~rhs)[i ];
1933  matrix_(i+1UL,col_) *= (~rhs)[i+1UL];
1934  }
1935  if( ipos < (~rhs).size() )
1936  matrix_(ipos,col_) *= (~rhs)[ipos];
1937 }
1939 //*************************************************************************************************
1940 
1941 
1942 //*************************************************************************************************
1954 template< typename MT // Type of the dense matrix
1955  , bool SF > // Symmetry flag
1956 template< typename VT > // Type of the right-hand side dense vector
1957 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
1958  Column<MT,true,true,SF>::multAssign( const DenseVector<VT,false>& rhs )
1959 {
1961 
1962  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1963 
1964  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1965  const size_t rows( size() );
1966 
1967  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1968  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1969 
1970  size_t i( 0UL );
1971  Iterator left( begin() );
1972  ConstIterator_<VT> right( (~rhs).begin() );
1973 
1974  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1975  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1976  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1977  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1978  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1979  }
1980  for( ; i<ipos; i+=SIMDSIZE ) {
1981  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1982  }
1983  for( ; remainder && i<rows; ++i ) {
1984  *left *= *right; ++left, ++right;
1985  }
1986 }
1988 //*************************************************************************************************
1989 
1990 
1991 //*************************************************************************************************
2003 template< typename MT // Type of the dense matrix
2004  , bool SF > // Symmetry flag
2005 template< typename VT > // Type of the right-hand side sparse vector
2006 inline void Column<MT,true,true,SF>::multAssign( const SparseVector<VT,false>& rhs )
2007 {
2008  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2009 
2010  const ResultType tmp( serial( *this ) );
2011 
2012  reset();
2013 
2014  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2015  matrix_(element->index(),col_) = tmp[element->index()] * element->value();
2016 }
2018 //*************************************************************************************************
2019 
2020 
2021 //*************************************************************************************************
2033 template< typename MT // Type of the dense matrix
2034  , bool SF > // Symmetry flag
2035 template< typename VT > // Type of the right-hand side dense vector
2036 inline DisableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2037  Column<MT,true,true,SF>::divAssign( const DenseVector<VT,false>& rhs )
2038 {
2039  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2040 
2041  const size_t ipos( (~rhs).size() & size_t(-2) );
2042  for( size_t i=0UL; i<ipos; i+=2UL ) {
2043  matrix_(i ,col_) /= (~rhs)[i ];
2044  matrix_(i+1UL,col_) /= (~rhs)[i+1UL];
2045  }
2046  if( ipos < (~rhs).size() )
2047  matrix_(ipos,col_) /= (~rhs)[ipos];
2048 }
2050 //*************************************************************************************************
2051 
2052 
2053 //*************************************************************************************************
2065 template< typename MT // Type of the dense matrix
2066  , bool SF > // Symmetry flag
2067 template< typename VT > // Type of the right-hand side dense vector
2068 inline EnableIf_< typename Column<MT,true,true,SF>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2069  Column<MT,true,true,SF>::divAssign( const DenseVector<VT,false>& rhs )
2070 {
2072 
2073  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2074 
2075  const size_t rows( size() );
2076 
2077  const size_t ipos( rows & size_t(-SIMDSIZE) );
2078  BLAZE_INTERNAL_ASSERT( ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2079 
2080  size_t i( 0UL );
2081  Iterator left( begin() );
2082  ConstIterator_<VT> right( (~rhs).begin() );
2083 
2084  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2085  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2086  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2087  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2088  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2089  }
2090  for( ; i<ipos; i+=SIMDSIZE ) {
2091  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2092  }
2093  for( ; i<rows; ++i ) {
2094  *left /= *right; ++left; ++right;
2095  }
2096 }
2098 //*************************************************************************************************
2099 
2100 
2101 
2102 
2103 
2104 
2105 
2106 
2107 //=================================================================================================
2108 //
2109 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
2110 //
2111 //=================================================================================================
2112 
2113 //*************************************************************************************************
2121 template< typename MT > // Type of the dense matrix
2122 class Column<MT,false,true,false>
2123  : public DenseVector< Column<MT,false,true,false>, false >
2124  , private View
2125 {
2126  private:
2127  //**Type definitions****************************************************************************
2129  typedef If_< IsExpression<MT>, MT, MT& > Operand;
2130  //**********************************************************************************************
2131 
2132  public:
2133  //**Type definitions****************************************************************************
2134  typedef Column<MT,false,true,false> This;
2135  typedef DenseVector<This,false> BaseType;
2136  typedef ColumnTrait_<MT> ResultType;
2137  typedef TransposeType_<ResultType> TransposeType;
2138  typedef ElementType_<MT> ElementType;
2139  typedef ReturnType_<MT> ReturnType;
2140  typedef const Column& CompositeType;
2141 
2143  typedef ConstReference_<MT> ConstReference;
2144 
2146  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
2147 
2149  typedef const ElementType* ConstPointer;
2150 
2152  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
2153  //**********************************************************************************************
2154 
2155  //**ColumnIterator class definition*************************************************************
2158  template< typename MatrixType > // Type of the dense matrix
2159  class ColumnIterator
2160  {
2161  public:
2162  //**Type definitions*************************************************************************
2164  typedef If_< IsConst<MatrixType>, ConstReference_<MatrixType>, Reference_<MatrixType> > Reference;
2165 
2166  typedef std::random_access_iterator_tag IteratorCategory;
2167  typedef RemoveReference_<Reference> ValueType;
2168  typedef ValueType* PointerType;
2169  typedef Reference ReferenceType;
2170  typedef ptrdiff_t DifferenceType;
2171 
2172  // STL iterator requirements
2173  typedef IteratorCategory iterator_category;
2174  typedef ValueType value_type;
2175  typedef PointerType pointer;
2176  typedef ReferenceType reference;
2177  typedef DifferenceType difference_type;
2178  //*******************************************************************************************
2179 
2180  //**Constructor******************************************************************************
2183  inline ColumnIterator() noexcept
2184  : matrix_( nullptr ) // The dense matrix containing the column.
2185  , row_ ( 0UL ) // The current row index.
2186  , column_( 0UL ) // The current column index.
2187  {}
2188  //*******************************************************************************************
2189 
2190  //**Constructor******************************************************************************
2197  inline ColumnIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2198  : matrix_( &matrix ) // The dense matrix containing the column.
2199  , row_ ( row ) // The current row index.
2200  , column_( column ) // The current column index.
2201  {}
2202  //*******************************************************************************************
2203 
2204  //**Constructor******************************************************************************
2209  template< typename MatrixType2 >
2210  inline ColumnIterator( const ColumnIterator<MatrixType2>& it ) noexcept
2211  : matrix_( it.matrix_ ) // The dense matrix containing the column.
2212  , row_ ( it.row_ ) // The current row index.
2213  , column_( it.column_ ) // The current column index.
2214  {}
2215  //*******************************************************************************************
2216 
2217  //**Addition assignment operator*************************************************************
2223  inline ColumnIterator& operator+=( size_t inc ) noexcept {
2224  row_ += inc;
2225  return *this;
2226  }
2227  //*******************************************************************************************
2228 
2229  //**Subtraction assignment operator**********************************************************
2235  inline ColumnIterator& operator-=( size_t dec ) noexcept {
2236  row_ -= dec;
2237  return *this;
2238  }
2239  //*******************************************************************************************
2240 
2241  //**Prefix increment operator****************************************************************
2246  inline ColumnIterator& operator++() noexcept {
2247  ++row_;
2248  return *this;
2249  }
2250  //*******************************************************************************************
2251 
2252  //**Postfix increment operator***************************************************************
2257  inline const ColumnIterator operator++( int ) noexcept {
2258  const ColumnIterator tmp( *this );
2259  ++(*this);
2260  return tmp;
2261  }
2262  //*******************************************************************************************
2263 
2264  //**Prefix decrement operator****************************************************************
2269  inline ColumnIterator& operator--() noexcept {
2270  --row_;
2271  return *this;
2272  }
2273  //*******************************************************************************************
2274 
2275  //**Postfix decrement operator***************************************************************
2280  inline const ColumnIterator operator--( int ) noexcept {
2281  const ColumnIterator tmp( *this );
2282  --(*this);
2283  return tmp;
2284  }
2285  //*******************************************************************************************
2286 
2287  //**Subscript operator***********************************************************************
2293  inline ReferenceType operator[]( size_t index ) const {
2294  return (*matrix_)(row_+index,column_);
2295  }
2296  //*******************************************************************************************
2297 
2298  //**Element access operator******************************************************************
2303  inline ReferenceType operator*() const {
2304  return (*matrix_)(row_,column_);
2305  }
2306  //*******************************************************************************************
2307 
2308  //**Element access operator******************************************************************
2313  inline PointerType operator->() const {
2314  return &(*matrix_)(row_,column_);
2315  }
2316  //*******************************************************************************************
2317 
2318  //**Equality operator************************************************************************
2324  template< typename MatrixType2 >
2325  inline bool operator==( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2326  return ( matrix_ == rhs.matrix_ ) && ( row_ == rhs.row_ ) && ( column_ == rhs.column_ );
2327  }
2328  //*******************************************************************************************
2329 
2330  //**Inequality operator**********************************************************************
2336  template< typename MatrixType2 >
2337  inline bool operator!=( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2338  return !( *this == rhs );
2339  }
2340  //*******************************************************************************************
2341 
2342  //**Less-than operator***********************************************************************
2348  template< typename MatrixType2 >
2349  inline bool operator<( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2350  return ( matrix_ == rhs.matrix_ ) && ( row_ < rhs.row_ ) && ( column_ == rhs.column_ );
2351  }
2352  //*******************************************************************************************
2353 
2354  //**Greater-than operator********************************************************************
2360  template< typename MatrixType2 >
2361  inline bool operator>( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2362  return ( matrix_ == rhs.matrix_ ) && ( row_ > rhs.row_ ) && ( column_ == rhs.column_ );
2363  }
2364  //*******************************************************************************************
2365 
2366  //**Less-or-equal-than operator**************************************************************
2372  template< typename MatrixType2 >
2373  inline bool operator<=( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2374  return ( matrix_ == rhs.matrix_ ) && ( row_ <= rhs.row_ ) && ( column_ == rhs.column_ );
2375  }
2376  //*******************************************************************************************
2377 
2378  //**Greater-or-equal-than operator***********************************************************
2384  template< typename MatrixType2 >
2385  inline bool operator>=( const ColumnIterator<MatrixType2>& rhs ) const noexcept {
2386  return ( matrix_ == rhs.matrix_ ) && ( row_ >= rhs.row_ ) && ( column_ == rhs.column_ );
2387  }
2388  //*******************************************************************************************
2389 
2390  //**Subtraction operator*********************************************************************
2396  inline DifferenceType operator-( const ColumnIterator& rhs ) const noexcept {
2397  return row_ - rhs.row_;
2398  }
2399  //*******************************************************************************************
2400 
2401  //**Addition operator************************************************************************
2408  friend inline const ColumnIterator operator+( const ColumnIterator& it, size_t inc ) noexcept {
2409  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2410  }
2411  //*******************************************************************************************
2412 
2413  //**Addition operator************************************************************************
2420  friend inline const ColumnIterator operator+( size_t inc, const ColumnIterator& it ) noexcept {
2421  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2422  }
2423  //*******************************************************************************************
2424 
2425  //**Subtraction operator*********************************************************************
2432  friend inline const ColumnIterator operator-( const ColumnIterator& it, size_t dec ) noexcept {
2433  return ColumnIterator( *it.matrix_, it.row_-dec, it.column_ );
2434  }
2435  //*******************************************************************************************
2436 
2437  private:
2438  //**Member variables*************************************************************************
2439  MatrixType* matrix_;
2440  size_t row_;
2441  size_t column_;
2442  //*******************************************************************************************
2443 
2444  //**Friend declarations**********************************************************************
2445  template< typename MatrixType2 > friend class ColumnIterator;
2446  //*******************************************************************************************
2447  };
2448  //**********************************************************************************************
2449 
2450  //**Type definitions****************************************************************************
2452  typedef ColumnIterator<const MT> ConstIterator;
2453 
2455  typedef If_< IsConst<MT>, ConstIterator, ColumnIterator<MT> > Iterator;
2456  //**********************************************************************************************
2457 
2458  //**Compilation flags***************************************************************************
2460  enum : bool { simdEnabled = false };
2461 
2463  enum : bool { smpAssignable = MT::smpAssignable };
2464  //**********************************************************************************************
2465 
2466  //**Constructors********************************************************************************
2469  explicit inline Column( Operand matrix, size_t index );
2470  // No explicitly declared copy constructor.
2472  //**********************************************************************************************
2473 
2474  //**Destructor**********************************************************************************
2475  // No explicitly declared destructor.
2476  //**********************************************************************************************
2477 
2478  //**Data access functions***********************************************************************
2481  inline Reference operator[]( size_t index );
2482  inline ConstReference operator[]( size_t index ) const;
2483  inline Reference at( size_t index );
2484  inline ConstReference at( size_t index ) const;
2485  inline Pointer data () noexcept;
2486  inline ConstPointer data () const noexcept;
2487  inline Iterator begin ();
2488  inline ConstIterator begin () const;
2489  inline ConstIterator cbegin() const;
2490  inline Iterator end ();
2491  inline ConstIterator end () const;
2492  inline ConstIterator cend () const;
2494  //**********************************************************************************************
2495 
2496  //**Assignment operators************************************************************************
2499  inline Column& operator=( const ElementType& rhs );
2500  inline Column& operator=( initializer_list<ElementType> list );
2501  inline Column& operator=( const Column& rhs );
2502 
2503  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
2504  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
2505  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
2506  template< typename VT > inline Column& operator*=( const DenseVector<VT,false>& rhs );
2507  template< typename VT > inline Column& operator*=( const SparseVector<VT,false>& rhs );
2508  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
2509 
2510  template< typename Other >
2511  inline EnableIf_< IsNumeric<Other>, Column >& operator*=( Other rhs );
2512 
2513  template< typename Other >
2514  inline EnableIf_< IsNumeric<Other>, Column >& operator/=( Other rhs );
2516  //**********************************************************************************************
2517 
2518  //**Utility functions***************************************************************************
2521  inline size_t size() const noexcept;
2522  inline size_t capacity() const noexcept;
2523  inline size_t nonZeros() const;
2524  inline void reset();
2525  template< typename Other > inline Column& scale( const Other& scalar );
2527  //**********************************************************************************************
2528 
2529  public:
2530  //**Expression template evaluation functions****************************************************
2533  template< typename Other >
2534  inline bool canAlias ( const Other* alias ) const noexcept;
2535 
2536  template< typename MT2, bool SO2, bool SF2 >
2537  inline bool canAlias ( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
2538 
2539  template< typename Other >
2540  inline bool isAliased( const Other* alias ) const noexcept;
2541 
2542  template< typename MT2, bool SO2, bool SF2 >
2543  inline bool isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
2544 
2545  inline bool isAligned () const noexcept;
2546  inline bool canSMPAssign() const noexcept;
2547 
2548  template< typename VT > inline void assign ( const DenseVector <VT,false>& rhs );
2549  template< typename VT > inline void assign ( const SparseVector<VT,false>& rhs );
2550  template< typename VT > inline void addAssign ( const DenseVector <VT,false>& rhs );
2551  template< typename VT > inline void addAssign ( const SparseVector<VT,false>& rhs );
2552  template< typename VT > inline void subAssign ( const DenseVector <VT,false>& rhs );
2553  template< typename VT > inline void subAssign ( const SparseVector<VT,false>& rhs );
2554  template< typename VT > inline void multAssign( const DenseVector <VT,false>& rhs );
2555  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
2556  template< typename VT > inline void divAssign ( const DenseVector <VT,false>& rhs );
2558  //**********************************************************************************************
2559 
2560  private:
2561  //**Member variables****************************************************************************
2564  Operand matrix_;
2565  const size_t col_;
2566 
2567  //**********************************************************************************************
2568 
2569  //**Friend declarations*************************************************************************
2570  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Column;
2571 
2572  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2573  friend bool isIntact( const Column<MT2,SO2,DF2,SF2>& column ) noexcept;
2574 
2575  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2576  friend bool isSame( const Column<MT2,SO2,DF2,SF2>& a, const Column<MT2,SO2,DF2,SF2>& b ) noexcept;
2577 
2578  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2579  friend bool tryAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2580 
2581  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2582  friend bool tryAddAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2583 
2584  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2585  friend bool trySubAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2586 
2587  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2588  friend bool tryMultAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2589 
2590  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
2591  friend bool tryDivAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
2592 
2593  template< typename MT2, bool SO2, bool DF2, bool SF2 >
2594  friend DerestrictTrait_< Column<MT2,SO2,DF2,SF2> > derestrict( Column<MT2,SO2,DF2,SF2>& column );
2595  //**********************************************************************************************
2596 
2597  //**Compile time checks*************************************************************************
2605  //**********************************************************************************************
2606 };
2608 //*************************************************************************************************
2609 
2610 
2611 
2612 
2613 //=================================================================================================
2614 //
2615 // CONSTRUCTOR
2616 //
2617 //=================================================================================================
2618 
2619 //*************************************************************************************************
2627 template< typename MT > // Type of the dense matrix
2628 inline Column<MT,false,true,false>::Column( Operand matrix, size_t index )
2629  : matrix_( matrix ) // The dense matrix containing the column
2630  , col_ ( index ) // The index of the column in the matrix
2631 {
2632  if( matrix_.columns() <= index ) {
2633  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2634  }
2635 }
2637 //*************************************************************************************************
2638 
2639 
2640 
2641 
2642 //=================================================================================================
2643 //
2644 // DATA ACCESS FUNCTIONS
2645 //
2646 //=================================================================================================
2647 
2648 //*************************************************************************************************
2658 template< typename MT > // Type of the dense matrix
2660  Column<MT,false,true,false>::operator[]( size_t index )
2661 {
2662  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2663  return matrix_(index,col_);
2664 }
2666 //*************************************************************************************************
2667 
2668 
2669 //*************************************************************************************************
2679 template< typename MT > // Type of the dense matrix
2681  Column<MT,false,true,false>::operator[]( size_t index ) const
2682 {
2683  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2684  return const_cast<const MT&>( matrix_ )(index,col_);
2685 }
2687 //*************************************************************************************************
2688 
2689 
2690 //*************************************************************************************************
2701 template< typename MT > // Type of the dense matrix
2703  Column<MT,false,true,false>::at( size_t index )
2704 {
2705  if( index >= size() ) {
2706  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2707  }
2708  return (*this)[index];
2709 }
2711 //*************************************************************************************************
2712 
2713 
2714 //*************************************************************************************************
2725 template< typename MT > // Type of the dense matrix
2727  Column<MT,false,true,false>::at( size_t index ) const
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 //*************************************************************************************************
2747 template< typename MT > // Type of the dense matrix
2748 inline typename Column<MT,false,true,false>::Pointer Column<MT,false,true,false>::data() noexcept
2749 {
2750  return matrix_.data() + col_;
2751 }
2753 //*************************************************************************************************
2754 
2755 
2756 //*************************************************************************************************
2765 template< typename MT > // Type of the dense matrix
2766 inline typename Column<MT,false,true,false>::ConstPointer Column<MT,false,true,false>::data() const noexcept
2767 {
2768  return matrix_.data() + col_;
2769 }
2771 //*************************************************************************************************
2772 
2773 
2774 //*************************************************************************************************
2782 template< typename MT > // Type of the dense matrix
2784 {
2785  return Iterator( matrix_, 0UL, col_ );
2786 }
2788 //*************************************************************************************************
2789 
2790 
2791 //*************************************************************************************************
2799 template< typename MT > // Type of the dense matrix
2802 {
2803  return ConstIterator( matrix_, 0UL, col_ );
2804 }
2806 //*************************************************************************************************
2807 
2808 
2809 //*************************************************************************************************
2817 template< typename MT > // Type of the dense matrix
2820 {
2821  return ConstIterator( matrix_, 0UL, col_ );
2822 }
2824 //*************************************************************************************************
2825 
2826 
2827 //*************************************************************************************************
2835 template< typename MT > // Type of the dense matrix
2837 {
2838  return Iterator( matrix_, size(), col_ );
2839 }
2841 //*************************************************************************************************
2842 
2843 
2844 //*************************************************************************************************
2852 template< typename MT > // Type of the dense matrix
2855 {
2856  return ConstIterator( matrix_, size(), col_ );
2857 }
2859 //*************************************************************************************************
2860 
2861 
2862 //*************************************************************************************************
2870 template< typename MT > // Type of the dense matrix
2873 {
2874  return ConstIterator( matrix_, size(), col_ );
2875 }
2877 //*************************************************************************************************
2878 
2879 
2880 
2881 
2882 //=================================================================================================
2883 //
2884 // ASSIGNMENT OPERATORS
2885 //
2886 //=================================================================================================
2887 
2888 //*************************************************************************************************
2899 template< typename MT > // Type of the dense matrix
2900 inline Column<MT,false,true,false>&
2901  Column<MT,false,true,false>::operator=( const ElementType& rhs )
2902 {
2903  const size_t ibegin( ( IsLower<MT>::value )
2904  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
2905  ?( col_+1UL )
2906  :( col_ ) )
2907  :( 0UL ) );
2908  const size_t iend ( ( IsUpper<MT>::value )
2909  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
2910  ?( col_ )
2911  :( col_+1UL ) )
2912  :( size() ) );
2913 
2914  for( size_t i=ibegin; i<iend; ++i )
2915  matrix_(i,col_) = rhs;
2916 
2917  return *this;
2918 }
2920 //*************************************************************************************************
2921 
2922 
2923 //*************************************************************************************************
2936 template< typename MT > // Type of the dense matrix
2937 inline Column<MT,false,true,false>&
2938  Column<MT,false,true,false>::operator=( initializer_list<ElementType> list )
2939 {
2940  if( list.size() > size() ) {
2941  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
2942  }
2943 
2944  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
2945 
2946  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2947 
2948  return *this;
2949 }
2951 //*************************************************************************************************
2952 
2953 
2954 //*************************************************************************************************
2968 template< typename MT > // Type of the dense matrix
2969 inline Column<MT,false,true,false>&
2970  Column<MT,false,true,false>::operator=( const Column& rhs )
2971 {
2972  if( &rhs == this ) return *this;
2973 
2974  if( size() != rhs.size() ) {
2975  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
2976  }
2977 
2978  if( !tryAssign( matrix_, rhs, 0UL, col_ ) ) {
2979  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
2980  }
2981 
2982  DerestrictTrait_<This> left( derestrict( *this ) );
2983 
2984  smpAssign( left, rhs );
2985 
2986  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
2987 
2988  return *this;
2989 }
2991 //*************************************************************************************************
2992 
2993 
2994 //*************************************************************************************************
3008 template< typename MT > // Type of the dense matrix
3009 template< typename VT > // Type of the right-hand side vector
3010 inline Column<MT,false,true,false>&
3011  Column<MT,false,true,false>::operator=( const Vector<VT,false>& rhs )
3012 {
3016 
3017  if( size() != (~rhs).size() ) {
3018  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3019  }
3020 
3021  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3022  Right right( ~rhs );
3023 
3024  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
3025  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3026  }
3027 
3028  DerestrictTrait_<This> left( derestrict( *this ) );
3029 
3030  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3031  const ResultType tmp( right );
3032  smpAssign( left, tmp );
3033  }
3034  else {
3035  if( IsSparseVector<VT>::value )
3036  reset();
3037  smpAssign( left, right );
3038  }
3039 
3040  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3041 
3042  return *this;
3043 }
3045 //*************************************************************************************************
3046 
3047 
3048 //*************************************************************************************************
3062 template< typename MT > // Type of the dense matrix
3063 template< typename VT > // Type of the right-hand side vector
3064 inline Column<MT,false,true,false>&
3065  Column<MT,false,true,false>::operator+=( const Vector<VT,false>& rhs )
3066 {
3067  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3069 
3070  if( size() != (~rhs).size() ) {
3071  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3072  }
3073 
3074  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3075  Right right( ~rhs );
3076 
3077  if( !tryAddAssign( matrix_, right, 0UL, col_ ) ) {
3078  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3079  }
3080 
3081  DerestrictTrait_<This> left( derestrict( *this ) );
3082 
3083  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3084  const ResultType_<VT> tmp( right );
3085  smpAddAssign( left, tmp );
3086  }
3087  else {
3088  smpAddAssign( left, right );
3089  }
3090 
3091  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3092 
3093  return *this;
3094 }
3096 //*************************************************************************************************
3097 
3098 
3099 //*************************************************************************************************
3113 template< typename MT > // Type of the dense matrix
3114 template< typename VT > // Type of the right-hand side vector
3115 inline Column<MT,false,true,false>&
3116  Column<MT,false,true,false>::operator-=( const Vector<VT,false>& rhs )
3117 {
3118  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3120 
3121  if( size() != (~rhs).size() ) {
3122  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3123  }
3124 
3125  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3126  Right right( ~rhs );
3127 
3128  if( !trySubAssign( matrix_, right, 0UL, col_ ) ) {
3129  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3130  }
3131 
3132  DerestrictTrait_<This> left( derestrict( *this ) );
3133 
3134  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3135  const ResultType_<VT> tmp( right );
3136  smpSubAssign( left, tmp );
3137  }
3138  else {
3139  smpSubAssign( left, right );
3140  }
3141 
3142  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3143 
3144  return *this;
3145 }
3147 //*************************************************************************************************
3148 
3149 
3150 //*************************************************************************************************
3163 template< typename MT > // Type of the dense matrix
3164 template< typename VT > // Type of the right-hand side dense vector
3165 inline Column<MT,false,true,false>&
3166  Column<MT,false,true,false>::operator*=( const DenseVector<VT,false>& rhs )
3167 {
3168  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3170 
3171  if( size() != (~rhs).size() ) {
3172  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3173  }
3174 
3175  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3176  Right right( ~rhs );
3177 
3178  if( !tryMultAssign( matrix_, right, 0UL, col_ ) ) {
3179  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3180  }
3181 
3182  DerestrictTrait_<This> left( derestrict( *this ) );
3183 
3184  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3185  const ResultType_<VT> tmp( right );
3186  smpMultAssign( left, tmp );
3187  }
3188  else {
3189  smpMultAssign( left, right );
3190  }
3191 
3192  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3193 
3194  return *this;
3195 }
3197 //*************************************************************************************************
3198 
3199 
3200 //*************************************************************************************************
3213 template< typename MT > // Type of the dense matrix
3214 template< typename VT > // Type of the right-hand side sparse vector
3215 inline Column<MT,false,true,false>&
3216  Column<MT,false,true,false>::operator*=( const SparseVector<VT,false>& rhs )
3217 {
3221 
3222  if( size() != (~rhs).size() ) {
3223  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3224  }
3225 
3226  const ResultType right( *this * (~rhs) );
3227 
3228  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
3229  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3230  }
3231 
3232  DerestrictTrait_<This> left( derestrict( *this ) );
3233 
3234  smpAssign( left, right );
3235 
3236  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3237 
3238  return *this;
3239 }
3241 //*************************************************************************************************
3242 
3243 
3244 //*************************************************************************************************
3256 template< typename MT > // Type of the dense matrix
3257 template< typename VT > // Type of the right-hand side dense vector
3258 inline Column<MT,false,true,false>&
3259  Column<MT,false,true,false>::operator/=( const DenseVector<VT,false>& rhs )
3260 {
3261  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3263 
3264  if( size() != (~rhs).size() ) {
3265  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3266  }
3267 
3268  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
3269  Right right( ~rhs );
3270 
3271  if( !tryDivAssign( matrix_, right, 0UL, col_ ) ) {
3272  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3273  }
3274 
3275  DerestrictTrait_<This> left( derestrict( *this ) );
3276 
3277  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3278  const ResultType_<VT> tmp( right );
3279  smpDivAssign( left, tmp );
3280  }
3281  else {
3282  smpDivAssign( left, right );
3283  }
3284 
3285  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3286 
3287  return *this;
3288 }
3290 //*************************************************************************************************
3291 
3292 
3293 //*************************************************************************************************
3304 template< typename MT > // Type of the dense matrix
3305 template< typename Other > // Data type of the right-hand side scalar
3306 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,false> >&
3308 {
3310 
3311  return operator=( (*this) * rhs );
3312 }
3314 //*************************************************************************************************
3315 
3316 
3317 //*************************************************************************************************
3330 template< typename MT > // Type of the dense matrix
3331 template< typename Other > // Data type of the right-hand side scalar
3332 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,false> >&
3334 {
3336 
3337  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
3338 
3339  return operator=( (*this) / rhs );
3340 }
3342 //*************************************************************************************************
3343 
3344 
3345 
3346 
3347 //=================================================================================================
3348 //
3349 // UTILITY FUNCTIONS
3350 //
3351 //=================================================================================================
3352 
3353 //*************************************************************************************************
3359 template< typename MT > // Type of the dense matrix
3360 inline size_t Column<MT,false,true,false>::size() const noexcept
3361 {
3362  return matrix_.rows();
3363 }
3365 //*************************************************************************************************
3366 
3367 
3368 //*************************************************************************************************
3374 template< typename MT > // Type of the dense matrix
3375 inline size_t Column<MT,false,true,false>::capacity() const noexcept
3376 {
3377  return matrix_.rows();
3378 }
3380 //*************************************************************************************************
3381 
3382 
3383 //*************************************************************************************************
3392 template< typename MT > // Type of the dense matrix
3393 inline size_t Column<MT,false,true,false>::nonZeros() const
3394 {
3395  const size_t rows( size() );
3396  size_t nonzeros( 0UL );
3397 
3398  for( size_t i=0UL; i<rows; ++i )
3399  if( !isDefault( matrix_(i,col_) ) )
3400  ++nonzeros;
3401 
3402  return nonzeros;
3403 }
3405 //*************************************************************************************************
3406 
3407 
3408 //*************************************************************************************************
3414 template< typename MT > // Type of the dense matrix
3416 {
3417  using blaze::clear;
3418 
3419  const size_t ibegin( ( IsLower<MT>::value )
3420  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3421  ?( col_+1UL )
3422  :( col_ ) )
3423  :( 0UL ) );
3424  const size_t iend ( ( IsUpper<MT>::value )
3425  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3426  ?( col_ )
3427  :( col_+1UL ) )
3428  :( size() ) );
3429 
3430  for( size_t i=ibegin; i<iend; ++i )
3431  clear( matrix_(i,col_) );
3432 }
3434 //*************************************************************************************************
3435 
3436 
3437 //*************************************************************************************************
3448 template< typename MT > // Type of the dense matrix
3449 template< typename Other > // Data type of the scalar value
3450 inline Column<MT,false,true,false>& Column<MT,false,true,false>::scale( const Other& scalar )
3451 {
3453 
3454  const size_t ibegin( ( IsLower<MT>::value )
3455  ?( ( IsStrictlyLower<MT>::value )
3456  ?( col_+1UL )
3457  :( col_ ) )
3458  :( 0UL ) );
3459  const size_t iend ( ( IsUpper<MT>::value )
3460  ?( ( IsStrictlyUpper<MT>::value )
3461  ?( col_ )
3462  :( col_+1UL ) )
3463  :( size() ) );
3464 
3465  for( size_t i=ibegin; i<iend; ++i ) {
3466  matrix_(i,col_) *= scalar;
3467  }
3468 
3469  return *this;
3470 }
3472 //*************************************************************************************************
3473 
3474 
3475 
3476 
3477 //=================================================================================================
3478 //
3479 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3480 //
3481 //=================================================================================================
3482 
3483 //*************************************************************************************************
3494 template< typename MT > // Type of the dense matrix
3495 template< typename Other > // Data type of the foreign expression
3496 inline bool Column<MT,false,true,false>::canAlias( const Other* alias ) const noexcept
3497 {
3498  return matrix_.isAliased( alias );
3499 }
3501 //*************************************************************************************************
3502 
3503 
3504 //*************************************************************************************************
3515 template< typename MT > // Type of the dense matrix
3516 template< typename MT2 // Data type of the foreign dense column
3517  , bool SO2 // Storage order of the foreign dense column
3518  , bool SF2 > // Symmetry flag of the foreign dense column
3519 inline bool Column<MT,false,true,false>::canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
3520 {
3521  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
3522 }
3524 //*************************************************************************************************
3525 
3526 
3527 //*************************************************************************************************
3538 template< typename MT > // Type of the dense matrix
3539 template< typename Other > // Data type of the foreign expression
3540 inline bool Column<MT,false,true,false>::isAliased( const Other* alias ) const noexcept
3541 {
3542  return matrix_.isAliased( alias );
3543 }
3545 //*************************************************************************************************
3546 
3547 
3548 //*************************************************************************************************
3559 template< typename MT > // Type of the dense matrix
3560 template< typename MT2 // Data type of the foreign dense column
3561  , bool SO2 // Storage order of the foreign dense column
3562  , bool SF2 > // Symmetry flag of the foreign dense column
3563 inline bool Column<MT,false,true,false>::isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
3564 {
3565  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
3566 }
3568 //*************************************************************************************************
3569 
3570 
3571 //*************************************************************************************************
3581 template< typename MT > // Type of the dense matrix
3582 inline bool Column<MT,false,true,false>::isAligned() const noexcept
3583 {
3584  return false;
3585 }
3587 //*************************************************************************************************
3588 
3589 
3590 //*************************************************************************************************
3601 template< typename MT > // Type of the dense matrix
3602 inline bool Column<MT,false,true,false>::canSMPAssign() const noexcept
3603 {
3604  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3605 }
3607 //*************************************************************************************************
3608 
3609 
3610 //*************************************************************************************************
3622 template< typename MT > // Type of the dense matrix
3623 template< typename VT > // Type of the right-hand side dense vector
3624 inline void Column<MT,false,true,false>::assign( const DenseVector<VT,false>& rhs )
3625 {
3626  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3627 
3628  const size_t ipos( (~rhs).size() & size_t(-2) );
3629  for( size_t i=0UL; i<ipos; i+=2UL ) {
3630  matrix_(i ,col_) = (~rhs)[i ];
3631  matrix_(i+1UL,col_) = (~rhs)[i+1UL];
3632  }
3633  if( ipos < (~rhs).size() )
3634  matrix_(ipos,col_) = (~rhs)[ipos];
3635 }
3637 //*************************************************************************************************
3638 
3639 
3640 //*************************************************************************************************
3652 template< typename MT > // Type of the dense matrix
3653 template< typename VT > // Type of the right-hand side sparse vector
3654 inline void Column<MT,false,true,false>::assign( const SparseVector<VT,false>& rhs )
3655 {
3656  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3657 
3658  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3659  matrix_(element->index(),col_) = element->value();
3660 }
3662 //*************************************************************************************************
3663 
3664 
3665 //*************************************************************************************************
3677 template< typename MT > // Type of the dense matrix
3678 template< typename VT > // Type of the right-hand side dense vector
3679 inline void Column<MT,false,true,false>::addAssign( const DenseVector<VT,false>& rhs )
3680 {
3681  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3682 
3683  const size_t ipos( (~rhs).size() & size_t(-2) );
3684  for( size_t i=0UL; i<ipos; i+=2UL ) {
3685  matrix_(i ,col_) += (~rhs)[i ];
3686  matrix_(i+1UL,col_) += (~rhs)[i+1UL];
3687  }
3688  if( ipos < (~rhs).size() )
3689  matrix_(ipos,col_) += (~rhs)[ipos];
3690 }
3692 //*************************************************************************************************
3693 
3694 
3695 //*************************************************************************************************
3707 template< typename MT > // Type of the dense matrix
3708 template< typename VT > // Type of the right-hand side sparse vector
3709 inline void Column<MT,false,true,false>::addAssign( const SparseVector<VT,false>& rhs )
3710 {
3711  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3712 
3713  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3714  matrix_(element->index(),col_) += element->value();
3715 }
3717 //*************************************************************************************************
3718 
3719 
3720 //*************************************************************************************************
3732 template< typename MT > // Type of the dense matrix
3733 template< typename VT > // Type of the right-hand side dense vector
3734 inline void Column<MT,false,true,false>::subAssign( const DenseVector<VT,false>& rhs )
3735 {
3736  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3737 
3738  const size_t ipos( (~rhs).size() & size_t(-2) );
3739  for( size_t i=0UL; i<ipos; i+=2UL ) {
3740  matrix_(i ,col_) -= (~rhs)[i ];
3741  matrix_(i+1UL,col_) -= (~rhs)[i+1UL];
3742  }
3743  if( ipos < (~rhs).size() )
3744  matrix_(ipos,col_) -= (~rhs)[ipos];
3745 }
3747 //*************************************************************************************************
3748 
3749 
3750 //*************************************************************************************************
3762 template< typename MT > // Type of the dense matrix
3763 template< typename VT > // Type of the right-hand side sparse vector
3764 inline void Column<MT,false,true,false>::subAssign( const SparseVector<VT,false>& rhs )
3765 {
3766  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3767 
3768  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3769  matrix_(element->index(),col_) -= element->value();
3770 }
3772 //*************************************************************************************************
3773 
3774 
3775 //*************************************************************************************************
3787 template< typename MT > // Type of the dense matrix
3788 template< typename VT > // Type of the right-hand side dense vector
3789 inline void Column<MT,false,true,false>::multAssign( const DenseVector<VT,false>& rhs )
3790 {
3791  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3792 
3793  const size_t ipos( (~rhs).size() & size_t(-2) );
3794  for( size_t i=0UL; i<ipos; i+=2UL ) {
3795  matrix_(i ,col_) *= (~rhs)[i ];
3796  matrix_(i+1UL,col_) *= (~rhs)[i+1UL];
3797  }
3798  if( ipos < (~rhs).size() )
3799  matrix_(ipos,col_) *= (~rhs)[ipos];
3800 }
3802 //*************************************************************************************************
3803 
3804 
3805 //*************************************************************************************************
3817 template< typename MT > // Type of the dense matrix
3818 template< typename VT > // Type of the right-hand side sparse vector
3819 inline void Column<MT,false,true,false>::multAssign( const SparseVector<VT,false>& rhs )
3820 {
3821  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3822 
3823  const ResultType tmp( serial( *this ) );
3824 
3825  reset();
3826 
3827  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3828  matrix_(element->index(),col_) = tmp[element->index()] * element->value();
3829 }
3831 //*************************************************************************************************
3832 
3833 
3834 //*************************************************************************************************
3846 template< typename MT > // Type of the dense matrix
3847 template< typename VT > // Type of the right-hand side dense vector
3848 inline void Column<MT,false,true,false>::divAssign( const DenseVector<VT,false>& rhs )
3849 {
3850  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3851 
3852  const size_t ipos( (~rhs).size() & size_t(-2) );
3853  for( size_t i=0UL; i<ipos; i+=2UL ) {
3854  matrix_(i ,col_) /= (~rhs)[i ];
3855  matrix_(i+1UL,col_) /= (~rhs)[i+1UL];
3856  }
3857  if( ipos < (~rhs).size() )
3858  matrix_(ipos,col_) /= (~rhs)[ipos];
3859 }
3861 //*************************************************************************************************
3862 
3863 
3864 
3865 
3866 
3867 
3868 
3869 
3870 //=================================================================================================
3871 //
3872 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
3873 //
3874 //=================================================================================================
3875 
3876 //*************************************************************************************************
3884 template< typename MT > // Type of the dense matrix
3885 class Column<MT,false,true,true>
3886  : public DenseVector< Column<MT,false,true,true>, false >
3887  , private View
3888 {
3889  private:
3890  //**Type definitions****************************************************************************
3892  typedef If_< IsExpression<MT>, MT, MT& > Operand;
3893  //**********************************************************************************************
3894 
3895  public:
3896  //**Type definitions****************************************************************************
3897  typedef Column<MT,false,true,true> This;
3898  typedef DenseVector<This,false> BaseType;
3899  typedef ColumnTrait_<MT> ResultType;
3900  typedef TransposeType_<ResultType> TransposeType;
3901  typedef ElementType_<MT> ElementType;
3902  typedef SIMDTrait_<ElementType> SIMDType;
3903  typedef ReturnType_<MT> ReturnType;
3904  typedef const Column& CompositeType;
3905 
3907  typedef ConstReference_<MT> ConstReference;
3908 
3910  typedef If_< IsConst<MT>, ConstReference, Reference_<MT> > Reference;
3911 
3913  typedef const ElementType* ConstPointer;
3914 
3916  typedef If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, ElementType* > Pointer;
3917 
3919  typedef ConstIterator_<MT> ConstIterator;
3920 
3922  typedef If_< IsConst<MT>, ConstIterator, Iterator_<MT> > Iterator;
3923  //**********************************************************************************************
3924 
3925  //**Compilation flags***************************************************************************
3927  enum : bool { simdEnabled = MT::simdEnabled };
3928 
3930  enum : bool { smpAssignable = MT::smpAssignable };
3931  //**********************************************************************************************
3932 
3933  //**Constructors********************************************************************************
3936  explicit inline Column( Operand matrix, size_t index );
3937  // No explicitly declared copy constructor.
3939  //**********************************************************************************************
3940 
3941  //**Destructor**********************************************************************************
3942  // No explicitly declared destructor.
3943  //**********************************************************************************************
3944 
3945  //**Data access functions***********************************************************************
3948  inline Reference operator[]( size_t index );
3949  inline ConstReference operator[]( size_t index ) const;
3950  inline Reference at( size_t index );
3951  inline ConstReference at( size_t index ) const;
3952  inline Pointer data () noexcept;
3953  inline ConstPointer data () const noexcept;
3954  inline Iterator begin ();
3955  inline ConstIterator begin () const;
3956  inline ConstIterator cbegin() const;
3957  inline Iterator end ();
3958  inline ConstIterator end () const;
3959  inline ConstIterator cend () const;
3961  //**********************************************************************************************
3962 
3963  //**Assignment operators************************************************************************
3966  inline Column& operator=( const ElementType& rhs );
3967  inline Column& operator=( initializer_list<ElementType> list );
3968  inline Column& operator=( const Column& rhs );
3969 
3970  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
3971  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
3972  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
3973  template< typename VT > inline Column& operator*=( const DenseVector<VT,false>& rhs );
3974  template< typename VT > inline Column& operator*=( const SparseVector<VT,false>& rhs );
3975  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
3976 
3977  template< typename Other >
3978  inline EnableIf_< IsNumeric<Other>, Column >& operator*=( Other rhs );
3979 
3980  template< typename Other >
3981  inline EnableIf_< IsNumeric<Other>, Column >& operator/=( Other rhs );
3983  //**********************************************************************************************
3984 
3985  //**Utility functions***************************************************************************
3988  inline size_t size() const noexcept;
3989  inline size_t capacity() const noexcept;
3990  inline size_t nonZeros() const;
3991  inline void reset();
3992  template< typename Other > inline Column& scale( const Other& scalar );
3994  //**********************************************************************************************
3995 
3996  private:
3997  //**********************************************************************************************
3999  template< typename VT >
4000  struct VectorizedAssign {
4001  enum : bool { value = useOptimizedKernels &&
4002  simdEnabled && VT::simdEnabled &&
4003  AreSIMDCombinable< ElementType, ElementType_<VT> >::value };
4004  };
4005  //**********************************************************************************************
4006 
4007  //**********************************************************************************************
4009  template< typename VT >
4010  struct VectorizedAddAssign {
4011  enum : bool { value = useOptimizedKernels &&
4012  simdEnabled && VT::simdEnabled &&
4013  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4014  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
4015  };
4016  //**********************************************************************************************
4017 
4018  //**********************************************************************************************
4020  template< typename VT >
4021  struct VectorizedSubAssign {
4022  enum : bool { value = useOptimizedKernels &&
4023  simdEnabled && VT::simdEnabled &&
4024  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4025  HasSIMDSub< ElementType, ElementType_<VT> >::value };
4026  };
4027  //**********************************************************************************************
4028 
4029  //**********************************************************************************************
4031  template< typename VT >
4032  struct VectorizedMultAssign {
4033  enum : bool { value = useOptimizedKernels &&
4034  simdEnabled && VT::simdEnabled &&
4035  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4036  HasSIMDMult< ElementType, ElementType_<VT> >::value };
4037  };
4038  //**********************************************************************************************
4039 
4040  //**********************************************************************************************
4042  template< typename VT >
4043  struct VectorizedDivAssign {
4044  enum : bool { value = useOptimizedKernels &&
4045  simdEnabled && VT::simdEnabled &&
4046  AreSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4047  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
4048  };
4049  //**********************************************************************************************
4050 
4051  //**SIMD properties*****************************************************************************
4053  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
4054  //**********************************************************************************************
4055 
4056  public:
4057  //**Expression template evaluation functions****************************************************
4060  template< typename Other >
4061  inline bool canAlias( const Other* alias ) const noexcept;
4062 
4063  template< typename MT2, bool SO2, bool SF2 >
4064  inline bool canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
4065 
4066  template< typename Other >
4067  inline bool isAliased( const Other* alias ) const noexcept;
4068 
4069  template< typename MT2, bool SO2, bool SF2 >
4070  inline bool isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept;
4071 
4072  inline bool isAligned () const noexcept;
4073  inline bool canSMPAssign() const noexcept;
4074 
4075  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4076  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4077  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4078 
4079  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4080  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4081  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4082  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4083 
4084  template< typename VT >
4085  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
4086 
4087  template< typename VT >
4088  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
4089 
4090  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
4091 
4092  template< typename VT >
4093  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
4094 
4095  template< typename VT >
4096  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
4097 
4098  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
4099 
4100  template< typename VT >
4101  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
4102 
4103  template< typename VT >
4104  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
4105 
4106  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
4107 
4108  template< typename VT >
4109  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
4110 
4111  template< typename VT >
4112  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
4113 
4114  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
4115 
4116  template< typename VT >
4117  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
4118 
4119  template< typename VT >
4120  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
4122  //**********************************************************************************************
4123 
4124  private:
4125  //**Member variables****************************************************************************
4128  Operand matrix_;
4129  const size_t col_;
4130 
4131  //**********************************************************************************************
4132 
4133  //**Friend declarations*************************************************************************
4134  template< typename MT2, bool SO2, bool DF2, bool SF2 > friend class Column;
4135 
4136  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4137  friend bool isIntact( const Column<MT2,SO2,DF2,SF2>& column ) noexcept;
4138 
4139  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4140  friend bool isSame( const Column<MT2,SO2,DF2,SF2>& a, const Column<MT2,SO2,DF2,SF2>& b ) noexcept;
4141 
4142  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4143  friend bool tryAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4144 
4145  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4146  friend bool tryAddAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4147 
4148  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4149  friend bool trySubAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4150 
4151  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4152  friend bool tryMultAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4153 
4154  template< typename MT2, bool SO2, bool DF2, bool SF2, typename VT >
4155  friend bool tryDivAssign( const Column<MT2,SO2,DF2,SF2>& lhs, const Vector<VT,false>& rhs, size_t index );
4156 
4157  template< typename MT2, bool SO2, bool DF2, bool SF2 >
4158  friend DerestrictTrait_< Column<MT2,SO2,DF2,SF2> > derestrict( Column<MT2,SO2,DF2,SF2>& column );
4159  //**********************************************************************************************
4160 
4161  //**Compile time checks*************************************************************************
4169  //**********************************************************************************************
4170 };
4172 //*************************************************************************************************
4173 
4174 
4175 
4176 
4177 //=================================================================================================
4178 //
4179 // CONSTRUCTOR
4180 //
4181 //=================================================================================================
4182 
4183 //*************************************************************************************************
4191 template< typename MT > // Type of the dense matrix
4192 inline Column<MT,false,true,true>::Column( Operand matrix, size_t index )
4193  : matrix_( matrix ) // The dense matrix containing the column
4194  , col_ ( index ) // The index of the column in the matrix
4195 {
4196  if( matrix_.columns() <= index ) {
4197  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
4198  }
4199 }
4201 //*************************************************************************************************
4202 
4203 
4204 
4205 
4206 //=================================================================================================
4207 //
4208 // DATA ACCESS FUNCTIONS
4209 //
4210 //=================================================================================================
4211 
4212 //*************************************************************************************************
4222 template< typename MT > // Type of the dense matrix
4224  Column<MT,false,true,true>::operator[]( size_t index )
4225 {
4226  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4227  return matrix_(col_,index);
4228 }
4230 //*************************************************************************************************
4231 
4232 
4233 //*************************************************************************************************
4243 template< typename MT > // Type of the dense matrix
4245  Column<MT,false,true,true>::operator[]( size_t index ) const
4246 {
4247  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4248  return const_cast<const MT&>( matrix_ )(index,col_);
4249 }
4251 //*************************************************************************************************
4252 
4253 
4254 //*************************************************************************************************
4265 template< typename MT > // Type of the dense matrix
4267  Column<MT,false,true,true>::at( size_t index )
4268 {
4269  if( index >= size() ) {
4270  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4271  }
4272  return (*this)[index];
4273 }
4275 //*************************************************************************************************
4276 
4277 
4278 //*************************************************************************************************
4289 template< typename MT > // Type of the dense matrix
4291  Column<MT,false,true,true>::at( size_t index ) const
4292 {
4293  if( index >= size() ) {
4294  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4295  }
4296  return (*this)[index];
4297 }
4299 //*************************************************************************************************
4300 
4301 
4302 //*************************************************************************************************
4311 template< typename MT > // Type of the dense matrix
4312 inline typename Column<MT,false,true,true>::Pointer Column<MT,false,true,true>::data() noexcept
4313 {
4314  return matrix_.data( col_ );
4315 }
4317 //*************************************************************************************************
4318 
4319 
4320 //*************************************************************************************************
4329 template< typename MT > // Type of the dense matrix
4330 inline typename Column<MT,false,true,true>::ConstPointer
4331  Column<MT,false,true,true>::data() const noexcept
4332 {
4333  return matrix_.data( col_ );
4334 }
4336 //*************************************************************************************************
4337 
4338 
4339 //*************************************************************************************************
4347 template< typename MT > // Type of the dense matrix
4349 {
4350  return matrix_.begin( col_ );
4351 }
4353 //*************************************************************************************************
4354 
4355 
4356 //*************************************************************************************************
4364 template< typename MT > // Type of the dense matrix
4366 {
4367  return matrix_.cbegin( col_ );
4368 }
4370 //*************************************************************************************************
4371 
4372 
4373 //*************************************************************************************************
4381 template< typename MT > // Type of the dense matrix
4383 {
4384  return matrix_.cbegin( col_ );
4385 }
4387 //*************************************************************************************************
4388 
4389 
4390 //*************************************************************************************************
4398 template< typename MT > // Type of the dense matrix
4400 {
4401  return matrix_.end( col_ );
4402 }
4404 //*************************************************************************************************
4405 
4406 
4407 //*************************************************************************************************
4415 template< typename MT > // Type of the dense matrix
4417 {
4418  return matrix_.cend( col_ );
4419 }
4421 //*************************************************************************************************
4422 
4423 
4424 //*************************************************************************************************
4432 template< typename MT > // Type of the dense matrix
4434 {
4435  return matrix_.cend( col_ );
4436 }
4438 //*************************************************************************************************
4439 
4440 
4441 
4442 
4443 //=================================================================================================
4444 //
4445 // ASSIGNMENT OPERATORS
4446 //
4447 //=================================================================================================
4448 
4449 //*************************************************************************************************
4456 template< typename MT > // Type of the dense matrix
4457 inline Column<MT,false,true,true>& Column<MT,false,true,true>::operator=( const ElementType& rhs )
4458 {
4459  const size_t jbegin( ( IsUpper<MT>::value )
4460  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4461  ?( col_+1UL )
4462  :( col_ ) )
4463  :( 0UL ) );
4464  const size_t jend ( ( IsLower<MT>::value )
4465  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4466  ?( col_ )
4467  :( col_+1UL ) )
4468  :( size() ) );
4469 
4470  for( size_t j=jbegin; j<jend; ++j )
4471  matrix_(col_,j) = rhs;
4472 
4473  return *this;
4474 }
4476 //*************************************************************************************************
4477 
4478 
4479 //*************************************************************************************************
4492 template< typename MT > // Type of the dense matrix
4493 inline Column<MT,false,true,true>&
4494  Column<MT,false,true,true>::operator=( initializer_list<ElementType> list )
4495 {
4496  if( list.size() > size() ) {
4497  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
4498  }
4499 
4500  std::fill( std::copy( list.begin(), list.end(), begin() ), end(), ElementType() );
4501 
4502  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4503 
4504  return *this;
4505 }
4507 //*************************************************************************************************
4508 
4509 
4510 //*************************************************************************************************
4524 template< typename MT > // Type of the dense matrix
4525 inline Column<MT,false,true,true>& Column<MT,false,true,true>::operator=( const Column& rhs )
4526 {
4527  if( &rhs == this ) return *this;
4528 
4529  if( size() != rhs.size() ) {
4530  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
4531  }
4532 
4533  if( !tryAssign( matrix_, rhs, 0UL, col_ ) ) {
4534  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4535  }
4536 
4537  DerestrictTrait_<This> left( derestrict( *this ) );
4538 
4539  smpAssign( left, rhs );
4540 
4541  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4542 
4543  return *this;
4544 }
4546 //*************************************************************************************************
4547 
4548 
4549 //*************************************************************************************************
4563 template< typename MT > // Type of the dense matrix
4564 template< typename VT > // Type of the right-hand side vector
4565 inline Column<MT,false,true,true>&
4566  Column<MT,false,true,true>::operator=( const Vector<VT,false>& rhs )
4567 {
4568  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4570 
4571  if( size() != (~rhs).size() ) {
4572  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4573  }
4574 
4575  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4576  Right right( ~rhs );
4577 
4578  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
4579  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4580  }
4581 
4582  DerestrictTrait_<This> left( derestrict( *this ) );
4583 
4584  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4585  const ResultType_<VT> tmp( right );
4586  smpAssign( left, tmp );
4587  }
4588  else {
4589  if( IsSparseVector<VT>::value )
4590  reset();
4591  smpAssign( left, right );
4592  }
4593 
4594  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4595 
4596  return *this;
4597 }
4599 //*************************************************************************************************
4600 
4601 
4602 //*************************************************************************************************
4616 template< typename MT > // Type of the dense matrix
4617 template< typename VT > // Type of the right-hand side vector
4618 inline Column<MT,false,true,true>&
4619  Column<MT,false,true,true>::operator+=( const Vector<VT,false>& rhs )
4620 {
4621  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4623 
4624  if( size() != (~rhs).size() ) {
4625  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4626  }
4627 
4628  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4629  Right right( ~rhs );
4630 
4631  if( !tryAddAssign( matrix_, right, 0UL, col_ ) ) {
4632  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4633  }
4634 
4635  DerestrictTrait_<This> left( derestrict( *this ) );
4636 
4637  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4638  const ResultType_<VT> tmp( right );
4639  smpAddAssign( left, tmp );
4640  }
4641  else {
4642  smpAddAssign( left, right );
4643  }
4644 
4645  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4646 
4647  return *this;
4648 }
4650 //*************************************************************************************************
4651 
4652 
4653 //*************************************************************************************************
4667 template< typename MT > // Type of the dense matrix
4668 template< typename VT > // Type of the right-hand side vector
4669 inline Column<MT,false,true,true>&
4670  Column<MT,false,true,true>::operator-=( const Vector<VT,false>& rhs )
4671 {
4672  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4674 
4675  if( size() != (~rhs).size() ) {
4676  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4677  }
4678 
4679  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4680  Right right( ~rhs );
4681 
4682  if( !trySubAssign( matrix_, right, 0UL, col_ ) ) {
4683  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4684  }
4685 
4686  DerestrictTrait_<This> left( derestrict( *this ) );
4687 
4688  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4689  const ResultType_<VT> tmp( right );
4690  smpSubAssign( left, tmp );
4691  }
4692  else {
4693  smpSubAssign( left, right );
4694  }
4695 
4696  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4697 
4698  return *this;
4699 }
4701 //*************************************************************************************************
4702 
4703 
4704 //*************************************************************************************************
4717 template< typename MT > // Type of the dense matrix
4718 template< typename VT > // Type of the right-hand side dense vector
4719 inline Column<MT,false,true,true>&
4720  Column<MT,false,true,true>::operator*=( const DenseVector<VT,false>& rhs )
4721 {
4722  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4724 
4725  if( size() != (~rhs).size() ) {
4726  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4727  }
4728 
4729  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4730  Right right( ~rhs );
4731 
4732  if( !tryMultAssign( matrix_, right, 0UL, col_ ) ) {
4733  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4734  }
4735 
4736  DerestrictTrait_<This> left( derestrict( *this ) );
4737 
4738  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4739  const ResultType_<VT> tmp( right );
4740  smpMultAssign( left, tmp );
4741  }
4742  else {
4743  smpMultAssign( left, right );
4744  }
4745 
4746  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4747 
4748  return *this;
4749 }
4751 //*************************************************************************************************
4752 
4753 
4754 //*************************************************************************************************
4767 template< typename MT > // Type of the dense matrix
4768 template< typename VT > // Type of the right-hand side sparse vector
4769 inline Column<MT,false,true,true>&
4770  Column<MT,false,true,true>::operator*=( const SparseVector<VT,false>& rhs )
4771 {
4775 
4776  if( size() != (~rhs).size() ) {
4777  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4778  }
4779 
4780  const ResultType right( *this * (~rhs) );
4781 
4782  if( !tryAssign( matrix_, right, 0UL, col_ ) ) {
4783  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4784  }
4785 
4786  DerestrictTrait_<This> left( derestrict( *this ) );
4787 
4788  smpAssign( left, right );
4789 
4790  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4791 
4792  return *this;
4793 }
4795 //*************************************************************************************************
4796 
4797 
4798 //*************************************************************************************************
4810 template< typename MT > // Type of the dense matrix
4811 template< typename VT > // Type of the right-hand side dense vector
4812 inline Column<MT,false,true,true>&
4813  Column<MT,false,true,true>::operator/=( const DenseVector<VT,false>& rhs )
4814 {
4815  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4817 
4818  if( size() != (~rhs).size() ) {
4819  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4820  }
4821 
4822  typedef If_< IsRestricted<MT>, CompositeType_<VT>, const VT& > Right;
4823  Right right( ~rhs );
4824 
4825  if( !tryDivAssign( matrix_, right, 0UL, col_ ) ) {
4826  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4827  }
4828 
4829  DerestrictTrait_<This> left( derestrict( *this ) );
4830 
4831  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4832  const ResultType_<VT> tmp( right );
4833  smpDivAssign( left, tmp );
4834  }
4835  else {
4836  smpDivAssign( left, right );
4837  }
4838 
4839  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4840 
4841  return *this;
4842 }
4844 //*************************************************************************************************
4845 
4846 
4847 //*************************************************************************************************
4858 template< typename MT > // Type of the dense matrix
4859 template< typename Other > // Data type of the right-hand side scalar
4860 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,true> >&
4862 {
4864 
4865  return operator=( (*this) * rhs );
4866 }
4868 //*************************************************************************************************
4869 
4870 
4871 //*************************************************************************************************
4884 template< typename MT > // Type of the dense matrix
4885 template< typename Other > // Data type of the right-hand side scalar
4886 inline EnableIf_< IsNumeric<Other>, Column<MT,false,true,true> >&
4888 {
4890 
4891  BLAZE_USER_ASSERT( rhs != Other(0), "Division by zero detected" );
4892 
4893  return operator=( (*this) / rhs );
4894 }
4896 //*************************************************************************************************
4897 
4898 
4899 
4900 
4901 //=================================================================================================
4902 //
4903 // UTILITY FUNCTIONS
4904 //
4905 //=================================================================================================
4906 
4907 //*************************************************************************************************
4913 template< typename MT > // Type of the dense matrix
4914 inline size_t Column<MT,false,true,true>::size() const noexcept
4915 {
4916  return matrix_.rows();
4917 }
4919 //*************************************************************************************************
4920 
4921 
4922 //*************************************************************************************************
4928 template< typename MT > // Type of the dense matrix
4929 inline size_t Column<MT,false,true,true>::capacity() const noexcept
4930 {
4931  return matrix_.capacity( col_ );
4932 }
4934 //*************************************************************************************************
4935 
4936 
4937 //*************************************************************************************************
4946 template< typename MT > // Type of the dense matrix
4947 inline size_t Column<MT,false,true,true>::nonZeros() const
4948 {
4949  return matrix_.nonZeros( col_ );
4950 }
4952 //*************************************************************************************************
4953 
4954 
4955 //*************************************************************************************************
4961 template< typename MT > // Type of the dense matrix
4963 {
4964  matrix_.reset( col_ );
4965 }
4967 //*************************************************************************************************
4968 
4969 
4970 //*************************************************************************************************
4981 template< typename MT > // Type of the dense matrix
4982 template< typename Other > // Data type of the scalar value
4983 inline Column<MT,false,true,true>& Column<MT,false,true,true>::scale( const Other& scalar )
4984 {
4986 
4987  const size_t jbegin( ( IsUpper<MT>::value )
4988  ?( ( IsStrictlyUpper<MT>::value )
4989  ?( col_+1UL )
4990  :( col_ ) )
4991  :( 0UL ) );
4992  const size_t jend ( ( IsLower<MT>::value )
4993  ?( ( IsStrictlyLower<MT>::value )
4994  ?( col_ )
4995  :( col_+1UL ) )
4996  :( size() ) );
4997 
4998  for( size_t j=jbegin; j<jend; ++j ) {
4999  matrix_(col_,j) *= scalar;
5000  }
5001 
5002  return *this;
5003 }
5005 //*************************************************************************************************
5006 
5007 
5008 
5009 
5010 //=================================================================================================
5011 //
5012 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5013 //
5014 //=================================================================================================
5015 
5016 //*************************************************************************************************
5027 template< typename MT > // Type of the dense matrix
5028 template< typename Other > // Data type of the foreign expression
5029 inline bool Column<MT,false,true,true>::canAlias( const Other* alias ) const noexcept
5030 {
5031  return matrix_.isAliased( alias );
5032 }
5034 //*************************************************************************************************
5035 
5036 
5037 //*************************************************************************************************
5048 template< typename MT > // Type of the dense matrix
5049 template< typename MT2 // Data type of the foreign dense column
5050  , bool SO2 // Storage order of the foreign dense column
5051  , bool SF2 > // Symmetry flag of the foreign dense column
5052 inline bool Column<MT,false,true,true>::canAlias( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
5053 {
5054  return matrix_.isAliased( alias->matrix_ ) && ( col_ == alias->col_ );
5055 }
5057 //*************************************************************************************************
5058 
5059 
5060 //*************************************************************************************************
5071 template< typename MT > // Type of the dense matrix
5072 template< typename Other > // Data type of the foreign expression
5073 inline bool Column<MT,false,true,true>::isAliased( const Other* alias ) const noexcept
5074 {
5075  return matrix_.isAliased( alias );
5076 }
5078 //*************************************************************************************************
5079 
5080 
5081 //*************************************************************************************************
5092 template< typename MT > // Type of the dense matrix
5093 template< typename MT2 // Data type of the foreign dense column
5094  , bool SO2 // Storage order of the foreign dense column
5095  , bool SF2 > // Symmetry flag of the foreign dense column
5096 inline bool Column<MT,false,true,true>::isAliased( const Column<MT2,SO2,true,SF2>* alias ) const noexcept
5097 {
5098  return matrix_.isAliased( &alias->matrix_ ) && ( col_ == alias->col_ );
5099 }
5101 //*************************************************************************************************
5102 
5103 
5104 //*************************************************************************************************
5114 template< typename MT > // Type of the dense matrix
5115 inline bool Column<MT,false,true,true>::isAligned() const noexcept
5116 {
5117  return matrix_.isAligned();
5118 }
5120 //*************************************************************************************************
5121 
5122 
5123 //*************************************************************************************************
5134 template< typename MT > // Type of the dense matrix
5135 inline bool Column<MT,false,true,true>::canSMPAssign() const noexcept
5136 {
5137  return ( size() > SMP_DVECASSIGN_THRESHOLD );
5138 }
5140 //*************************************************************************************************
5141 
5142 
5143 //*************************************************************************************************
5155 template< typename MT > // Type of the dense matrix
5156 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true>::SIMDType
5157  Column<MT,false,true,true>::load( size_t index ) const noexcept
5158 {
5159  return matrix_.load( col_, index );
5160 }
5162 //*************************************************************************************************
5163 
5164 
5165 //*************************************************************************************************
5178 template< typename MT > // Type of the dense matrix
5179 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true>::SIMDType
5180  Column<MT,false,true,true>::loada( size_t index ) const noexcept
5181 {
5182  return matrix_.loada( col_, index );
5183 }
5185 //*************************************************************************************************
5186 
5187 
5188 //*************************************************************************************************
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>::loadu( size_t index ) const noexcept
5204 {
5205  return matrix_.loadu( col_, index );
5206 }
5208 //*************************************************************************************************
5209 
5210 
5211 //*************************************************************************************************
5224 template< typename MT > // Type of the dense matrix
5226  Column<MT,false,true,true>::store( size_t index, const SIMDType& value ) noexcept
5227 {
5228  matrix_.store( col_, index, value );
5229 }
5231 //*************************************************************************************************
5232 
5233 
5234 //*************************************************************************************************
5248 template< typename MT > // Type of the dense matrix
5250  Column<MT,false,true,true>::storea( size_t index, const SIMDType& value ) noexcept
5251 {
5252  matrix_.storea( col_, index, value );
5253 }
5255 //*************************************************************************************************
5256 
5257 
5258 //*************************************************************************************************
5272 template< typename MT > // Type of the dense matrix
5274  Column<MT,false,true,true>::storeu( size_t index, const SIMDType& value ) noexcept
5275 {
5276  matrix_.storeu( col_, index, value );
5277 }
5279 //*************************************************************************************************
5280 
5281 
5282 //*************************************************************************************************
5296 template< typename MT > // Type of the dense matrix
5298  Column<MT,false,true,true>::stream( size_t index, const SIMDType& value ) noexcept
5299 {
5300  matrix_.stream( col_, index, value );
5301 }
5303 //*************************************************************************************************
5304 
5305 
5306 //*************************************************************************************************
5318 template< typename MT > // Type of the dense matrix
5319 template< typename VT > // Type of the right-hand side dense vector
5320 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5321  Column<MT,false,true,true>::assign( const DenseVector<VT,false>& rhs )
5322 {
5323  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5324 
5325  const size_t jpos( (~rhs).size() & size_t(-2) );
5326  for( size_t j=0UL; j<jpos; j+=2UL ) {
5327  matrix_(col_,j ) = (~rhs)[j ];
5328  matrix_(col_,j+1UL) = (~rhs)[j+1UL];
5329  }
5330  if( jpos < (~rhs).size() )
5331  matrix_(col_,jpos) = (~rhs)[jpos];
5332 }
5334 //*************************************************************************************************
5335 
5336 
5337 //*************************************************************************************************
5349 template< typename MT > // Type of the dense matrix
5350 template< typename VT > // Type of the right-hand side dense vector
5351 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5352  Column<MT,false,true,true>::assign( const DenseVector<VT,false>& rhs )
5353 {
5355 
5356  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5357 
5358  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5359  const size_t columns( size() );
5360 
5361  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5362  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5363 
5364  size_t j( 0UL );
5365  Iterator left( begin() );
5366  ConstIterator_<VT> right( (~rhs).begin() );
5367 
5368  if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
5369  {
5370  for( ; j<jpos; j+=SIMDSIZE ) {
5371  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5372  }
5373  for( ; remainder && j<columns; ++j ) {
5374  *left = *right; ++left; ++right;
5375  }
5376  }
5377  else
5378  {
5379  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5380  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5381  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5382  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5383  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5384  }
5385  for( ; j<jpos; j+=SIMDSIZE ) {
5386  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5387  }
5388  for( ; remainder && j<columns; ++j ) {
5389  *left = *right; ++left; ++right;
5390  }
5391  }
5392 }
5394 //*************************************************************************************************
5395 
5396 
5397 //*************************************************************************************************
5409 template< typename MT > // Type of the dense matrix
5410 template< typename VT > // Type of the right-hand side sparse vector
5411 inline void Column<MT,false,true,true>::assign( const SparseVector<VT,false>& rhs )
5412 {
5413  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5414 
5415  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5416  matrix_(col_,element->index()) = element->value();
5417 }
5419 //*************************************************************************************************
5420 
5421 
5422 //*************************************************************************************************
5434 template< typename MT > // Type of the dense matrix
5435 template< typename VT > // Type of the right-hand side dense vector
5436 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5437  Column<MT,false,true,true>::addAssign( const DenseVector<VT,false>& rhs )
5438 {
5439  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5440 
5441  const size_t jpos( (~rhs).size() & size_t(-2) );
5442  for( size_t j=0UL; j<jpos; j+=2UL ) {
5443  matrix_(col_,j ) += (~rhs)[j ];
5444  matrix_(col_,j+1UL) += (~rhs)[j+1UL];
5445  }
5446  if( jpos < (~rhs).size() )
5447  matrix_(col_,jpos) += (~rhs)[jpos];
5448 }
5450 //*************************************************************************************************
5451 
5452 
5453 //*************************************************************************************************
5465 template< typename MT > // Type of the dense matrix
5466 template< typename VT > // Type of the right-hand side dense vector
5467 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5468  Column<MT,false,true,true>::addAssign( const DenseVector<VT,false>& rhs )
5469 {
5471 
5472  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5473 
5474  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5475  const size_t columns( size() );
5476 
5477  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5478  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5479 
5480  size_t j( 0UL );
5481  Iterator left( begin() );
5482  ConstIterator_<VT> right( (~rhs).begin() );
5483 
5484  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5485  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5486  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5487  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5488  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5489  }
5490  for( ; j<jpos; j+=SIMDSIZE ) {
5491  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5492  }
5493  for( ; remainder && j<columns; ++j ) {
5494  *left += *right; ++left; ++right;
5495  }
5496 }
5498 //*************************************************************************************************
5499 
5500 
5501 //*************************************************************************************************
5513 template< typename MT > // Type of the dense matrix
5514 template< typename VT > // Type of the right-hand side sparse vector
5515 inline void Column<MT,false,true,true>::addAssign( const SparseVector<VT,false>& rhs )
5516 {
5517  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5518 
5519  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5520  matrix_(col_,element->index()) += element->value();
5521 }
5523 //*************************************************************************************************
5524 
5525 
5526 //*************************************************************************************************
5538 template< typename MT > // Type of the dense matrix
5539 template< typename VT > // Type of the right-hand side dense vector
5540 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5541  Column<MT,false,true,true>::subAssign( const DenseVector<VT,false>& rhs )
5542 {
5543  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5544 
5545  const size_t jpos( (~rhs).size() & size_t(-2) );
5546  for( size_t j=0UL; j<jpos; j+=2UL ) {
5547  matrix_(col_,j ) -= (~rhs)[j ];
5548  matrix_(col_,j+1UL) -= (~rhs)[j+1UL];
5549  }
5550  if( jpos < (~rhs).size() )
5551  matrix_(col_,jpos) -= (~rhs)[jpos];
5552 }
5554 //*************************************************************************************************
5555 
5556 
5557 //*************************************************************************************************
5569 template< typename MT > // Type of the dense matrix
5570 template< typename VT > // Type of the right-hand side dense vector
5571 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5572  Column<MT,false,true,true>::subAssign( const DenseVector<VT,false>& rhs )
5573 {
5575 
5576  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5577 
5578  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5579  const size_t columns( size() );
5580 
5581  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5582  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5583 
5584  size_t j( 0UL );
5585  Iterator left( begin() );
5586  ConstIterator_<VT> right( (~rhs).begin() );
5587 
5588  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5589  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5590  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5591  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5592  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5593  }
5594  for( ; j<jpos; j+=SIMDSIZE ) {
5595  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5596  }
5597  for( ; remainder && j<columns; ++j ) {
5598  *left -= *right; ++left; ++right;
5599  }
5600 }
5602 //*************************************************************************************************
5603 
5604 
5605 //*************************************************************************************************
5617 template< typename MT > // Type of the dense matrix
5618 template< typename VT > // Type of the right-hand side sparse vector
5619 inline void Column<MT,false,true,true>::subAssign( const SparseVector<VT,false>& rhs )
5620 {
5621  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5622 
5623  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5624  matrix_(col_,element->index()) -= element->value();
5625 }
5627 //*************************************************************************************************
5628 
5629 
5630 //*************************************************************************************************
5642 template< typename MT > // Type of the dense matrix
5643 template< typename VT > // Type of the right-hand side dense vector
5644 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5645  Column<MT,false,true,true>::multAssign( const DenseVector<VT,false>& rhs )
5646 {
5647  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5648 
5649  const size_t jpos( (~rhs).size() & size_t(-2) );
5650  for( size_t j=0UL; j<jpos; j+=2UL ) {
5651  matrix_(col_,j ) *= (~rhs)[j ];
5652  matrix_(col_,j+1UL) *= (~rhs)[j+1UL];
5653  }
5654  if( jpos < (~rhs).size() )
5655  matrix_(col_,jpos) *= (~rhs)[jpos];
5656 }
5658 //*************************************************************************************************
5659 
5660 
5661 //*************************************************************************************************
5673 template< typename MT > // Type of the dense matrix
5674 template< typename VT > // Type of the right-hand side dense vector
5675 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
5676  Column<MT,false,true,true>::multAssign( const DenseVector<VT,false>& rhs )
5677 {
5679 
5680  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5681 
5682  const bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5683  const size_t columns( size() );
5684 
5685  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5686  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5687 
5688  size_t j( 0UL );
5689  Iterator left( begin() );
5690  ConstIterator_<VT> right( (~rhs).begin() );
5691 
5692  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5693  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5694  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5695  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5696  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5697  }
5698  for( ; j<jpos; j+=SIMDSIZE ) {
5699  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5700  }
5701  for( ; remainder && j<columns; ++j ) {
5702  *left *= *right; ++left; ++right;
5703  }
5704 }
5706 //*************************************************************************************************
5707 
5708 
5709 //*************************************************************************************************
5721 template< typename MT > // Type of the dense matrix
5722 template< typename VT > // Type of the right-hand side sparse vector
5723 inline void Column<MT,false,true,true>::multAssign( const SparseVector<VT,false>& rhs )
5724 {
5725  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5726 
5727  const ResultType tmp( serial( *this ) );
5728 
5729  reset();
5730 
5731  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5732  matrix_(col_,element->index()) = tmp[element->index()] * element->value();
5733 }
5735 //*************************************************************************************************
5736 
5737 
5738 //*************************************************************************************************
5750 template< typename MT > // Type of the dense matrix
5751 template< typename VT > // Type of the right-hand side dense vector
5752 inline DisableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
5753  Column<MT,false,true,true>::divAssign( const DenseVector<VT,false>& rhs )
5754 {
5755  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5756 
5757  const size_t jpos( (~rhs).size() & size_t(-2) );
5758  for( size_t j=0UL; j<jpos; j+=2UL ) {
5759  matrix_(col_,j ) /= (~rhs)[j ];
5760  matrix_(col_,j+1UL) /= (~rhs)[j+1UL];
5761  }
5762  if( jpos < (~rhs).size() )
5763  matrix_(col_,jpos) /= (~rhs)[jpos];
5764 }
5766 //*************************************************************************************************
5767 
5768 
5769 //*************************************************************************************************
5781 template< typename MT > // Type of the dense matrix
5782 template< typename VT > // Type of the right-hand side dense vector
5783 inline EnableIf_< typename Column<MT,false,true,true>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
5784  Column<MT,false,true,true>::divAssign( const DenseVector<VT,false>& rhs )
5785 {
5787 
5788  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5789 
5790  const size_t columns( size() );
5791 
5792  const size_t jpos( columns & size_t(-SIMDSIZE) );
5793  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5794 
5795  size_t j( 0UL );
5796  Iterator left( begin() );
5797  ConstIterator_<VT> right( (~rhs).begin() );
5798 
5799  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5800  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5801  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5802  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5803  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5804  }
5805  for( ; j<jpos; j+=SIMDSIZE ) {
5806  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5807  }
5808  for( ; j<columns; ++j ) {
5809  *left /= *right; ++left; ++right;
5810  }
5811 }
5813 //*************************************************************************************************
5814 
5815 } // namespace blaze
5816 
5817 #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.
const DMatDMatMultExpr< T1, T2 > 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:7800
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:346
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:653
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:258
#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:188
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:2643
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
bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:366
Header file for the DenseVector base class.
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:2636
#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
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:442
const DMatSerialExpr< MT, SO > serial(const DenseMatrix< MT, SO > &dm)
Forces the serial evaluation of the given dense matrix expression dm.
Definition: DMatSerialExpr.h:723
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:384
#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
DisableIf_< Or< IsComputation< MT >, IsTransExpr< 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:126
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:298
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:232
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:573
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:2647
#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.
Header file for the Not class template.
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:330
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Constraint on the data type.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2640
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:254
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:2641
Constraint on the data type.
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:2645
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.
DisableIf_< Or< IsComputation< MT >, IsTransExpr< 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:126
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 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:2642
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:2646
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:314
#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:2637
Header file for the AreSIMDCombinable type trait.
Header file for the HasSIMDDiv type trait.
bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:249
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2638
bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:289
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:240
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:2644
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.
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.