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>
58 #include <blaze/math/Exception.h>
62 #include <blaze/math/shims/Clear.h>
64 #include <blaze/math/SIMD.h>
84 #include <blaze/math/views/Check.h>
87 #include <blaze/system/CacheSize.h>
88 #include <blaze/system/Inline.h>
91 #include <blaze/util/Assert.h>
95 #include <blaze/util/DisableIf.h>
96 #include <blaze/util/EnableIf.h>
97 #include <blaze/util/mpl/If.h>
98 #include <blaze/util/mpl/Not.h>
99 #include <blaze/util/mpl/Or.h>
100 #include <blaze/util/Template.h>
101 #include <blaze/util/TrueType.h>
102 #include <blaze/util/TypeList.h>
103 #include <blaze/util/Types.h>
107 
108 
109 namespace blaze {
110 
111 //=================================================================================================
112 //
113 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR DENSE MATRICES
114 //
115 //=================================================================================================
116 
117 //*************************************************************************************************
125 template< typename MT // Type of the dense matrix
126  , bool SF // Symmetry flag
127  , size_t... CCAs > // Compile time column arguments
128 class Column<MT,true,true,SF,CCAs...>
129  : public View< DenseVector< Column<MT,true,true,SF,CCAs...>, false > >
130  , private ColumnData<CCAs...>
131 {
132  private:
133  //**Type definitions****************************************************************************
134  using DataType = ColumnData<CCAs...>;
135  using Operand = If_< IsExpression<MT>, MT, MT& >;
136  //**********************************************************************************************
137 
138  public:
139  //**Type definitions****************************************************************************
141  using This = Column<MT,true,true,SF,CCAs...>;
142 
143  using BaseType = DenseVector<This,false>;
144  using ViewedType = MT;
145  using ResultType = ColumnTrait_<MT,CCAs...>;
146  using TransposeType = TransposeType_<ResultType>;
147  using ElementType = ElementType_<MT>;
148  using SIMDType = SIMDTrait_<ElementType>;
149  using ReturnType = ReturnType_<MT>;
150  using CompositeType = const Column&;
151 
153  using ConstReference = ConstReference_<MT>;
154 
156  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
157 
159  using ConstPointer = ConstPointer_<MT>;
160 
162  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, Pointer_<MT> >;
163 
165  using ConstIterator = ConstIterator_<MT>;
166 
168  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
169  //**********************************************************************************************
170 
171  //**Compilation flags***************************************************************************
173  enum : bool { simdEnabled = MT::simdEnabled };
174 
176  enum : bool { smpAssignable = MT::smpAssignable };
177  //**********************************************************************************************
178 
179  //**Constructors********************************************************************************
182  template< typename... RCAs >
183  explicit inline Column( MT& matrix, RCAs... args );
184  // No explicitly declared copy constructor.
186  //**********************************************************************************************
187 
188  //**Destructor**********************************************************************************
189  // No explicitly declared destructor.
190  //**********************************************************************************************
191 
192  //**Data access functions***********************************************************************
195  inline Reference operator[]( size_t index );
196  inline ConstReference operator[]( size_t index ) const;
197  inline Reference at( size_t index );
198  inline ConstReference at( size_t index ) const;
199  inline Pointer data () noexcept;
200  inline ConstPointer data () const noexcept;
201  inline Iterator begin ();
202  inline ConstIterator begin () const;
203  inline ConstIterator cbegin() const;
204  inline Iterator end ();
205  inline ConstIterator end () const;
206  inline ConstIterator cend () const;
208  //**********************************************************************************************
209 
210  //**Assignment operators************************************************************************
213  inline Column& operator=( const ElementType& rhs );
214  inline Column& operator=( initializer_list<ElementType> list );
215  inline Column& operator=( const Column& rhs );
216 
217  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
218  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
219  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
220  template< typename VT > inline Column& operator*=( const Vector<VT,false>& rhs );
221  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
222  template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
224  //**********************************************************************************************
225 
226  //**Utility functions***************************************************************************
229  using DataType::column;
230 
231  inline MT& operand() noexcept;
232  inline const MT& operand() const noexcept;
233 
234  inline size_t size() const noexcept;
235  inline size_t spacing() const noexcept;
236  inline size_t capacity() const noexcept;
237  inline size_t nonZeros() const;
238  inline void reset();
240  //**********************************************************************************************
241 
242  //**Numeric functions***************************************************************************
245  template< typename Other > inline Column& scale( const Other& scalar );
247  //**********************************************************************************************
248 
249  private:
250  //**********************************************************************************************
252  template< typename VT >
253  struct VectorizedAssign {
254  enum : bool { value = useOptimizedKernels &&
255  simdEnabled && VT::simdEnabled &&
256  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
257  };
258  //**********************************************************************************************
259 
260  //**********************************************************************************************
262  template< typename VT >
263  struct VectorizedAddAssign {
264  enum : bool { value = useOptimizedKernels &&
265  simdEnabled && VT::simdEnabled &&
266  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
267  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
268  };
269  //**********************************************************************************************
270 
271  //**********************************************************************************************
273  template< typename VT >
274  struct VectorizedSubAssign {
275  enum : bool { value = useOptimizedKernels &&
276  simdEnabled && VT::simdEnabled &&
277  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
278  HasSIMDSub< ElementType, ElementType_<VT> >::value };
279  };
280  //**********************************************************************************************
281 
282  //**********************************************************************************************
284  template< typename VT >
285  struct VectorizedMultAssign {
286  enum : bool { value = useOptimizedKernels &&
287  simdEnabled && VT::simdEnabled &&
288  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
289  HasSIMDMult< ElementType, ElementType_<VT> >::value };
290  };
291  //**********************************************************************************************
292 
293  //**********************************************************************************************
295  template< typename VT >
296  struct VectorizedDivAssign {
297  enum : bool { value = useOptimizedKernels &&
298  simdEnabled && VT::simdEnabled &&
299  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
300  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
301  };
302  //**********************************************************************************************
303 
304  //**SIMD properties*****************************************************************************
306  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
307  //**********************************************************************************************
308 
309  public:
310  //**Expression template evaluation functions****************************************************
313  template< typename Other >
314  inline bool canAlias( const Other* alias ) const noexcept;
315 
316  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
317  inline bool canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
318 
319  template< typename Other >
320  inline bool isAliased( const Other* alias ) const noexcept;
321 
322  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
323  inline bool isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
324 
325  inline bool isAligned () const noexcept;
326  inline bool canSMPAssign() const noexcept;
327 
328  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
329  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
330  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
331 
332  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
333  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
334  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
335  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
336 
337  template< typename VT >
338  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
339 
340  template< typename VT >
341  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
342 
343  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
344 
345  template< typename VT >
346  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
347 
348  template< typename VT >
349  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
350 
351  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
352 
353  template< typename VT >
354  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
355 
356  template< typename VT >
357  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
358 
359  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
360 
361  template< typename VT >
362  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
363 
364  template< typename VT >
365  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
366 
367  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
368 
369  template< typename VT >
370  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
371 
372  template< typename VT >
373  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
375  //**********************************************************************************************
376 
377  private:
378  //**Member variables****************************************************************************
381  Operand matrix_;
382 
383  //**********************************************************************************************
384 
385  //**Friend declarations*************************************************************************
386  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Column;
387  //**********************************************************************************************
388 
389  //**Compile time checks*************************************************************************
397  //**********************************************************************************************
398 };
400 //*************************************************************************************************
401 
402 
403 
404 
405 //=================================================================================================
406 //
407 // CONSTRUCTORS
408 //
409 //=================================================================================================
410 
411 //*************************************************************************************************
424 template< typename MT // Type of the dense matrix
425  , bool SF // Symmetry flag
426  , size_t... CCAs > // Compile time column arguments
427 template< typename... RCAs > // Runtime column arguments
428 inline Column<MT,true,true,SF,CCAs...>::Column( MT& matrix, RCAs... args )
429  : DataType( args... ) // Base class initialization
430  , matrix_ ( matrix ) // The matrix containing the column
431 {
432  if( !Contains< TypeList<RCAs...>, Unchecked >::value ) {
433  if( matrix_.columns() <= column() ) {
434  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
435  }
436  }
437  else {
438  BLAZE_USER_ASSERT( column() < matrix_.columns(), "Invalid column access index" );
439  }
440 }
442 //*************************************************************************************************
443 
444 
445 
446 
447 //=================================================================================================
448 //
449 // DATA ACCESS FUNCTIONS
450 //
451 //=================================================================================================
452 
453 //*************************************************************************************************
463 template< typename MT // Type of the dense matrix
464  , bool SF // Symmetry flag
465  , size_t... CCAs > // Compile time column arguments
466 inline typename Column<MT,true,true,SF,CCAs...>::Reference
467  Column<MT,true,true,SF,CCAs...>::operator[]( size_t index )
468 {
469  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
470  return matrix_(index,column());
471 }
473 //*************************************************************************************************
474 
475 
476 //*************************************************************************************************
486 template< typename MT // Type of the dense matrix
487  , bool SF // Symmetry flag
488  , size_t... CCAs > // Compile time column arguments
489 inline typename Column<MT,true,true,SF,CCAs...>::ConstReference
490  Column<MT,true,true,SF,CCAs...>::operator[]( size_t index ) const
491 {
492  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
493  return const_cast<const MT&>( matrix_ )(index,column());
494 }
496 //*************************************************************************************************
497 
498 
499 //*************************************************************************************************
510 template< typename MT // Type of the dense matrix
511  , bool SF // Symmetry flag
512  , size_t... CCAs > // Compile time column arguments
513 inline typename Column<MT,true,true,SF,CCAs...>::Reference
514  Column<MT,true,true,SF,CCAs...>::at( size_t index )
515 {
516  if( index >= size() ) {
517  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
518  }
519  return (*this)[index];
520 }
522 //*************************************************************************************************
523 
524 
525 //*************************************************************************************************
536 template< typename MT // Type of the dense matrix
537  , bool SF // Symmetry flag
538  , size_t... CCAs > // Compile time column arguments
539 inline typename Column<MT,true,true,SF,CCAs...>::ConstReference
540  Column<MT,true,true,SF,CCAs...>::at( size_t index ) const
541 {
542  if( index >= size() ) {
543  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
544  }
545  return (*this)[index];
546 }
548 //*************************************************************************************************
549 
550 
551 //*************************************************************************************************
560 template< typename MT // Type of the dense matrix
561  , bool SF // Symmetry flag
562  , size_t... CCAs > // Compile time column arguments
563 inline typename Column<MT,true,true,SF,CCAs...>::Pointer
565 {
566  return matrix_.data( column() );
567 }
569 //*************************************************************************************************
570 
571 
572 //*************************************************************************************************
581 template< typename MT // Type of the dense matrix
582  , bool SF // Symmetry flag
583  , size_t... CCAs > // Compile time column arguments
584 inline typename Column<MT,true,true,SF,CCAs...>::ConstPointer
586 {
587  return matrix_.data( column() );
588 }
590 //*************************************************************************************************
591 
592 
593 //*************************************************************************************************
601 template< typename MT // Type of the dense matrix
602  , bool SF // Symmetry flag
603  , size_t... CCAs > // Compile time column arguments
604 inline typename Column<MT,true,true,SF,CCAs...>::Iterator
606 {
607  return matrix_.begin( column() );
608 }
610 //*************************************************************************************************
611 
612 
613 //*************************************************************************************************
621 template< typename MT // Type of the dense matrix
622  , bool SF // Symmetry flag
623  , size_t... CCAs > // Compile time column arguments
624 inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
626 {
627  return matrix_.cbegin( column() );
628 }
630 //*************************************************************************************************
631 
632 
633 //*************************************************************************************************
641 template< typename MT // Type of the dense matrix
642  , bool SF // Symmetry flag
643  , size_t... CCAs > // Compile time column arguments
644 inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
646 {
647  return matrix_.cbegin( column() );
648 }
650 //*************************************************************************************************
651 
652 
653 //*************************************************************************************************
661 template< typename MT // Type of the dense matrix
662  , bool SF // Symmetry flag
663  , size_t... CCAs > // Compile time column arguments
664 inline typename Column<MT,true,true,SF,CCAs...>::Iterator
666 {
667  return matrix_.end( column() );
668 }
670 //*************************************************************************************************
671 
672 
673 //*************************************************************************************************
681 template< typename MT // Type of the dense matrix
682  , bool SF // Symmetry flag
683  , size_t... CCAs > // Compile time column arguments
684 inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
686 {
687  return matrix_.cend( column() );
688 }
690 //*************************************************************************************************
691 
692 
693 //*************************************************************************************************
701 template< typename MT // Type of the dense matrix
702  , bool SF // Symmetry flag
703  , size_t... CCAs > // Compile time column arguments
704 inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
706 {
707  return matrix_.cend( column() );
708 }
710 //*************************************************************************************************
711 
712 
713 
714 
715 //=================================================================================================
716 //
717 // ASSIGNMENT OPERATORS
718 //
719 //=================================================================================================
720 
721 //*************************************************************************************************
732 template< typename MT // Type of the dense matrix
733  , bool SF // Symmetry flag
734  , size_t... CCAs > // Compile time column arguments
735 inline Column<MT,true,true,SF,CCAs...>&
736  Column<MT,true,true,SF,CCAs...>::operator=( const ElementType& rhs )
737 {
738  decltype(auto) left( derestrict( matrix_ ) );
739 
740  const size_t ibegin( ( IsLower<MT>::value )
741  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
742  ?( column()+1UL )
743  :( column() ) )
744  :( 0UL ) );
745  const size_t iend ( ( IsUpper<MT>::value )
746  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
747  ?( column() )
748  :( column()+1UL ) )
749  :( size() ) );
750 
751  for( size_t i=ibegin; i<iend; ++i ) {
752  if( !IsRestricted<MT>::value || IsTriangular<MT>::value || trySet( matrix_, i, column(), rhs ) )
753  left(i,column()) = rhs;
754  }
755 
756  return *this;
757 }
759 //*************************************************************************************************
760 
761 
762 //*************************************************************************************************
777 template< typename MT // Type of the dense matrix
778  , bool SF // Symmetry flag
779  , size_t... CCAs > // Compile time column arguments
780 inline Column<MT,true,true,SF,CCAs...>&
781  Column<MT,true,true,SF,CCAs...>::operator=( initializer_list<ElementType> list )
782 {
783  if( list.size() > size() ) {
784  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
785  }
786 
787  if( IsRestricted<MT>::value ) {
788  const InitializerVector<ElementType,false> tmp( list, size() );
789  if( !tryAssign( matrix_, tmp, 0UL, column() ) ) {
790  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
791  }
792  }
793 
794  decltype(auto) left( derestrict( *this ) );
795 
796  std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
797 
798  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
799 
800  return *this;
801 }
803 //*************************************************************************************************
804 
805 
806 //*************************************************************************************************
820 template< typename MT // Type of the dense matrix
821  , bool SF // Symmetry flag
822  , size_t... CCAs > // Compile time column arguments
823 inline Column<MT,true,true,SF,CCAs...>&
824  Column<MT,true,true,SF,CCAs...>::operator=( const Column& rhs )
825 {
826  if( &rhs == this ) return *this;
827 
828  if( size() != rhs.size() ) {
829  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
830  }
831 
832  if( !tryAssign( matrix_, rhs, 0UL, column() ) ) {
833  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
834  }
835 
836  decltype(auto) left( derestrict( *this ) );
837 
838  if( IsExpression<MT>::value && rhs.canAlias( &matrix_ ) ) {
839  const ResultType tmp( rhs );
840  smpAssign( left, tmp );
841  }
842  else {
843  smpAssign( left, rhs );
844  }
845 
846  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
847 
848  return *this;
849 }
851 //*************************************************************************************************
852 
853 
854 //*************************************************************************************************
868 template< typename MT // Type of the dense matrix
869  , bool SF // Symmetry flag
870  , size_t... CCAs > // Compile time column arguments
871 template< typename VT > // Type of the right-hand side vector
872 inline Column<MT,true,true,SF,CCAs...>&
873  Column<MT,true,true,SF,CCAs...>::operator=( const Vector<VT,false>& rhs )
874 {
877 
878  if( size() != (~rhs).size() ) {
879  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
880  }
881 
882  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
883  Right right( ~rhs );
884 
885  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
886  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
887  }
888 
889  decltype(auto) left( derestrict( *this ) );
890 
891  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
892  const ResultType_<VT> tmp( right );
893  smpAssign( left, tmp );
894  }
895  else {
896  if( IsSparseVector<VT>::value )
897  reset();
898  smpAssign( left, right );
899  }
900 
901  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
902 
903  return *this;
904 }
906 //*************************************************************************************************
907 
908 
909 //*************************************************************************************************
923 template< typename MT // Type of the dense matrix
924  , bool SF // Symmetry flag
925  , size_t... CCAs > // Compile time column arguments
926 template< typename VT > // Type of the right-hand side vector
927 inline Column<MT,true,true,SF,CCAs...>&
928  Column<MT,true,true,SF,CCAs...>::operator+=( const Vector<VT,false>& rhs )
929 {
932 
933  if( size() != (~rhs).size() ) {
934  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
935  }
936 
937  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
938  Right right( ~rhs );
939 
940  if( !tryAddAssign( matrix_, right, 0UL, column() ) ) {
941  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
942  }
943 
944  decltype(auto) left( derestrict( *this ) );
945 
946  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
947  const ResultType_<VT> tmp( right );
948  smpAddAssign( left, tmp );
949  }
950  else {
951  smpAddAssign( left, right );
952  }
953 
954  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
955 
956  return *this;
957 }
959 //*************************************************************************************************
960 
961 
962 //*************************************************************************************************
976 template< typename MT // Type of the dense matrix
977  , bool SF // Symmetry flag
978  , size_t... CCAs > // Compile time column arguments
979 template< typename VT > // Type of the right-hand side vector
980 inline Column<MT,true,true,SF,CCAs...>&
981  Column<MT,true,true,SF,CCAs...>::operator-=( const Vector<VT,false>& rhs )
982 {
985 
986  if( size() != (~rhs).size() ) {
987  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
988  }
989 
990  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
991  Right right( ~rhs );
992 
993  if( !trySubAssign( matrix_, right, 0UL, column() ) ) {
994  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
995  }
996 
997  decltype(auto) left( derestrict( *this ) );
998 
999  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1000  const ResultType_<VT> tmp( right );
1001  smpSubAssign( left, tmp );
1002  }
1003  else {
1004  smpSubAssign( left, right );
1005  }
1006 
1007  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1008 
1009  return *this;
1010 }
1012 //*************************************************************************************************
1013 
1014 
1015 //*************************************************************************************************
1028 template< typename MT // Type of the dense matrix
1029  , bool SF // Symmetry flag
1030  , size_t... CCAs > // Compile time column arguments
1031 template< typename VT > // Type of the right-hand side vector
1032 inline Column<MT,true,true,SF,CCAs...>&
1033  Column<MT,true,true,SF,CCAs...>::operator*=( const Vector<VT,false>& rhs )
1034 {
1035  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
1037 
1038  if( size() != (~rhs).size() ) {
1039  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1040  }
1041 
1042  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
1043  Right right( ~rhs );
1044 
1045  if( !tryMultAssign( matrix_, right, 0UL, column() ) ) {
1046  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1047  }
1048 
1049  decltype(auto) left( derestrict( *this ) );
1050 
1051  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1052  const ResultType_<VT> tmp( right );
1053  smpMultAssign( left, tmp );
1054  }
1055  else {
1056  smpMultAssign( left, right );
1057  }
1058 
1059  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1060 
1061  return *this;
1062 }
1064 //*************************************************************************************************
1065 
1066 
1067 //*************************************************************************************************
1079 template< typename MT // Type of the dense matrix
1080  , bool SF // Symmetry flag
1081  , size_t... CCAs > // Compile time column arguments
1082 template< typename VT > // Type of the right-hand side dense vector
1083 inline Column<MT,true,true,SF,CCAs...>&
1084  Column<MT,true,true,SF,CCAs...>::operator/=( const DenseVector<VT,false>& rhs )
1085 {
1086  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
1088 
1089  if( size() != (~rhs).size() ) {
1090  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1091  }
1092 
1093  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
1094  Right right( ~rhs );
1095 
1096  if( !tryDivAssign( matrix_, right, 0UL, column() ) ) {
1097  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1098  }
1099 
1100  decltype(auto) left( derestrict( *this ) );
1101 
1102  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1103  const ResultType_<VT> tmp( right );
1104  smpDivAssign( left, tmp );
1105  }
1106  else {
1107  smpDivAssign( left, right );
1108  }
1109 
1110  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1111 
1112  return *this;
1113 }
1115 //*************************************************************************************************
1116 
1117 
1118 //*************************************************************************************************
1131 template< typename MT // Type of the dense matrix
1132  , bool SF // Symmetry flag
1133  , size_t... CCAs > // Compile time column arguments
1134 template< typename VT > // Type of the right-hand side vector
1135 inline Column<MT,true,true,SF,CCAs...>&
1136  Column<MT,true,true,SF,CCAs...>::operator%=( const Vector<VT,false>& rhs )
1137 {
1138  using blaze::assign;
1139 
1140  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
1142 
1143  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
1144 
1148 
1149  if( size() != 3UL || (~rhs).size() != 3UL ) {
1150  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1151  }
1152 
1153  const CrossType right( *this % (~rhs) );
1154 
1155  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
1156  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1157  }
1158 
1159  decltype(auto) left( derestrict( *this ) );
1160 
1161  assign( left, right );
1162 
1163  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1164 
1165  return *this;
1166 }
1168 //*************************************************************************************************
1169 
1170 
1171 
1172 
1173 //=================================================================================================
1174 //
1175 // UTILITY FUNCTIONS
1176 //
1177 //=================================================================================================
1178 
1179 //*************************************************************************************************
1185 template< typename MT // Type of the dense matrix
1186  , bool SF // Symmetry flag
1187  , size_t... CCAs > // Compile time column arguments
1188 inline MT& Column<MT,true,true,SF,CCAs...>::operand() noexcept
1189 {
1190  return matrix_;
1191 }
1193 //*************************************************************************************************
1194 
1195 
1196 //*************************************************************************************************
1202 template< typename MT // Type of the dense matrix
1203  , bool SF // Symmetry flag
1204  , size_t... CCAs > // Compile time column arguments
1205 inline const MT& Column<MT,true,true,SF,CCAs...>::operand() const noexcept
1206 {
1207  return matrix_;
1208 }
1210 //*************************************************************************************************
1211 
1212 
1213 //*************************************************************************************************
1219 template< typename MT // Type of the dense matrix
1220  , bool SF // Symmetry flag
1221  , size_t... CCAs > // Compile time column arguments
1222 inline size_t Column<MT,true,true,SF,CCAs...>::size() const noexcept
1223 {
1224  return matrix_.rows();
1225 }
1227 //*************************************************************************************************
1228 
1229 
1230 //*************************************************************************************************
1239 template< typename MT // Type of the dense matrix
1240  , bool SF // Symmetry flag
1241  , size_t... CCAs > // Compile time column arguments
1242 inline size_t Column<MT,true,true,SF,CCAs...>::spacing() const noexcept
1243 {
1244  return matrix_.spacing();
1245 }
1247 //*************************************************************************************************
1248 
1249 
1250 //*************************************************************************************************
1256 template< typename MT // Type of the dense matrix
1257  , bool SF // Symmetry flag
1258  , size_t... CCAs > // Compile time column arguments
1259 inline size_t Column<MT,true,true,SF,CCAs...>::capacity() const noexcept
1260 {
1261  return matrix_.capacity( column() );
1262 }
1264 //*************************************************************************************************
1265 
1266 
1267 //*************************************************************************************************
1276 template< typename MT // Type of the dense matrix
1277  , bool SF // Symmetry flag
1278  , size_t... CCAs > // Compile time column arguments
1279 inline size_t Column<MT,true,true,SF,CCAs...>::nonZeros() const
1280 {
1281  return matrix_.nonZeros( column() );
1282 }
1284 //*************************************************************************************************
1285 
1286 
1287 //*************************************************************************************************
1293 template< typename MT // Type of the dense matrix
1294  , bool SF // Symmetry flag
1295  , size_t... CCAs > // Compile time column arguments
1297 {
1298  matrix_.reset( column() );
1299 }
1301 //*************************************************************************************************
1302 
1303 
1304 
1305 
1306 //=================================================================================================
1307 //
1308 // NUMERIC FUNCTIONS
1309 //
1310 //=================================================================================================
1311 
1312 //*************************************************************************************************
1325 template< typename MT // Type of the dense matrix
1326  , bool SF // Symmetry flag
1327  , size_t... CCAs > // Compile time column arguments
1328 template< typename Other > // Data type of the scalar value
1329 inline Column<MT,true,true,SF,CCAs...>&
1330  Column<MT,true,true,SF,CCAs...>::scale( const Other& scalar )
1331 {
1333 
1334  const size_t ibegin( ( IsLower<MT>::value )
1335  ?( ( IsStrictlyLower<MT>::value )
1336  ?( column()+1UL )
1337  :( column() ) )
1338  :( 0UL ) );
1339  const size_t iend ( ( IsUpper<MT>::value )
1340  ?( ( IsStrictlyUpper<MT>::value )
1341  ?( column() )
1342  :( column()+1UL ) )
1343  :( size() ) );
1344 
1345  for( size_t i=ibegin; i<iend; ++i ) {
1346  matrix_(i,column()) *= scalar;
1347  }
1348 
1349  return *this;
1350 }
1352 //*************************************************************************************************
1353 
1354 
1355 
1356 
1357 //=================================================================================================
1358 //
1359 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1360 //
1361 //=================================================================================================
1362 
1363 //*************************************************************************************************
1374 template< typename MT // Type of the dense matrix
1375  , bool SF // Symmetry flag
1376  , size_t... CCAs > // Compile time column arguments
1377 template< typename Other > // Data type of the foreign expression
1378 inline bool Column<MT,true,true,SF,CCAs...>::canAlias( const Other* alias ) const noexcept
1379 {
1380  return matrix_.isAliased( alias );
1381 }
1383 //*************************************************************************************************
1384 
1385 
1386 //*************************************************************************************************
1397 template< typename MT // Type of the dense matrix
1398  , bool SF // Symmetry flag
1399  , size_t... CCAs > // Compile time column arguments
1400 template< typename MT2 // Data type of the foreign dense column
1401  , bool SO2 // Storage order of the foreign dense column
1402  , bool SF2 // Symmetry flag of the foreign dense column
1403  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
1404 inline bool
1405  Column<MT,true,true,SF,CCAs...>::canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1406 {
1407  return matrix_.isAliased( alias->matrix_ ) && ( column() == alias->column() );
1408 }
1410 //*************************************************************************************************
1411 
1412 
1413 //*************************************************************************************************
1424 template< typename MT // Type of the dense matrix
1425  , bool SF // Symmetry flag
1426  , size_t... CCAs > // Compile time column arguments
1427 template< typename Other > // Data type of the foreign expression
1428 inline bool Column<MT,true,true,SF,CCAs...>::isAliased( const Other* alias ) const noexcept
1429 {
1430  return matrix_.isAliased( alias );
1431 }
1433 //*************************************************************************************************
1434 
1435 
1436 //*************************************************************************************************
1447 template< typename MT // Type of the dense matrix
1448  , bool SF // Symmetry flag
1449  , size_t... CCAs > // Compile time column arguments
1450 template< typename MT2 // Data type of the foreign dense column
1451  , bool SO2 // Storage order of the foreign dense column
1452  , bool SF2 // Symmetry flag of the foreign dense column
1453  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
1454 inline bool
1455  Column<MT,true,true,SF,CCAs...>::isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1456 {
1457  return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
1458 }
1460 //*************************************************************************************************
1461 
1462 
1463 //*************************************************************************************************
1473 template< typename MT // Type of the dense matrix
1474  , bool SF // Symmetry flag
1475  , size_t... CCAs > // Compile time column arguments
1476 inline bool Column<MT,true,true,SF,CCAs...>::isAligned() const noexcept
1477 {
1478  return matrix_.isAligned();
1479 }
1481 //*************************************************************************************************
1482 
1483 
1484 //*************************************************************************************************
1495 template< typename MT // Type of the dense matrix
1496  , bool SF // Symmetry flag
1497  , size_t... CCAs > // Compile time column arguments
1498 inline bool Column<MT,true,true,SF,CCAs...>::canSMPAssign() const noexcept
1499 {
1500  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1501 }
1503 //*************************************************************************************************
1504 
1505 
1506 //*************************************************************************************************
1518 template< typename MT // Type of the dense matrix
1519  , bool SF // Symmetry flag
1520  , size_t... CCAs > // Compile time column arguments
1521 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF,CCAs...>::SIMDType
1522  Column<MT,true,true,SF,CCAs...>::load( size_t index ) const noexcept
1523 {
1524  return matrix_.load( index, column() );
1525 }
1527 //*************************************************************************************************
1528 
1529 
1530 //*************************************************************************************************
1543 template< typename MT // Type of the dense matrix
1544  , bool SF // Symmetry flag
1545  , size_t... CCAs > // Compile time column arguments
1546 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF,CCAs...>::SIMDType
1547  Column<MT,true,true,SF,CCAs...>::loada( size_t index ) const noexcept
1548 {
1549  return matrix_.loada( index, column() );
1550 }
1552 //*************************************************************************************************
1553 
1554 
1555 //*************************************************************************************************
1568 template< typename MT // Type of the dense matrix
1569  , bool SF // Symmetry flag
1570  , size_t... CCAs > // Compile time column arguments
1571 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF,CCAs...>::SIMDType
1572  Column<MT,true,true,SF,CCAs...>::loadu( size_t index ) const noexcept
1573 {
1574  return matrix_.loadu( index, column() );
1575 }
1577 //*************************************************************************************************
1578 
1579 
1580 //*************************************************************************************************
1593 template< typename MT // Type of the dense matrix
1594  , bool SF // Symmetry flag
1595  , size_t... CCAs > // Compile time column arguments
1597  Column<MT,true,true,SF,CCAs...>::store( size_t index, const SIMDType& value ) noexcept
1598 {
1599  matrix_.store( index, column(), value );
1600 }
1602 //*************************************************************************************************
1603 
1604 
1605 //*************************************************************************************************
1619 template< typename MT // Type of the dense matrix
1620  , bool SF // Symmetry flag
1621  , size_t... CCAs > // Compile time column arguments
1623  Column<MT,true,true,SF,CCAs...>::storea( size_t index, const SIMDType& value ) noexcept
1624 {
1625  matrix_.storea( index, column(), value );
1626 }
1628 //*************************************************************************************************
1629 
1630 
1631 //*************************************************************************************************
1645 template< typename MT // Type of the dense matrix
1646  , bool SF // Symmetry flag
1647  , size_t... CCAs > // Compile time column arguments
1649  Column<MT,true,true,SF,CCAs...>::storeu( size_t index, const SIMDType& value ) noexcept
1650 {
1651  matrix_.storeu( index, column(), value );
1652 }
1654 //*************************************************************************************************
1655 
1656 
1657 //*************************************************************************************************
1671 template< typename MT // Type of the dense matrix
1672  , bool SF // Symmetry flag
1673  , size_t... CCAs > // Compile time column arguments
1675  Column<MT,true,true,SF,CCAs...>::stream( size_t index, const SIMDType& value ) noexcept
1676 {
1677  matrix_.stream( index, column(), value );
1678 }
1680 //*************************************************************************************************
1681 
1682 
1683 //*************************************************************************************************
1695 template< typename MT // Type of the dense matrix
1696  , bool SF // Symmetry flag
1697  , size_t... CCAs > // Compile time column arguments
1698 template< typename VT > // Type of the right-hand side dense vector
1699 inline DisableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1700  Column<MT,true,true,SF,CCAs...>::assign( const DenseVector<VT,false>& rhs )
1701 {
1702  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1703 
1704  const size_t ipos( (~rhs).size() & size_t(-2) );
1705  for( size_t i=0UL; i<ipos; i+=2UL ) {
1706  matrix_(i ,column()) = (~rhs)[i ];
1707  matrix_(i+1UL,column()) = (~rhs)[i+1UL];
1708  }
1709  if( ipos < (~rhs).size() )
1710  matrix_(ipos,column()) = (~rhs)[ipos];
1711 }
1713 //*************************************************************************************************
1714 
1715 
1716 //*************************************************************************************************
1728 template< typename MT // Type of the dense matrix
1729  , bool SF // Symmetry flag
1730  , size_t... CCAs > // Compile time column arguments
1731 template< typename VT > // Type of the right-hand side dense vector
1732 inline EnableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedAssign<VT> >
1733  Column<MT,true,true,SF,CCAs...>::assign( const DenseVector<VT,false>& rhs )
1734 {
1736 
1737  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1738 
1739  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1740 
1741  const size_t rows( size() );
1742 
1743  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1744  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1745 
1746  size_t i( 0UL );
1747  Iterator left( begin() );
1748  ConstIterator_<VT> right( (~rhs).begin() );
1749 
1750  if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
1751  {
1752  for( ; i<ipos; i+=SIMDSIZE ) {
1753  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1754  }
1755  for( ; remainder && i<rows; ++i ) {
1756  *left = *right; ++left; ++right;
1757  }
1758  }
1759  else
1760  {
1761  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1762  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1763  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1764  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1765  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1766  }
1767  for( ; i<ipos; i+=SIMDSIZE ) {
1768  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1769  }
1770  for( ; remainder && i<rows; ++i ) {
1771  *left = *right; ++left; ++right;
1772  }
1773  }
1774 }
1776 //*************************************************************************************************
1777 
1778 
1779 //*************************************************************************************************
1791 template< typename MT // Type of the dense matrix
1792  , bool SF // Symmetry flag
1793  , size_t... CCAs > // Compile time column arguments
1794 template< typename VT > // Type of the right-hand side sparse vector
1795 inline void Column<MT,true,true,SF,CCAs...>::assign( const SparseVector<VT,false>& rhs )
1796 {
1797  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1798 
1799  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1800  matrix_(element->index(),column()) = element->value();
1801 }
1803 //*************************************************************************************************
1804 
1805 
1806 //*************************************************************************************************
1818 template< typename MT // Type of the dense matrix
1819  , bool SF // Symmetry flag
1820  , size_t... CCAs > // Compile time column arguments
1821 template< typename VT > // Type of the right-hand side dense vector
1822 inline DisableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1823  Column<MT,true,true,SF,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
1824 {
1825  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1826 
1827  const size_t ipos( (~rhs).size() & size_t(-2) );
1828  for( size_t i=0UL; i<ipos; i+=2UL ) {
1829  matrix_(i ,column()) += (~rhs)[i ];
1830  matrix_(i+1UL,column()) += (~rhs)[i+1UL];
1831  }
1832  if( ipos < (~rhs).size() )
1833  matrix_(ipos,column()) += (~rhs)[ipos];
1834 }
1836 //*************************************************************************************************
1837 
1838 
1839 //*************************************************************************************************
1851 template< typename MT // Type of the dense matrix
1852  , bool SF // Symmetry flag
1853  , size_t... CCAs > // Compile time column arguments
1854 template< typename VT > // Type of the right-hand side dense vector
1855 inline EnableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
1856  Column<MT,true,true,SF,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
1857 {
1859 
1860  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1861 
1862  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1863 
1864  const size_t rows( size() );
1865 
1866  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1867  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1868 
1869  size_t i( 0UL );
1870  Iterator left( begin() );
1871  ConstIterator_<VT> right( (~rhs).begin() );
1872 
1873  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1874  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1875  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1876  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1877  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1878  }
1879  for( ; i<ipos; i+=SIMDSIZE ) {
1880  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1881  }
1882  for( ; remainder && i<rows; ++i ) {
1883  *left += *right; ++left; ++right;
1884  }
1885 }
1887 //*************************************************************************************************
1888 
1889 
1890 //*************************************************************************************************
1902 template< typename MT // Type of the dense matrix
1903  , bool SF // Symmetry flag
1904  , size_t... CCAs > // Compile time column arguments
1905 template< typename VT > // Type of the right-hand side sparse vector
1906 inline void Column<MT,true,true,SF,CCAs...>::addAssign( const SparseVector<VT,false>& rhs )
1907 {
1908  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1909 
1910  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1911  matrix_(element->index(),column()) += element->value();
1912 }
1914 //*************************************************************************************************
1915 
1916 
1917 //*************************************************************************************************
1929 template< typename MT // Type of the dense matrix
1930  , bool SF // Symmetry flag
1931  , size_t... CCAs > // Compile time column arguments
1932 template< typename VT > // Type of the right-hand side dense vector
1933 inline DisableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1934  Column<MT,true,true,SF,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
1935 {
1936  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1937 
1938  const size_t ipos( (~rhs).size() & size_t(-2) );
1939  for( size_t i=0UL; i<ipos; i+=2UL ) {
1940  matrix_(i ,column()) -= (~rhs)[i ];
1941  matrix_(i+1UL,column()) -= (~rhs)[i+1UL];
1942  }
1943  if( ipos < (~rhs).size() )
1944  matrix_(ipos,column()) -= (~rhs)[ipos];
1945 }
1947 //*************************************************************************************************
1948 
1949 
1950 //*************************************************************************************************
1962 template< typename MT // Type of the dense matrix
1963  , bool SF // Symmetry flag
1964  , size_t... CCAs > // Compile time column arguments
1965 template< typename VT > // Type of the right-hand side dense vector
1966 inline EnableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
1967  Column<MT,true,true,SF,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
1968 {
1970 
1971  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1972 
1973  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
1974 
1975  const size_t rows( size() );
1976 
1977  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1978  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1979 
1980  size_t i( 0UL );
1981  Iterator left( begin() );
1982  ConstIterator_<VT> right( (~rhs).begin() );
1983 
1984  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1985  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1986  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1987  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1988  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1989  }
1990  for( ; i<ipos; i+=SIMDSIZE ) {
1991  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1992  }
1993  for( ; remainder && i<rows; ++i ) {
1994  *left -= *right; ++left; ++right;
1995  }
1996 }
1998 //*************************************************************************************************
1999 
2000 
2001 //*************************************************************************************************
2013 template< typename MT // Type of the dense matrix
2014  , bool SF // Symmetry flag
2015  , size_t... CCAs > // Compile time column arguments
2016 template< typename VT > // Type of the right-hand side sparse vector
2017 inline void Column<MT,true,true,SF,CCAs...>::subAssign( const SparseVector<VT,false>& rhs )
2018 {
2019  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2020 
2021  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2022  matrix_(element->index(),column()) -= element->value();
2023 }
2025 //*************************************************************************************************
2026 
2027 
2028 //*************************************************************************************************
2040 template< typename MT // Type of the dense matrix
2041  , bool SF // Symmetry flag
2042  , size_t... CCAs > // Compile time column arguments
2043 template< typename VT > // Type of the right-hand side dense vector
2044 inline DisableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
2045  Column<MT,true,true,SF,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
2046 {
2047  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2048 
2049  const size_t ipos( (~rhs).size() & size_t(-2) );
2050  for( size_t i=0UL; i<ipos; i+=2UL ) {
2051  matrix_(i ,column()) *= (~rhs)[i ];
2052  matrix_(i+1UL,column()) *= (~rhs)[i+1UL];
2053  }
2054  if( ipos < (~rhs).size() )
2055  matrix_(ipos,column()) *= (~rhs)[ipos];
2056 }
2058 //*************************************************************************************************
2059 
2060 
2061 //*************************************************************************************************
2073 template< typename MT // Type of the dense matrix
2074  , bool SF // Symmetry flag
2075  , size_t... CCAs > // Compile time column arguments
2076 template< typename VT > // Type of the right-hand side dense vector
2077 inline EnableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
2078  Column<MT,true,true,SF,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
2079 {
2081 
2082  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2083 
2084  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
2085 
2086  const size_t rows( size() );
2087 
2088  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
2089  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2090 
2091  size_t i( 0UL );
2092  Iterator left( begin() );
2093  ConstIterator_<VT> right( (~rhs).begin() );
2094 
2095  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2096  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2097  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2098  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2099  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2100  }
2101  for( ; i<ipos; i+=SIMDSIZE ) {
2102  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2103  }
2104  for( ; remainder && i<rows; ++i ) {
2105  *left *= *right; ++left, ++right;
2106  }
2107 }
2109 //*************************************************************************************************
2110 
2111 
2112 //*************************************************************************************************
2124 template< typename MT // Type of the dense matrix
2125  , bool SF // Symmetry flag
2126  , size_t... CCAs > // Compile time column arguments
2127 template< typename VT > // Type of the right-hand side sparse vector
2128 inline void Column<MT,true,true,SF,CCAs...>::multAssign( const SparseVector<VT,false>& rhs )
2129 {
2130  using blaze::reset;
2131 
2132  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2133 
2134  size_t i( 0UL );
2135 
2136  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2137  const size_t index( element->index() );
2138  for( ; i<index; ++i )
2139  reset( matrix_(i,column()) );
2140  matrix_(i,column()) *= element->value();
2141  ++i;
2142  }
2143 
2144  for( ; i<size(); ++i ) {
2145  reset( matrix_(i,column()) );
2146  }
2147 }
2149 //*************************************************************************************************
2150 
2151 
2152 //*************************************************************************************************
2164 template< typename MT // Type of the dense matrix
2165  , bool SF // Symmetry flag
2166  , size_t... CCAs > // Compile time column arguments
2167 template< typename VT > // Type of the right-hand side dense vector
2168 inline DisableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2169  Column<MT,true,true,SF,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
2170 {
2171  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2172 
2173  const size_t ipos( (~rhs).size() & size_t(-2) );
2174  for( size_t i=0UL; i<ipos; i+=2UL ) {
2175  matrix_(i ,column()) /= (~rhs)[i ];
2176  matrix_(i+1UL,column()) /= (~rhs)[i+1UL];
2177  }
2178  if( ipos < (~rhs).size() )
2179  matrix_(ipos,column()) /= (~rhs)[ipos];
2180 }
2182 //*************************************************************************************************
2183 
2184 
2185 //*************************************************************************************************
2197 template< typename MT // Type of the dense matrix
2198  , bool SF // Symmetry flag
2199  , size_t... CCAs > // Compile time column arguments
2200 template< typename VT > // Type of the right-hand side dense vector
2201 inline EnableIf_< typename Column<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
2202  Column<MT,true,true,SF,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
2203 {
2205 
2206  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2207 
2208  const size_t rows( size() );
2209 
2210  const size_t ipos( rows & size_t(-SIMDSIZE) );
2211  BLAZE_INTERNAL_ASSERT( ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2212 
2213  size_t i( 0UL );
2214  Iterator left( begin() );
2215  ConstIterator_<VT> right( (~rhs).begin() );
2216 
2217  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2218  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2219  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2220  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2221  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2222  }
2223  for( ; i<ipos; i+=SIMDSIZE ) {
2224  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2225  }
2226  for( ; i<rows; ++i ) {
2227  *left /= *right; ++left; ++right;
2228  }
2229 }
2231 //*************************************************************************************************
2232 
2233 
2234 
2235 
2236 
2237 
2238 
2239 
2240 //=================================================================================================
2241 //
2242 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
2243 //
2244 //=================================================================================================
2245 
2246 //*************************************************************************************************
2254 template< typename MT // Type of the dense matrix
2255  , size_t... CCAs > // Compile time column arguments
2256 class Column<MT,false,true,false,CCAs...>
2257  : public View< DenseVector< Column<MT,false,true,false,CCAs...>, false > >
2258  , private ColumnData<CCAs...>
2259 {
2260  private:
2261  //**Type definitions****************************************************************************
2262  using DataType = ColumnData<CCAs...>;
2263  using Operand = If_< IsExpression<MT>, MT, MT& >;
2264  //**********************************************************************************************
2265 
2266  public:
2267  //**Type definitions****************************************************************************
2269  using This = Column<MT,false,true,false,CCAs...>;
2270 
2271  using BaseType = DenseVector<This,false>;
2272  using ViewedType = MT;
2273  using ResultType = ColumnTrait_<MT,CCAs...>;
2274  using TransposeType = TransposeType_<ResultType>;
2275  using ElementType = ElementType_<MT>;
2276  using ReturnType = ReturnType_<MT>;
2277  using CompositeType = const Column&;
2278 
2280  using ConstReference = ConstReference_<MT>;
2281 
2283  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
2284 
2286  using ConstPointer = ConstPointer_<MT>;
2287 
2289  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, Pointer_<MT> >;
2290  //**********************************************************************************************
2291 
2292  //**ColumnIterator class definition*************************************************************
2295  template< typename MatrixType // Type of the dense matrix
2296  , typename IteratorType > // Type of the dense matrix iterator
2297  class ColumnIterator
2298  {
2299  public:
2300  //**Type definitions*************************************************************************
2302  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
2303 
2305  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
2306 
2308  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
2309 
2311  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
2312 
2314  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
2315 
2316  // STL iterator requirements
2317  using iterator_category = IteratorCategory;
2318  using value_type = ValueType;
2319  using pointer = PointerType;
2320  using reference = ReferenceType;
2321  using difference_type = DifferenceType;
2322  //*******************************************************************************************
2323 
2324  //**Constructor******************************************************************************
2327  inline ColumnIterator() noexcept
2328  : matrix_( nullptr ) // The dense matrix containing the column
2329  , row_ ( 0UL ) // The current row index
2330  , column_( 0UL ) // The current column index
2331  , pos_ ( ) // Iterator to the current dense element
2332  {}
2333  //*******************************************************************************************
2334 
2335  //**Constructor******************************************************************************
2342  inline ColumnIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2343  : matrix_( &matrix ) // The dense matrix containing the column
2344  , row_ ( row ) // The current row index
2345  , column_( column ) // The current column index
2346  , pos_ ( ) // Iterator to the current dense element
2347  {
2348  if( row_ != matrix_->rows() )
2349  pos_ = matrix_->begin( row_ ) + column_;
2350  }
2351  //*******************************************************************************************
2352 
2353  //**Constructor******************************************************************************
2358  template< typename MatrixType2, typename IteratorType2 >
2359  inline ColumnIterator( const ColumnIterator<MatrixType2,IteratorType2>& it ) noexcept
2360  : matrix_( it.matrix_ ) // The dense matrix containing the column
2361  , row_ ( it.row_ ) // The current row index
2362  , column_( it.column_ ) // The current column index
2363  , pos_ ( it.pos_ ) // Iterator to the current dense element
2364  {}
2365  //*******************************************************************************************
2366 
2367  //**Addition assignment operator*************************************************************
2373  inline ColumnIterator& operator+=( size_t inc ) noexcept {
2374  using blaze::reset;
2375  row_ += inc;
2376  if( row_ != matrix_->rows() )
2377  pos_ = matrix_->begin( row_ ) + column_;
2378  else reset( pos_ );
2379  return *this;
2380  }
2381  //*******************************************************************************************
2382 
2383  //**Subtraction assignment operator**********************************************************
2389  inline ColumnIterator& operator-=( size_t dec ) noexcept {
2390  using blaze::reset;
2391  row_ -= dec;
2392  if( row_ != matrix_->rows() )
2393  pos_ = matrix_->begin( row_ ) + column_;
2394  else reset( pos_ );
2395  return *this;
2396  }
2397  //*******************************************************************************************
2398 
2399  //**Prefix increment operator****************************************************************
2404  inline ColumnIterator& operator++() noexcept {
2405  using blaze::reset;
2406  ++row_;
2407  if( row_ != matrix_->rows() )
2408  pos_ = matrix_->begin( row_ ) + column_;
2409  else reset( pos_ );
2410  return *this;
2411  }
2412  //*******************************************************************************************
2413 
2414  //**Postfix increment operator***************************************************************
2419  inline const ColumnIterator operator++( int ) noexcept {
2420  const ColumnIterator tmp( *this );
2421  ++(*this);
2422  return tmp;
2423  }
2424  //*******************************************************************************************
2425 
2426  //**Prefix decrement operator****************************************************************
2431  inline ColumnIterator& operator--() noexcept {
2432  using blaze::reset;
2433  --row_;
2434  if( row_ != matrix_->rows() )
2435  pos_ = matrix_->begin( row_ ) + column_;
2436  else reset( pos_ );
2437  return *this;
2438  }
2439  //*******************************************************************************************
2440 
2441  //**Postfix decrement operator***************************************************************
2446  inline const ColumnIterator operator--( int ) noexcept {
2447  const ColumnIterator tmp( *this );
2448  --(*this);
2449  return tmp;
2450  }
2451  //*******************************************************************************************
2452 
2453  //**Subscript operator***********************************************************************
2459  inline ReferenceType operator[]( size_t index ) const {
2460  BLAZE_USER_ASSERT( row_+index < matrix_->rows(), "Invalid access index detected" );
2461  const IteratorType pos( matrix_->begin( row_+index ) + column_ );
2462  return *pos;
2463  }
2464  //*******************************************************************************************
2465 
2466  //**Element access operator******************************************************************
2471  inline ReferenceType operator*() const {
2472  return *pos_;
2473  }
2474  //*******************************************************************************************
2475 
2476  //**Element access operator******************************************************************
2481  inline PointerType operator->() const {
2482  return pos_;
2483  }
2484  //*******************************************************************************************
2485 
2486  //**Equality operator************************************************************************
2492  template< typename MatrixType2, typename IteratorType2 >
2493  inline bool operator==( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2494  return row_ == rhs.row_;
2495  }
2496  //*******************************************************************************************
2497 
2498  //**Inequality operator**********************************************************************
2504  template< typename MatrixType2, typename IteratorType2 >
2505  inline bool operator!=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2506  return !( *this == rhs );
2507  }
2508  //*******************************************************************************************
2509 
2510  //**Less-than operator***********************************************************************
2516  template< typename MatrixType2, typename IteratorType2 >
2517  inline bool operator<( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2518  return row_ < rhs.row_;
2519  }
2520  //*******************************************************************************************
2521 
2522  //**Greater-than operator********************************************************************
2528  template< typename MatrixType2, typename IteratorType2 >
2529  inline bool operator>( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2530  return row_ > rhs.row_;
2531  }
2532  //*******************************************************************************************
2533 
2534  //**Less-or-equal-than operator**************************************************************
2540  template< typename MatrixType2, typename IteratorType2 >
2541  inline bool operator<=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2542  return row_ <= rhs.row_;
2543  }
2544  //*******************************************************************************************
2545 
2546  //**Greater-or-equal-than operator***********************************************************
2552  template< typename MatrixType2, typename IteratorType2 >
2553  inline bool operator>=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2554  return row_ >= rhs.row_;
2555  }
2556  //*******************************************************************************************
2557 
2558  //**Subtraction operator*********************************************************************
2564  inline DifferenceType operator-( const ColumnIterator& rhs ) const noexcept {
2565  return row_ - rhs.row_;
2566  }
2567  //*******************************************************************************************
2568 
2569  //**Addition operator************************************************************************
2576  friend inline const ColumnIterator operator+( const ColumnIterator& it, size_t inc ) noexcept {
2577  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2578  }
2579  //*******************************************************************************************
2580 
2581  //**Addition operator************************************************************************
2588  friend inline const ColumnIterator operator+( size_t inc, const ColumnIterator& it ) noexcept {
2589  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2590  }
2591  //*******************************************************************************************
2592 
2593  //**Subtraction operator*********************************************************************
2600  friend inline const ColumnIterator operator-( const ColumnIterator& it, size_t dec ) noexcept {
2601  return ColumnIterator( *it.matrix_, it.row_-dec, it.column_ );
2602  }
2603  //*******************************************************************************************
2604 
2605  private:
2606  //**Member variables*************************************************************************
2607  MatrixType* matrix_;
2608  size_t row_;
2609  size_t column_;
2610  IteratorType pos_;
2611  //*******************************************************************************************
2612 
2613  //**Friend declarations**********************************************************************
2614  template< typename MatrixType2, typename IteratorType2 > friend class ColumnIterator;
2615  //*******************************************************************************************
2616  };
2617  //**********************************************************************************************
2618 
2619  //**Type definitions****************************************************************************
2621  using ConstIterator = ColumnIterator< const MT, ConstIterator_<MT> >;
2622 
2624  using Iterator = If_< IsConst<MT>, ConstIterator, ColumnIterator< MT, Iterator_<MT> > >;
2625  //**********************************************************************************************
2626 
2627  //**Compilation flags***************************************************************************
2629  enum : bool { simdEnabled = false };
2630 
2632  enum : bool { smpAssignable = MT::smpAssignable };
2633  //**********************************************************************************************
2634 
2635  //**Constructors********************************************************************************
2638  template< typename... RCAs >
2639  explicit inline Column( MT& matrix, RCAs... args );
2640  // No explicitly declared copy constructor.
2642  //**********************************************************************************************
2643 
2644  //**Destructor**********************************************************************************
2645  // No explicitly declared destructor.
2646  //**********************************************************************************************
2647 
2648  //**Data access functions***********************************************************************
2651  inline Reference operator[]( size_t index );
2652  inline ConstReference operator[]( size_t index ) const;
2653  inline Reference at( size_t index );
2654  inline ConstReference at( size_t index ) const;
2655  inline Pointer data () noexcept;
2656  inline ConstPointer data () const noexcept;
2657  inline Iterator begin ();
2658  inline ConstIterator begin () const;
2659  inline ConstIterator cbegin() const;
2660  inline Iterator end ();
2661  inline ConstIterator end () const;
2662  inline ConstIterator cend () const;
2664  //**********************************************************************************************
2665 
2666  //**Assignment operators************************************************************************
2669  inline Column& operator=( const ElementType& rhs );
2670  inline Column& operator=( initializer_list<ElementType> list );
2671  inline Column& operator=( const Column& rhs );
2672 
2673  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
2674  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
2675  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
2676  template< typename VT > inline Column& operator*=( const Vector<VT,false>& rhs );
2677  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
2678  template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
2680  //**********************************************************************************************
2681 
2682  //**Utility functions***************************************************************************
2685  using DataType::column;
2686 
2687  inline MT& operand() noexcept;
2688  inline const MT& operand() const noexcept;
2689 
2690  inline size_t size() const noexcept;
2691  inline size_t spacing() const noexcept;
2692  inline size_t capacity() const noexcept;
2693  inline size_t nonZeros() const;
2694  inline void reset();
2696  //**********************************************************************************************
2697 
2698  //**Numeric functions***************************************************************************
2701  template< typename Other > inline Column& scale( const Other& scalar );
2703  //**********************************************************************************************
2704 
2705  //**Expression template evaluation functions****************************************************
2708  template< typename Other >
2709  inline bool canAlias ( const Other* alias ) const noexcept;
2710 
2711  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
2712  inline bool canAlias ( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
2713 
2714  template< typename Other >
2715  inline bool isAliased( const Other* alias ) const noexcept;
2716 
2717  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
2718  inline bool isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
2719 
2720  inline bool isAligned () const noexcept;
2721  inline bool canSMPAssign() const noexcept;
2722 
2723  template< typename VT > inline void assign ( const DenseVector <VT,false>& rhs );
2724  template< typename VT > inline void assign ( const SparseVector<VT,false>& rhs );
2725  template< typename VT > inline void addAssign ( const DenseVector <VT,false>& rhs );
2726  template< typename VT > inline void addAssign ( const SparseVector<VT,false>& rhs );
2727  template< typename VT > inline void subAssign ( const DenseVector <VT,false>& rhs );
2728  template< typename VT > inline void subAssign ( const SparseVector<VT,false>& rhs );
2729  template< typename VT > inline void multAssign( const DenseVector <VT,false>& rhs );
2730  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
2731  template< typename VT > inline void divAssign ( const DenseVector <VT,false>& rhs );
2733  //**********************************************************************************************
2734 
2735  private:
2736  //**Member variables****************************************************************************
2739  Operand matrix_;
2740 
2741  //**********************************************************************************************
2742 
2743  //**Friend declarations*************************************************************************
2744  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Column;
2745  //**********************************************************************************************
2746 
2747  //**Compile time checks*************************************************************************
2756  //**********************************************************************************************
2757 };
2759 //*************************************************************************************************
2760 
2761 
2762 
2763 
2764 //=================================================================================================
2765 //
2766 // CONSTRUCTORS
2767 //
2768 //=================================================================================================
2769 
2770 //*************************************************************************************************
2783 template< typename MT // Type of the dense matrix
2784  , size_t... CCAs > // Compile time column arguments
2785 template< typename... RCAs > // Runtime column arguments
2786 inline Column<MT,false,true,false,CCAs...>::Column( MT& matrix, RCAs... args )
2787  : DataType( args... ) // Base class initialization
2788  , matrix_ ( matrix ) // The matrix containing the column
2789 {
2790  if( !Contains< TypeList<RCAs...>, Unchecked >::value ) {
2791  if( matrix_.columns() <= column() ) {
2792  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2793  }
2794  }
2795  else {
2796  BLAZE_USER_ASSERT( column() < matrix_.columns(), "Invalid column access index" );
2797  }
2798 }
2800 //*************************************************************************************************
2801 
2802 
2803 
2804 
2805 //=================================================================================================
2806 //
2807 // DATA ACCESS FUNCTIONS
2808 //
2809 //=================================================================================================
2810 
2811 //*************************************************************************************************
2821 template< typename MT // Type of the dense matrix
2822  , size_t... CCAs > // Compile time column arguments
2823 inline typename Column<MT,false,true,false,CCAs...>::Reference
2824  Column<MT,false,true,false,CCAs...>::operator[]( size_t index )
2825 {
2826  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2827  return matrix_(index,column());
2828 }
2830 //*************************************************************************************************
2831 
2832 
2833 //*************************************************************************************************
2843 template< typename MT // Type of the dense matrix
2844  , size_t... CCAs > // Compile time column arguments
2845 inline typename Column<MT,false,true,false,CCAs...>::ConstReference
2846  Column<MT,false,true,false,CCAs...>::operator[]( size_t index ) const
2847 {
2848  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2849  return const_cast<const MT&>( matrix_ )(index,column());
2850 }
2852 //*************************************************************************************************
2853 
2854 
2855 //*************************************************************************************************
2866 template< typename MT // Type of the dense matrix
2867  , size_t... CCAs > // Compile time column arguments
2868 inline typename Column<MT,false,true,false,CCAs...>::Reference
2869  Column<MT,false,true,false,CCAs...>::at( size_t index )
2870 {
2871  if( index >= size() ) {
2872  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2873  }
2874  return (*this)[index];
2875 }
2877 //*************************************************************************************************
2878 
2879 
2880 //*************************************************************************************************
2891 template< typename MT // Type of the dense matrix
2892  , size_t... CCAs > // Compile time column arguments
2893 inline typename Column<MT,false,true,false,CCAs...>::ConstReference
2894  Column<MT,false,true,false,CCAs...>::at( size_t index ) const
2895 {
2896  if( index >= size() ) {
2897  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2898  }
2899  return (*this)[index];
2900 }
2902 //*************************************************************************************************
2903 
2904 
2905 //*************************************************************************************************
2914 template< typename MT // Type of the dense matrix
2915  , size_t... CCAs > // Compile time column arguments
2916 inline typename Column<MT,false,true,false,CCAs...>::Pointer
2918 {
2919  return matrix_.data() + column();
2920 }
2922 //*************************************************************************************************
2923 
2924 
2925 //*************************************************************************************************
2934 template< typename MT // Type of the dense matrix
2935  , size_t... CCAs > // Compile time column arguments
2936 inline typename Column<MT,false,true,false,CCAs...>::ConstPointer
2938 {
2939  return matrix_.data() + column();
2940 }
2942 //*************************************************************************************************
2943 
2944 
2945 //*************************************************************************************************
2953 template< typename MT // Type of the dense matrix
2954  , size_t... CCAs > // Compile time column arguments
2955 inline typename Column<MT,false,true,false,CCAs...>::Iterator
2957 {
2958  return Iterator( matrix_, 0UL, column() );
2959 }
2961 //*************************************************************************************************
2962 
2963 
2964 //*************************************************************************************************
2972 template< typename MT // Type of the dense matrix
2973  , size_t... CCAs > // Compile time column arguments
2974 inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
2976 {
2977  return ConstIterator( matrix_, 0UL, column() );
2978 }
2980 //*************************************************************************************************
2981 
2982 
2983 //*************************************************************************************************
2991 template< typename MT // Type of the dense matrix
2992  , size_t... CCAs > // Compile time column arguments
2993 inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
2995 {
2996  return ConstIterator( matrix_, 0UL, column() );
2997 }
2999 //*************************************************************************************************
3000 
3001 
3002 //*************************************************************************************************
3010 template< typename MT // Type of the dense matrix
3011  , size_t... CCAs > // Compile time column arguments
3012 inline typename Column<MT,false,true,false,CCAs...>::Iterator
3014 {
3015  return Iterator( matrix_, size(), column() );
3016 }
3018 //*************************************************************************************************
3019 
3020 
3021 //*************************************************************************************************
3029 template< typename MT // Type of the dense matrix
3030  , size_t... CCAs > // Compile time column arguments
3031 inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
3033 {
3034  return ConstIterator( matrix_, size(), column() );
3035 }
3037 //*************************************************************************************************
3038 
3039 
3040 //*************************************************************************************************
3048 template< typename MT // Type of the dense matrix
3049  , size_t... CCAs > // Compile time column arguments
3050 inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
3052 {
3053  return ConstIterator( matrix_, size(), column() );
3054 }
3056 //*************************************************************************************************
3057 
3058 
3059 
3060 
3061 //=================================================================================================
3062 //
3063 // ASSIGNMENT OPERATORS
3064 //
3065 //=================================================================================================
3066 
3067 //*************************************************************************************************
3078 template< typename MT // Type of the dense matrix
3079  , size_t... CCAs > // Compile time column arguments
3080 inline Column<MT,false,true,false,CCAs...>&
3081  Column<MT,false,true,false,CCAs...>::operator=( const ElementType& rhs )
3082 {
3083  decltype(auto) left( derestrict( matrix_ ) );
3084 
3085  const size_t ibegin( ( IsLower<MT>::value )
3086  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3087  ?( column()+1UL )
3088  :( column() ) )
3089  :( 0UL ) );
3090  const size_t iend ( ( IsUpper<MT>::value )
3091  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3092  ?( column() )
3093  :( column()+1UL ) )
3094  :( size() ) );
3095 
3096  for( size_t i=ibegin; i<iend; ++i ) {
3097  if( !IsRestricted<MT>::value || IsTriangular<MT>::value || trySet( matrix_, i, column(), rhs ) )
3098  left(i,column()) = rhs;
3099  }
3100 
3101  return *this;
3102 }
3104 //*************************************************************************************************
3105 
3106 
3107 //*************************************************************************************************
3122 template< typename MT // Type of the dense matrix
3123  , size_t... CCAs > // Compile time column arguments
3124 inline Column<MT,false,true,false,CCAs...>&
3125  Column<MT,false,true,false,CCAs...>::operator=( initializer_list<ElementType> list )
3126 {
3127  if( list.size() > size() ) {
3128  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
3129  }
3130 
3131  if( IsRestricted<MT>::value ) {
3132  const InitializerVector<ElementType,false> tmp( list, size() );
3133  if( !tryAssign( matrix_, tmp, 0UL, column() ) ) {
3134  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3135  }
3136  }
3137 
3138  decltype(auto) left( derestrict( *this ) );
3139 
3140  std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
3141 
3142  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3143 
3144  return *this;
3145 }
3147 //*************************************************************************************************
3148 
3149 
3150 //*************************************************************************************************
3164 template< typename MT // Type of the dense matrix
3165  , size_t... CCAs > // Compile time column arguments
3166 inline Column<MT,false,true,false,CCAs...>&
3167  Column<MT,false,true,false,CCAs...>::operator=( const Column& rhs )
3168 {
3169  if( &rhs == this ) return *this;
3170 
3171  if( size() != rhs.size() ) {
3172  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
3173  }
3174 
3175  if( !tryAssign( matrix_, rhs, 0UL, column() ) ) {
3176  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3177  }
3178 
3179  decltype(auto) left( derestrict( *this ) );
3180 
3181  if( IsExpression<MT>::value && rhs.canAlias( &matrix_ ) ) {
3182  const ResultType tmp( rhs );
3183  smpAssign( left, tmp );
3184  }
3185  else {
3186  smpAssign( left, rhs );
3187  }
3188 
3189  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3190 
3191  return *this;
3192 }
3194 //*************************************************************************************************
3195 
3196 
3197 //*************************************************************************************************
3211 template< typename MT // Type of the dense matrix
3212  , size_t... CCAs > // Compile time column arguments
3213 template< typename VT > // Type of the right-hand side vector
3214 inline Column<MT,false,true,false,CCAs...>&
3215  Column<MT,false,true,false,CCAs...>::operator=( const Vector<VT,false>& rhs )
3216 {
3220 
3221  if( size() != (~rhs).size() ) {
3222  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3223  }
3224 
3225  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3226  Right right( ~rhs );
3227 
3228  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
3229  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3230  }
3231 
3232  decltype(auto) left( derestrict( *this ) );
3233 
3234  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3235  const ResultType tmp( right );
3236  smpAssign( left, tmp );
3237  }
3238  else {
3239  if( IsSparseVector<VT>::value )
3240  reset();
3241  smpAssign( left, right );
3242  }
3243 
3244  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3245 
3246  return *this;
3247 }
3249 //*************************************************************************************************
3250 
3251 
3252 //*************************************************************************************************
3266 template< typename MT // Type of the dense matrix
3267  , size_t... CCAs > // Compile time column arguments
3268 template< typename VT > // Type of the right-hand side vector
3269 inline Column<MT,false,true,false,CCAs...>&
3270  Column<MT,false,true,false,CCAs...>::operator+=( const Vector<VT,false>& rhs )
3271 {
3272  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3274 
3275  if( size() != (~rhs).size() ) {
3276  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3277  }
3278 
3279  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3280  Right right( ~rhs );
3281 
3282  if( !tryAddAssign( matrix_, right, 0UL, column() ) ) {
3283  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3284  }
3285 
3286  decltype(auto) left( derestrict( *this ) );
3287 
3288  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3289  const ResultType_<VT> tmp( right );
3290  smpAddAssign( left, tmp );
3291  }
3292  else {
3293  smpAddAssign( left, right );
3294  }
3295 
3296  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3297 
3298  return *this;
3299 }
3301 //*************************************************************************************************
3302 
3303 
3304 //*************************************************************************************************
3318 template< typename MT // Type of the dense matrix
3319  , size_t... CCAs > // Compile time column arguments
3320 template< typename VT > // Type of the right-hand side vector
3321 inline Column<MT,false,true,false,CCAs...>&
3322  Column<MT,false,true,false,CCAs...>::operator-=( const Vector<VT,false>& rhs )
3323 {
3324  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3326 
3327  if( size() != (~rhs).size() ) {
3328  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3329  }
3330 
3331  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3332  Right right( ~rhs );
3333 
3334  if( !trySubAssign( matrix_, right, 0UL, column() ) ) {
3335  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3336  }
3337 
3338  decltype(auto) left( derestrict( *this ) );
3339 
3340  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3341  const ResultType_<VT> tmp( right );
3342  smpSubAssign( left, tmp );
3343  }
3344  else {
3345  smpSubAssign( left, right );
3346  }
3347 
3348  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3349 
3350  return *this;
3351 }
3353 //*************************************************************************************************
3354 
3355 
3356 //*************************************************************************************************
3369 template< typename MT // Type of the dense matrix
3370  , size_t... CCAs > // Compile time column arguments
3371 template< typename VT > // Type of the right-hand side vector
3372 inline Column<MT,false,true,false,CCAs...>&
3373  Column<MT,false,true,false,CCAs...>::operator*=( const Vector<VT,false>& rhs )
3374 {
3375  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3377 
3378  if( size() != (~rhs).size() ) {
3379  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3380  }
3381 
3382  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3383  Right right( ~rhs );
3384 
3385  if( !tryMultAssign( matrix_, right, 0UL, column() ) ) {
3386  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3387  }
3388 
3389  decltype(auto) left( derestrict( *this ) );
3390 
3391  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3392  const ResultType_<VT> tmp( right );
3393  smpMultAssign( left, tmp );
3394  }
3395  else {
3396  smpMultAssign( left, right );
3397  }
3398 
3399  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3400 
3401  return *this;
3402 }
3404 //*************************************************************************************************
3405 
3406 
3407 //*************************************************************************************************
3419 template< typename MT // Type of the dense matrix
3420  , size_t... CCAs > // Compile time column arguments
3421 template< typename VT > // Type of the right-hand side dense vector
3422 inline Column<MT,false,true,false,CCAs...>&
3423  Column<MT,false,true,false,CCAs...>::operator/=( const DenseVector<VT,false>& rhs )
3424 {
3425  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3427 
3428  if( size() != (~rhs).size() ) {
3429  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3430  }
3431 
3432  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
3433  Right right( ~rhs );
3434 
3435  if( !tryDivAssign( matrix_, right, 0UL, column() ) ) {
3436  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3437  }
3438 
3439  decltype(auto) left( derestrict( *this ) );
3440 
3441  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
3442  const ResultType_<VT> tmp( right );
3443  smpDivAssign( left, tmp );
3444  }
3445  else {
3446  smpDivAssign( left, right );
3447  }
3448 
3449  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3450 
3451  return *this;
3452 }
3454 //*************************************************************************************************
3455 
3456 
3457 //*************************************************************************************************
3470 template< typename MT // Type of the dense matrix
3471  , size_t... CCAs > // Compile time column arguments
3472 template< typename VT > // Type of the right-hand side vector
3473 inline Column<MT,false,true,false,CCAs...>&
3474  Column<MT,false,true,false,CCAs...>::operator%=( const Vector<VT,false>& rhs )
3475 {
3476  using blaze::assign;
3477 
3478  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
3480 
3481  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
3482 
3486 
3487  if( size() != 3UL || (~rhs).size() != 3UL ) {
3488  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3489  }
3490 
3491  const CrossType right( *this % (~rhs) );
3492 
3493  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
3494  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3495  }
3496 
3497  decltype(auto) left( derestrict( *this ) );
3498 
3499  assign( left, right );
3500 
3501  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3502 
3503  return *this;
3504 }
3506 //*************************************************************************************************
3507 
3508 
3509 
3510 
3511 //=================================================================================================
3512 //
3513 // UTILITY FUNCTIONS
3514 //
3515 //=================================================================================================
3516 
3517 //*************************************************************************************************
3523 template< typename MT // Type of the dense matrix
3524  , size_t... CCAs > // Compile time column arguments
3525 inline MT& Column<MT,false,true,false,CCAs...>::operand() noexcept
3526 {
3527  return matrix_;
3528 }
3530 //*************************************************************************************************
3531 
3532 
3533 //*************************************************************************************************
3539 template< typename MT // Type of the dense matrix
3540  , size_t... CCAs > // Compile time column arguments
3541 inline const MT& Column<MT,false,true,false,CCAs...>::operand() const noexcept
3542 {
3543  return matrix_;
3544 }
3546 //*************************************************************************************************
3547 
3548 
3549 //*************************************************************************************************
3555 template< typename MT // Type of the dense matrix
3556  , size_t... CCAs > // Compile time column arguments
3557 inline size_t Column<MT,false,true,false,CCAs...>::size() const noexcept
3558 {
3559  return matrix_.rows();
3560 }
3562 //*************************************************************************************************
3563 
3564 
3565 //*************************************************************************************************
3574 template< typename MT // Type of the dense matrix
3575  , size_t... CCAs > // Compile time column arguments
3576 inline size_t Column<MT,false,true,false,CCAs...>::spacing() const noexcept
3577 {
3578  return matrix_.spacing();
3579 }
3581 //*************************************************************************************************
3582 
3583 
3584 //*************************************************************************************************
3590 template< typename MT // Type of the dense matrix
3591  , size_t... CCAs > // Compile time column arguments
3592 inline size_t Column<MT,false,true,false,CCAs...>::capacity() const noexcept
3593 {
3594  return matrix_.rows();
3595 }
3597 //*************************************************************************************************
3598 
3599 
3600 //*************************************************************************************************
3609 template< typename MT // Type of the dense matrix
3610  , size_t... CCAs > // Compile time column arguments
3612 {
3613  const size_t rows( size() );
3614  size_t nonzeros( 0UL );
3615 
3616  for( size_t i=0UL; i<rows; ++i )
3617  if( !isDefault( matrix_(i,column()) ) )
3618  ++nonzeros;
3619 
3620  return nonzeros;
3621 }
3623 //*************************************************************************************************
3624 
3625 
3626 //*************************************************************************************************
3632 template< typename MT // Type of the dense matrix
3633  , size_t... CCAs > // Compile time column arguments
3635 {
3636  using blaze::clear;
3637 
3638  const size_t ibegin( ( IsLower<MT>::value )
3639  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
3640  ?( column()+1UL )
3641  :( column() ) )
3642  :( 0UL ) );
3643  const size_t iend ( ( IsUpper<MT>::value )
3644  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
3645  ?( column() )
3646  :( column()+1UL ) )
3647  :( size() ) );
3648 
3649  for( size_t i=ibegin; i<iend; ++i )
3650  clear( matrix_(i,column()) );
3651 }
3653 //*************************************************************************************************
3654 
3655 
3656 
3657 
3658 //=================================================================================================
3659 //
3660 // NUMERIC FUNCTIONS
3661 //
3662 //=================================================================================================
3663 
3664 //*************************************************************************************************
3677 template< typename MT // Type of the dense matrix
3678  , size_t... CCAs > // Compile time column arguments
3679 template< typename Other > // Data type of the scalar value
3680 inline Column<MT,false,true,false,CCAs...>&
3681  Column<MT,false,true,false,CCAs...>::scale( const Other& scalar )
3682 {
3684 
3685  const size_t ibegin( ( IsLower<MT>::value )
3686  ?( ( IsStrictlyLower<MT>::value )
3687  ?( column()+1UL )
3688  :( column() ) )
3689  :( 0UL ) );
3690  const size_t iend ( ( IsUpper<MT>::value )
3691  ?( ( IsStrictlyUpper<MT>::value )
3692  ?( column() )
3693  :( column()+1UL ) )
3694  :( size() ) );
3695 
3696  for( size_t i=ibegin; i<iend; ++i ) {
3697  matrix_(i,column()) *= scalar;
3698  }
3699 
3700  return *this;
3701 }
3703 //*************************************************************************************************
3704 
3705 
3706 
3707 
3708 //=================================================================================================
3709 //
3710 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3711 //
3712 //=================================================================================================
3713 
3714 //*************************************************************************************************
3725 template< typename MT // Type of the dense matrix
3726  , size_t... CCAs > // Compile time column arguments
3727 template< typename Other > // Data type of the foreign expression
3728 inline bool Column<MT,false,true,false,CCAs...>::canAlias( const Other* alias ) const noexcept
3729 {
3730  return matrix_.isAliased( alias );
3731 }
3733 //*************************************************************************************************
3734 
3735 
3736 //*************************************************************************************************
3747 template< typename MT // Type of the dense matrix
3748  , size_t... CCAs > // Compile time column arguments
3749 template< typename MT2 // Data type of the foreign dense column
3750  , bool SO2 // Storage order of the foreign dense column
3751  , bool SF2 // Symmetry flag of the foreign dense column
3752  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
3753 inline bool
3754  Column<MT,false,true,false,CCAs...>::canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
3755 {
3756  return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
3757 }
3759 //*************************************************************************************************
3760 
3761 
3762 //*************************************************************************************************
3773 template< typename MT // Type of the dense matrix
3774  , size_t... CCAs > // Compile time column arguments
3775 template< typename Other > // Data type of the foreign expression
3776 inline bool Column<MT,false,true,false,CCAs...>::isAliased( const Other* alias ) const noexcept
3777 {
3778  return matrix_.isAliased( alias );
3779 }
3781 //*************************************************************************************************
3782 
3783 
3784 //*************************************************************************************************
3795 template< typename MT // Type of the dense matrix
3796  , size_t... CCAs > // Compile time column arguments
3797 template< typename MT2 // Data type of the foreign dense column
3798  , bool SO2 // Storage order of the foreign dense column
3799  , bool SF2 // Symmetry flag of the foreign dense column
3800  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
3801 inline bool
3802  Column<MT,false,true,false,CCAs...>::isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
3803 {
3804  return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
3805 }
3807 //*************************************************************************************************
3808 
3809 
3810 //*************************************************************************************************
3820 template< typename MT // Type of the dense matrix
3821  , size_t... CCAs > // Compile time column arguments
3822 inline bool Column<MT,false,true,false,CCAs...>::isAligned() const noexcept
3823 {
3824  return false;
3825 }
3827 //*************************************************************************************************
3828 
3829 
3830 //*************************************************************************************************
3841 template< typename MT // Type of the dense matrix
3842  , size_t... CCAs > // Compile time column arguments
3843 inline bool Column<MT,false,true,false,CCAs...>::canSMPAssign() const noexcept
3844 {
3845  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3846 }
3848 //*************************************************************************************************
3849 
3850 
3851 //*************************************************************************************************
3863 template< typename MT // Type of the dense matrix
3864  , size_t... CCAs > // Compile time column arguments
3865 template< typename VT > // Type of the right-hand side dense vector
3866 inline void Column<MT,false,true,false,CCAs...>::assign( const DenseVector<VT,false>& rhs )
3867 {
3868  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3869 
3870  const size_t ipos( (~rhs).size() & size_t(-2) );
3871  for( size_t i=0UL; i<ipos; i+=2UL ) {
3872  matrix_(i ,column()) = (~rhs)[i ];
3873  matrix_(i+1UL,column()) = (~rhs)[i+1UL];
3874  }
3875  if( ipos < (~rhs).size() )
3876  matrix_(ipos,column()) = (~rhs)[ipos];
3877 }
3879 //*************************************************************************************************
3880 
3881 
3882 //*************************************************************************************************
3894 template< typename MT // Type of the dense matrix
3895  , size_t... CCAs > // Compile time column arguments
3896 template< typename VT > // Type of the right-hand side sparse vector
3897 inline void Column<MT,false,true,false,CCAs...>::assign( const SparseVector<VT,false>& rhs )
3898 {
3899  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3900 
3901  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3902  matrix_(element->index(),column()) = element->value();
3903 }
3905 //*************************************************************************************************
3906 
3907 
3908 //*************************************************************************************************
3920 template< typename MT // Type of the dense matrix
3921  , size_t... CCAs > // Compile time column arguments
3922 template< typename VT > // Type of the right-hand side dense vector
3923 inline void Column<MT,false,true,false,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
3924 {
3925  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3926 
3927  const size_t ipos( (~rhs).size() & size_t(-2) );
3928  for( size_t i=0UL; i<ipos; i+=2UL ) {
3929  matrix_(i ,column()) += (~rhs)[i ];
3930  matrix_(i+1UL,column()) += (~rhs)[i+1UL];
3931  }
3932  if( ipos < (~rhs).size() )
3933  matrix_(ipos,column()) += (~rhs)[ipos];
3934 }
3936 //*************************************************************************************************
3937 
3938 
3939 //*************************************************************************************************
3951 template< typename MT // Type of the dense matrix
3952  , size_t... CCAs > // Compile time column arguments
3953 template< typename VT > // Type of the right-hand side sparse vector
3954 inline void Column<MT,false,true,false,CCAs...>::addAssign( const SparseVector<VT,false>& rhs )
3955 {
3956  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3957 
3958  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3959  matrix_(element->index(),column()) += element->value();
3960 }
3962 //*************************************************************************************************
3963 
3964 
3965 //*************************************************************************************************
3977 template< typename MT // Type of the dense matrix
3978  , size_t... CCAs > // Compile time column arguments
3979 template< typename VT > // Type of the right-hand side dense vector
3980 inline void Column<MT,false,true,false,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
3981 {
3982  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3983 
3984  const size_t ipos( (~rhs).size() & size_t(-2) );
3985  for( size_t i=0UL; i<ipos; i+=2UL ) {
3986  matrix_(i ,column()) -= (~rhs)[i ];
3987  matrix_(i+1UL,column()) -= (~rhs)[i+1UL];
3988  }
3989  if( ipos < (~rhs).size() )
3990  matrix_(ipos,column()) -= (~rhs)[ipos];
3991 }
3993 //*************************************************************************************************
3994 
3995 
3996 //*************************************************************************************************
4008 template< typename MT // Type of the dense matrix
4009  , size_t... CCAs > // Compile time column arguments
4010 template< typename VT > // Type of the right-hand side sparse vector
4011 inline void Column<MT,false,true,false,CCAs...>::subAssign( const SparseVector<VT,false>& rhs )
4012 {
4013  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4014 
4015  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4016  matrix_(element->index(),column()) -= element->value();
4017 }
4019 //*************************************************************************************************
4020 
4021 
4022 //*************************************************************************************************
4034 template< typename MT // Type of the dense matrix
4035  , size_t... CCAs > // Compile time column arguments
4036 template< typename VT > // Type of the right-hand side dense vector
4037 inline void Column<MT,false,true,false,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
4038 {
4039  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4040 
4041  const size_t ipos( (~rhs).size() & size_t(-2) );
4042  for( size_t i=0UL; i<ipos; i+=2UL ) {
4043  matrix_(i ,column()) *= (~rhs)[i ];
4044  matrix_(i+1UL,column()) *= (~rhs)[i+1UL];
4045  }
4046  if( ipos < (~rhs).size() )
4047  matrix_(ipos,column()) *= (~rhs)[ipos];
4048 }
4050 //*************************************************************************************************
4051 
4052 
4053 //*************************************************************************************************
4065 template< typename MT // Type of the dense matrix
4066  , size_t... CCAs > // Compile time column arguments
4067 template< typename VT > // Type of the right-hand side sparse vector
4068 inline void Column<MT,false,true,false,CCAs...>::multAssign( const SparseVector<VT,false>& rhs )
4069 {
4070  using blaze::reset;
4071 
4072  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4073 
4074  size_t i( 0UL );
4075 
4076  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
4077  const size_t index( element->index() );
4078  for( ; i<index; ++i )
4079  reset( matrix_(i,column()) );
4080  matrix_(i,column()) *= element->value();
4081  ++i;
4082  }
4083 
4084  for( ; i<size(); ++i ) {
4085  reset( matrix_(i,column()) );
4086  }
4087 }
4089 //*************************************************************************************************
4090 
4091 
4092 //*************************************************************************************************
4104 template< typename MT // Type of the dense matrix
4105  , size_t... CCAs > // Compile time column arguments
4106 template< typename VT > // Type of the right-hand side dense vector
4107 inline void Column<MT,false,true,false,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
4108 {
4109  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4110 
4111  const size_t ipos( (~rhs).size() & size_t(-2) );
4112  for( size_t i=0UL; i<ipos; i+=2UL ) {
4113  matrix_(i ,column()) /= (~rhs)[i ];
4114  matrix_(i+1UL,column()) /= (~rhs)[i+1UL];
4115  }
4116  if( ipos < (~rhs).size() )
4117  matrix_(ipos,column()) /= (~rhs)[ipos];
4118 }
4120 //*************************************************************************************************
4121 
4122 
4123 
4124 
4125 
4126 
4127 
4128 
4129 //=================================================================================================
4130 //
4131 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
4132 //
4133 //=================================================================================================
4134 
4135 //*************************************************************************************************
4143 template< typename MT // Type of the dense matrix
4144  , size_t... CCAs > // Compile time column arguments
4145 class Column<MT,false,true,true,CCAs...>
4146  : public View< DenseVector< Column<MT,false,true,true,CCAs...>, false > >
4147  , private ColumnData<CCAs...>
4148 {
4149  private:
4150  //**Type definitions****************************************************************************
4151  using DataType = ColumnData<CCAs...>;
4152  using Operand = If_< IsExpression<MT>, MT, MT& >;
4153  //**********************************************************************************************
4154 
4155  public:
4156  //**Type definitions****************************************************************************
4158  using This = Column<MT,false,true,true,CCAs...>;
4159 
4160  using BaseType = DenseVector<This,false>;
4161  using ViewedType = MT;
4162  using ResultType = ColumnTrait_<MT,CCAs...>;
4163  using TransposeType = TransposeType_<ResultType>;
4164  using ElementType = ElementType_<MT>;
4165  using SIMDType = SIMDTrait_<ElementType>;
4166  using ReturnType = ReturnType_<MT>;
4167  using CompositeType = const Column&;
4168 
4170  using ConstReference = ConstReference_<MT>;
4171 
4173  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
4174 
4176  using ConstPointer = ConstPointer_<MT>;
4177 
4179  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, Pointer_<MT> >;
4180 
4182  using ConstIterator = ConstIterator_<MT>;
4183 
4185  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
4186  //**********************************************************************************************
4187 
4188  //**Compilation flags***************************************************************************
4190  enum : bool { simdEnabled = MT::simdEnabled };
4191 
4193  enum : bool { smpAssignable = MT::smpAssignable };
4194  //**********************************************************************************************
4195 
4196  //**Constructors********************************************************************************
4199  template< typename... RCAs >
4200  explicit inline Column( MT& matrix, RCAs... args );
4201  // No explicitly declared copy constructor.
4203  //**********************************************************************************************
4204 
4205  //**Destructor**********************************************************************************
4206  // No explicitly declared destructor.
4207  //**********************************************************************************************
4208 
4209  //**Data access functions***********************************************************************
4212  inline Reference operator[]( size_t index );
4213  inline ConstReference operator[]( size_t index ) const;
4214  inline Reference at( size_t index );
4215  inline ConstReference at( size_t index ) const;
4216  inline Pointer data () noexcept;
4217  inline ConstPointer data () const noexcept;
4218  inline Iterator begin ();
4219  inline ConstIterator begin () const;
4220  inline ConstIterator cbegin() const;
4221  inline Iterator end ();
4222  inline ConstIterator end () const;
4223  inline ConstIterator cend () const;
4225  //**********************************************************************************************
4226 
4227  //**Assignment operators************************************************************************
4230  inline Column& operator=( const ElementType& rhs );
4231  inline Column& operator=( initializer_list<ElementType> list );
4232  inline Column& operator=( const Column& rhs );
4233 
4234  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
4235  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
4236  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
4237  template< typename VT > inline Column& operator*=( const Vector<VT,false>& rhs );
4238  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
4239  template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
4241  //**********************************************************************************************
4242 
4243  //**Utility functions***************************************************************************
4246  using DataType::column;
4247 
4248  inline MT& operand() noexcept;
4249  inline const MT& operand() const noexcept;
4250 
4251  inline size_t size() const noexcept;
4252  inline size_t spacing() const noexcept;
4253  inline size_t capacity() const noexcept;
4254  inline size_t nonZeros() const;
4255  inline void reset();
4257  //**********************************************************************************************
4258 
4259  //**Numeric functions***************************************************************************
4262  template< typename Other > inline Column& scale( const Other& scalar );
4264  //**********************************************************************************************
4265 
4266  private:
4267  //**********************************************************************************************
4269  template< typename VT >
4270  struct VectorizedAssign {
4271  enum : bool { value = useOptimizedKernels &&
4272  simdEnabled && VT::simdEnabled &&
4273  IsSIMDCombinable< ElementType, ElementType_<VT> >::value };
4274  };
4275  //**********************************************************************************************
4276 
4277  //**********************************************************************************************
4279  template< typename VT >
4280  struct VectorizedAddAssign {
4281  enum : bool { value = useOptimizedKernels &&
4282  simdEnabled && VT::simdEnabled &&
4283  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4284  HasSIMDAdd< ElementType, ElementType_<VT> >::value };
4285  };
4286  //**********************************************************************************************
4287 
4288  //**********************************************************************************************
4290  template< typename VT >
4291  struct VectorizedSubAssign {
4292  enum : bool { value = useOptimizedKernels &&
4293  simdEnabled && VT::simdEnabled &&
4294  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4295  HasSIMDSub< ElementType, ElementType_<VT> >::value };
4296  };
4297  //**********************************************************************************************
4298 
4299  //**********************************************************************************************
4301  template< typename VT >
4302  struct VectorizedMultAssign {
4303  enum : bool { value = useOptimizedKernels &&
4304  simdEnabled && VT::simdEnabled &&
4305  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4306  HasSIMDMult< ElementType, ElementType_<VT> >::value };
4307  };
4308  //**********************************************************************************************
4309 
4310  //**********************************************************************************************
4312  template< typename VT >
4313  struct VectorizedDivAssign {
4314  enum : bool { value = useOptimizedKernels &&
4315  simdEnabled && VT::simdEnabled &&
4316  IsSIMDCombinable< ElementType, ElementType_<VT> >::value &&
4317  HasSIMDDiv< ElementType, ElementType_<VT> >::value };
4318  };
4319  //**********************************************************************************************
4320 
4321  //**SIMD properties*****************************************************************************
4323  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
4324  //**********************************************************************************************
4325 
4326  public:
4327  //**Expression template evaluation functions****************************************************
4330  template< typename Other >
4331  inline bool canAlias( const Other* alias ) const noexcept;
4332 
4333  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
4334  inline bool canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
4335 
4336  template< typename Other >
4337  inline bool isAliased( const Other* alias ) const noexcept;
4338 
4339  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
4340  inline bool isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
4341 
4342  inline bool isAligned () const noexcept;
4343  inline bool canSMPAssign() const noexcept;
4344 
4345  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4346  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4347  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4348 
4349  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4350  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4351  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4352  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4353 
4354  template< typename VT >
4355  inline DisableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
4356 
4357  template< typename VT >
4358  inline EnableIf_< VectorizedAssign<VT> > assign( const DenseVector<VT,false>& rhs );
4359 
4360  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
4361 
4362  template< typename VT >
4363  inline DisableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
4364 
4365  template< typename VT >
4366  inline EnableIf_< VectorizedAddAssign<VT> > addAssign( const DenseVector<VT,false>& rhs );
4367 
4368  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
4369 
4370  template< typename VT >
4371  inline DisableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
4372 
4373  template< typename VT >
4374  inline EnableIf_< VectorizedSubAssign<VT> > subAssign( const DenseVector<VT,false>& rhs );
4375 
4376  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
4377 
4378  template< typename VT >
4379  inline DisableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
4380 
4381  template< typename VT >
4382  inline EnableIf_< VectorizedMultAssign<VT> > multAssign( const DenseVector<VT,false>& rhs );
4383 
4384  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
4385 
4386  template< typename VT >
4387  inline DisableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
4388 
4389  template< typename VT >
4390  inline EnableIf_< VectorizedDivAssign<VT> > divAssign( const DenseVector<VT,false>& rhs );
4392  //**********************************************************************************************
4393 
4394  private:
4395  //**Member variables****************************************************************************
4398  Operand matrix_;
4399 
4400  //**********************************************************************************************
4401 
4402  //**Friend declarations*************************************************************************
4403  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Column;
4404  //**********************************************************************************************
4405 
4406  //**Compile time checks*************************************************************************
4415  //**********************************************************************************************
4416 };
4418 //*************************************************************************************************
4419 
4420 
4421 
4422 
4423 //=================================================================================================
4424 //
4425 // CONSTRUCTORS
4426 //
4427 //=================================================================================================
4428 
4429 //*************************************************************************************************
4442 template< typename MT // Type of the dense matrix
4443  , size_t... CCAs > // Compile time column arguments
4444 template< typename... RCAs > // Runtime column arguments
4445 inline Column<MT,false,true,true,CCAs...>::Column( MT& matrix, RCAs... args )
4446  : DataType( args... ) // Base class initialization
4447  , matrix_ ( matrix ) // The matrix containing the column
4448 {
4449  if( !Contains< TypeList<RCAs...>, Unchecked >::value ) {
4450  if( matrix_.columns() <= column() ) {
4451  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
4452  }
4453  }
4454  else {
4455  BLAZE_USER_ASSERT( column() < matrix_.columns(), "Invalid column access index" );
4456  }
4457 }
4459 //*************************************************************************************************
4460 
4461 
4462 
4463 
4464 //=================================================================================================
4465 //
4466 // DATA ACCESS FUNCTIONS
4467 //
4468 //=================================================================================================
4469 
4470 //*************************************************************************************************
4480 template< typename MT // Type of the dense matrix
4481  , size_t... CCAs > // Compile time column arguments
4482 inline typename Column<MT,false,true,true,CCAs...>::Reference
4483  Column<MT,false,true,true,CCAs...>::operator[]( size_t index )
4484 {
4485  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4486  return matrix_(column(),index);
4487 }
4489 //*************************************************************************************************
4490 
4491 
4492 //*************************************************************************************************
4502 template< typename MT // Type of the dense matrix
4503  , size_t... CCAs > // Compile time column arguments
4504 inline typename Column<MT,false,true,true,CCAs...>::ConstReference
4505  Column<MT,false,true,true,CCAs...>::operator[]( size_t index ) const
4506 {
4507  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4508  return const_cast<const MT&>( matrix_ )(column(),index);
4509 }
4511 //*************************************************************************************************
4512 
4513 
4514 //*************************************************************************************************
4525 template< typename MT // Type of the dense matrix
4526  , size_t... CCAs > // Compile time column arguments
4527 inline typename Column<MT,false,true,true,CCAs...>::Reference
4528  Column<MT,false,true,true,CCAs...>::at( size_t index )
4529 {
4530  if( index >= size() ) {
4531  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4532  }
4533  return (*this)[index];
4534 }
4536 //*************************************************************************************************
4537 
4538 
4539 //*************************************************************************************************
4550 template< typename MT // Type of the dense matrix
4551  , size_t... CCAs > // Compile time column arguments
4552 inline typename Column<MT,false,true,true,CCAs...>::ConstReference
4553  Column<MT,false,true,true,CCAs...>::at( size_t index ) const
4554 {
4555  if( index >= size() ) {
4556  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4557  }
4558  return (*this)[index];
4559 }
4561 //*************************************************************************************************
4562 
4563 
4564 //*************************************************************************************************
4573 template< typename MT // Type of the dense matrix
4574  , size_t... CCAs > // Compile time column arguments
4575 inline typename Column<MT,false,true,true,CCAs...>::Pointer
4577 {
4578  return matrix_.data( column() );
4579 }
4581 //*************************************************************************************************
4582 
4583 
4584 //*************************************************************************************************
4593 template< typename MT // Type of the dense matrix
4594  , size_t... CCAs > // Compile time column arguments
4595 inline typename Column<MT,false,true,true,CCAs...>::ConstPointer
4597 {
4598  return matrix_.data( column() );
4599 }
4601 //*************************************************************************************************
4602 
4603 
4604 //*************************************************************************************************
4612 template< typename MT // Type of the dense matrix
4613  , size_t... CCAs > // Compile time column arguments
4614 inline typename Column<MT,false,true,true,CCAs...>::Iterator
4616 {
4617  return matrix_.begin( column() );
4618 }
4620 //*************************************************************************************************
4621 
4622 
4623 //*************************************************************************************************
4631 template< typename MT // Type of the dense matrix
4632  , size_t... CCAs > // Compile time column arguments
4633 inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4635 {
4636  return matrix_.cbegin( column() );
4637 }
4639 //*************************************************************************************************
4640 
4641 
4642 //*************************************************************************************************
4650 template< typename MT // Type of the dense matrix
4651  , size_t... CCAs > // Compile time column arguments
4652 inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4654 {
4655  return matrix_.cbegin( column() );
4656 }
4658 //*************************************************************************************************
4659 
4660 
4661 //*************************************************************************************************
4669 template< typename MT // Type of the dense matrix
4670  , size_t... CCAs > // Compile time column arguments
4671 inline typename Column<MT,false,true,true,CCAs...>::Iterator
4673 {
4674  return matrix_.end( column() );
4675 }
4677 //*************************************************************************************************
4678 
4679 
4680 //*************************************************************************************************
4688 template< typename MT // Type of the dense matrix
4689  , size_t... CCAs > // Compile time column arguments
4690 inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4692 {
4693  return matrix_.cend( column() );
4694 }
4696 //*************************************************************************************************
4697 
4698 
4699 //*************************************************************************************************
4707 template< typename MT // Type of the dense matrix
4708  , size_t... CCAs > // Compile time column arguments
4709 inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4711 {
4712  return matrix_.cend( column() );
4713 }
4715 //*************************************************************************************************
4716 
4717 
4718 
4719 
4720 //=================================================================================================
4721 //
4722 // ASSIGNMENT OPERATORS
4723 //
4724 //=================================================================================================
4725 
4726 //*************************************************************************************************
4733 template< typename MT // Type of the dense matrix
4734  , size_t... CCAs > // Compile time column arguments
4735 inline Column<MT,false,true,true,CCAs...>&
4736  Column<MT,false,true,true,CCAs...>::operator=( const ElementType& rhs )
4737 {
4738  decltype(auto) left( derestrict( matrix_ ) );
4739 
4740  const size_t jbegin( ( IsUpper<MT>::value )
4741  ?( ( IsUniUpper<MT>::value || IsStrictlyUpper<MT>::value )
4742  ?( column()+1UL )
4743  :( column() ) )
4744  :( 0UL ) );
4745  const size_t jend ( ( IsLower<MT>::value )
4746  ?( ( IsUniLower<MT>::value || IsStrictlyLower<MT>::value )
4747  ?( column() )
4748  :( column()+1UL ) )
4749  :( size() ) );
4750 
4751  for( size_t j=jbegin; j<jend; ++j ) {
4752  if( !IsRestricted<MT>::value || IsTriangular<MT>::value || trySet( matrix_, column(), j, rhs ) )
4753  left(column(),j) = rhs;
4754  }
4755 
4756  return *this;
4757 }
4759 //*************************************************************************************************
4760 
4761 
4762 //*************************************************************************************************
4777 template< typename MT // Type of the dense matrix
4778  , size_t... CCAs > // Compile time column arguments
4779 inline Column<MT,false,true,true,CCAs...>&
4780  Column<MT,false,true,true,CCAs...>::operator=( initializer_list<ElementType> list )
4781 {
4782  if( list.size() > size() ) {
4783  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
4784  }
4785 
4786  if( IsRestricted<MT>::value ) {
4787  const InitializerVector<ElementType,false> tmp( list, size() );
4788  if( !tryAssign( matrix_, tmp, 0UL, column() ) ) {
4789  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4790  }
4791  }
4792 
4793  decltype(auto) left( derestrict( *this ) );
4794 
4795  std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
4796 
4797  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4798 
4799  return *this;
4800 }
4802 //*************************************************************************************************
4803 
4804 
4805 //*************************************************************************************************
4819 template< typename MT // Type of the dense matrix
4820  , size_t... CCAs > // Compile time column arguments
4821 inline Column<MT,false,true,true,CCAs...>&
4822  Column<MT,false,true,true,CCAs...>::operator=( const Column& rhs )
4823 {
4824  if( &rhs == this ) return *this;
4825 
4826  if( size() != rhs.size() ) {
4827  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
4828  }
4829 
4830  if( !tryAssign( matrix_, rhs, 0UL, column() ) ) {
4831  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4832  }
4833 
4834  decltype(auto) left( derestrict( *this ) );
4835 
4836  if( IsExpression<MT>::value && rhs.canAlias( &matrix_ ) ) {
4837  const ResultType tmp( rhs );
4838  smpAssign( left, tmp );
4839  }
4840  else {
4841  smpAssign( left, rhs );
4842  }
4843 
4844  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4845 
4846  return *this;
4847 }
4849 //*************************************************************************************************
4850 
4851 
4852 //*************************************************************************************************
4866 template< typename MT // Type of the dense matrix
4867  , size_t... CCAs > // Compile time column arguments
4868 template< typename VT > // Type of the right-hand side vector
4869 inline Column<MT,false,true,true,CCAs...>&
4870  Column<MT,false,true,true,CCAs...>::operator=( const Vector<VT,false>& rhs )
4871 {
4872  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4874 
4875  if( size() != (~rhs).size() ) {
4876  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4877  }
4878 
4879  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4880  Right right( ~rhs );
4881 
4882  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
4883  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4884  }
4885 
4886  decltype(auto) left( derestrict( *this ) );
4887 
4888  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4889  const ResultType_<VT> tmp( right );
4890  smpAssign( left, tmp );
4891  }
4892  else {
4893  if( IsSparseVector<VT>::value )
4894  reset();
4895  smpAssign( left, right );
4896  }
4897 
4898  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4899 
4900  return *this;
4901 }
4903 //*************************************************************************************************
4904 
4905 
4906 //*************************************************************************************************
4920 template< typename MT // Type of the dense matrix
4921  , size_t... CCAs > // Compile time column arguments
4922 template< typename VT > // Type of the right-hand side vector
4923 inline Column<MT,false,true,true,CCAs...>&
4924  Column<MT,false,true,true,CCAs...>::operator+=( const Vector<VT,false>& rhs )
4925 {
4926  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4928 
4929  if( size() != (~rhs).size() ) {
4930  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4931  }
4932 
4933  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4934  Right right( ~rhs );
4935 
4936  if( !tryAddAssign( matrix_, right, 0UL, column() ) ) {
4937  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4938  }
4939 
4940  decltype(auto) left( derestrict( *this ) );
4941 
4942  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4943  const ResultType_<VT> tmp( right );
4944  smpAddAssign( left, tmp );
4945  }
4946  else {
4947  smpAddAssign( left, right );
4948  }
4949 
4950  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4951 
4952  return *this;
4953 }
4955 //*************************************************************************************************
4956 
4957 
4958 //*************************************************************************************************
4972 template< typename MT // Type of the dense matrix
4973  , size_t... CCAs > // Compile time column arguments
4974 template< typename VT > // Type of the right-hand side vector
4975 inline Column<MT,false,true,true,CCAs...>&
4976  Column<MT,false,true,true,CCAs...>::operator-=( const Vector<VT,false>& rhs )
4977 {
4978  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
4980 
4981  if( size() != (~rhs).size() ) {
4982  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4983  }
4984 
4985  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
4986  Right right( ~rhs );
4987 
4988  if( !trySubAssign( matrix_, right, 0UL, column() ) ) {
4989  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4990  }
4991 
4992  decltype(auto) left( derestrict( *this ) );
4993 
4994  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4995  const ResultType_<VT> tmp( right );
4996  smpSubAssign( left, tmp );
4997  }
4998  else {
4999  smpSubAssign( left, right );
5000  }
5001 
5002  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5003 
5004  return *this;
5005 }
5007 //*************************************************************************************************
5008 
5009 
5010 //*************************************************************************************************
5023 template< typename MT // Type of the dense matrix
5024  , size_t... CCAs > // Compile time column arguments
5025 template< typename VT > // Type of the right-hand side vector
5026 inline Column<MT,false,true,true,CCAs...>&
5027  Column<MT,false,true,true,CCAs...>::operator*=( const Vector<VT,false>& rhs )
5028 {
5029  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
5031 
5032  if( size() != (~rhs).size() ) {
5033  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5034  }
5035 
5036  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
5037  Right right( ~rhs );
5038 
5039  if( !tryMultAssign( matrix_, right, 0UL, column() ) ) {
5040  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5041  }
5042 
5043  decltype(auto) left( derestrict( *this ) );
5044 
5045  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
5046  const ResultType_<VT> tmp( right );
5047  smpMultAssign( left, tmp );
5048  }
5049  else {
5050  smpMultAssign( left, right );
5051  }
5052 
5053  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5054 
5055  return *this;
5056 }
5058 //*************************************************************************************************
5059 
5060 
5061 //*************************************************************************************************
5073 template< typename MT // Type of the dense matrix
5074  , size_t... CCAs > // Compile time column arguments
5075 template< typename VT > // Type of the right-hand side dense vector
5076 inline Column<MT,false,true,true,CCAs...>&
5077  Column<MT,false,true,true,CCAs...>::operator/=( const DenseVector<VT,false>& rhs )
5078 {
5079  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
5081 
5082  if( size() != (~rhs).size() ) {
5083  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5084  }
5085 
5086  using Right = If_< IsRestricted<MT>, CompositeType_<VT>, const VT& >;
5087  Right right( ~rhs );
5088 
5089  if( !tryDivAssign( matrix_, right, 0UL, column() ) ) {
5090  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5091  }
5092 
5093  decltype(auto) left( derestrict( *this ) );
5094 
5095  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
5096  const ResultType_<VT> tmp( right );
5097  smpDivAssign( left, tmp );
5098  }
5099  else {
5100  smpDivAssign( left, right );
5101  }
5102 
5103  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5104 
5105  return *this;
5106 }
5108 //*************************************************************************************************
5109 
5110 
5111 //*************************************************************************************************
5124 template< typename MT // Type of the dense matrix
5125  , size_t... CCAs > // Compile time column arguments
5126 template< typename VT > // Type of the right-hand side vector
5127 inline Column<MT,false,true,true,CCAs...>&
5128  Column<MT,false,true,true,CCAs...>::operator%=( const Vector<VT,false>& rhs )
5129 {
5130  using blaze::assign;
5131 
5132  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_<VT> );
5134 
5135  using CrossType = CrossTrait_< ResultType, ResultType_<VT> >;
5136 
5140 
5141  if( size() != 3UL || (~rhs).size() != 3UL ) {
5142  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
5143  }
5144 
5145  const CrossType right( *this % (~rhs) );
5146 
5147  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
5148  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5149  }
5150 
5151  decltype(auto) left( derestrict( *this ) );
5152 
5153  assign( left, right );
5154 
5155  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5156 
5157  return *this;
5158 }
5160 //*************************************************************************************************
5161 
5162 
5163 
5164 
5165 //=================================================================================================
5166 //
5167 // UTILITY FUNCTIONS
5168 //
5169 //=================================================================================================
5170 
5171 //*************************************************************************************************
5177 template< typename MT // Type of the dense matrix
5178  , size_t... CCAs > // Compile time column arguments
5179 inline MT& Column<MT,false,true,true,CCAs...>::operand() noexcept
5180 {
5181  return matrix_;
5182 }
5184 //*************************************************************************************************
5185 
5186 
5187 //*************************************************************************************************
5193 template< typename MT // Type of the dense matrix
5194  , size_t... CCAs > // Compile time column arguments
5195 inline const MT& Column<MT,false,true,true,CCAs...>::operand() const noexcept
5196 {
5197  return matrix_;
5198 }
5200 //*************************************************************************************************
5201 
5202 
5203 //*************************************************************************************************
5209 template< typename MT // Type of the dense matrix
5210  , size_t... CCAs > // Compile time column arguments
5211 inline size_t Column<MT,false,true,true,CCAs...>::size() const noexcept
5212 {
5213  return matrix_.rows();
5214 }
5216 //*************************************************************************************************
5217 
5218 
5219 //*************************************************************************************************
5228 template< typename MT // Type of the dense matrix
5229  , size_t... CCAs > // Compile time column arguments
5230 inline size_t Column<MT,false,true,true,CCAs...>::spacing() const noexcept
5231 {
5232  return matrix_.spacing();
5233 }
5235 //*************************************************************************************************
5236 
5237 
5238 //*************************************************************************************************
5244 template< typename MT // Type of the dense matrix
5245  , size_t... CCAs > // Compile time column arguments
5246 inline size_t Column<MT,false,true,true,CCAs...>::capacity() const noexcept
5247 {
5248  return matrix_.capacity( column() );
5249 }
5251 //*************************************************************************************************
5252 
5253 
5254 //*************************************************************************************************
5263 template< typename MT // Type of the dense matrix
5264  , size_t... CCAs > // Compile time column arguments
5266 {
5267  return matrix_.nonZeros( column() );
5268 }
5270 //*************************************************************************************************
5271 
5272 
5273 //*************************************************************************************************
5279 template< typename MT // Type of the dense matrix
5280  , size_t... CCAs > // Compile time column arguments
5282 {
5283  matrix_.reset( column() );
5284 }
5286 //*************************************************************************************************
5287 
5288 
5289 
5290 
5291 //=================================================================================================
5292 //
5293 // NUMERIC FUNCTIONS
5294 //
5295 //=================================================================================================
5296 
5297 //*************************************************************************************************
5310 template< typename MT // Type of the dense matrix
5311  , size_t... CCAs > // Compile time column arguments
5312 template< typename Other > // Data type of the scalar value
5313 inline Column<MT,false,true,true,CCAs...>&
5314  Column<MT,false,true,true,CCAs...>::scale( const Other& scalar )
5315 {
5317 
5318  const size_t jbegin( ( IsUpper<MT>::value )
5319  ?( ( IsStrictlyUpper<MT>::value )
5320  ?( column()+1UL )
5321  :( column() ) )
5322  :( 0UL ) );
5323  const size_t jend ( ( IsLower<MT>::value )
5324  ?( ( IsStrictlyLower<MT>::value )
5325  ?( column() )
5326  :( column()+1UL ) )
5327  :( size() ) );
5328 
5329  for( size_t j=jbegin; j<jend; ++j ) {
5330  matrix_(column(),j) *= scalar;
5331  }
5332 
5333  return *this;
5334 }
5336 //*************************************************************************************************
5337 
5338 
5339 
5340 
5341 //=================================================================================================
5342 //
5343 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5344 //
5345 //=================================================================================================
5346 
5347 //*************************************************************************************************
5358 template< typename MT // Type of the dense matrix
5359  , size_t... CCAs > // Compile time column arguments
5360 template< typename Other > // Data type of the foreign expression
5361 inline bool Column<MT,false,true,true,CCAs...>::canAlias( const Other* alias ) const noexcept
5362 {
5363  return matrix_.isAliased( alias );
5364 }
5366 //*************************************************************************************************
5367 
5368 
5369 //*************************************************************************************************
5380 template< typename MT // Type of the dense matrix
5381  , size_t... CCAs > // Compile time column arguments
5382 template< typename MT2 // Data type of the foreign dense column
5383  , bool SO2 // Storage order of the foreign dense column
5384  , bool SF2 // Symmetry flag of the foreign dense column
5385  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
5386 inline bool
5387  Column<MT,false,true,true,CCAs...>::canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5388 {
5389  return matrix_.isAliased( alias->matrix_ ) && ( column() == alias->column() );
5390 }
5392 //*************************************************************************************************
5393 
5394 
5395 //*************************************************************************************************
5406 template< typename MT // Type of the dense matrix
5407  , size_t... CCAs > // Compile time column arguments
5408 template< typename Other > // Data type of the foreign expression
5409 inline bool Column<MT,false,true,true,CCAs...>::isAliased( const Other* alias ) const noexcept
5410 {
5411  return matrix_.isAliased( alias );
5412 }
5414 //*************************************************************************************************
5415 
5416 
5417 //*************************************************************************************************
5428 template< typename MT // Type of the dense matrix
5429  , size_t... CCAs > // Compile time column arguments
5430 template< typename MT2 // Data type of the foreign dense column
5431  , bool SO2 // Storage order of the foreign dense column
5432  , bool SF2 // Symmetry flag of the foreign dense column
5433  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
5434 inline bool
5435  Column<MT,false,true,true,CCAs...>::isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5436 {
5437  return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
5438 }
5440 //*************************************************************************************************
5441 
5442 
5443 //*************************************************************************************************
5453 template< typename MT // Type of the dense matrix
5454  , size_t... CCAs > // Compile time column arguments
5455 inline bool Column<MT,false,true,true,CCAs...>::isAligned() const noexcept
5456 {
5457  return matrix_.isAligned();
5458 }
5460 //*************************************************************************************************
5461 
5462 
5463 //*************************************************************************************************
5474 template< typename MT // Type of the dense matrix
5475  , size_t... CCAs > // Compile time column arguments
5476 inline bool Column<MT,false,true,true,CCAs...>::canSMPAssign() const noexcept
5477 {
5478  return ( size() > SMP_DVECASSIGN_THRESHOLD );
5479 }
5481 //*************************************************************************************************
5482 
5483 
5484 //*************************************************************************************************
5496 template< typename MT // Type of the dense matrix
5497  , size_t... CCAs > // Compile time column arguments
5498 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true,CCAs...>::SIMDType
5499  Column<MT,false,true,true,CCAs...>::load( size_t index ) const noexcept
5500 {
5501  return matrix_.load( column(), index );
5502 }
5504 //*************************************************************************************************
5505 
5506 
5507 //*************************************************************************************************
5520 template< typename MT // Type of the dense matrix
5521  , size_t... CCAs > // Compile time column arguments
5522 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true,CCAs...>::SIMDType
5523  Column<MT,false,true,true,CCAs...>::loada( size_t index ) const noexcept
5524 {
5525  return matrix_.loada( column(), index );
5526 }
5528 //*************************************************************************************************
5529 
5530 
5531 //*************************************************************************************************
5544 template< typename MT // Type of the dense matrix
5545  , size_t... CCAs > // Compile time column arguments
5546 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true,CCAs...>::SIMDType
5547  Column<MT,false,true,true,CCAs...>::loadu( size_t index ) const noexcept
5548 {
5549  return matrix_.loadu( column(), index );
5550 }
5552 //*************************************************************************************************
5553 
5554 
5555 //*************************************************************************************************
5568 template< typename MT // Type of the dense matrix
5569  , size_t... CCAs > // Compile time column arguments
5571  Column<MT,false,true,true,CCAs...>::store( size_t index, const SIMDType& value ) noexcept
5572 {
5573  matrix_.store( column(), index, value );
5574 }
5576 //*************************************************************************************************
5577 
5578 
5579 //*************************************************************************************************
5593 template< typename MT // Type of the dense matrix
5594  , size_t... CCAs > // Compile time column arguments
5596  Column<MT,false,true,true,CCAs...>::storea( size_t index, const SIMDType& value ) noexcept
5597 {
5598  matrix_.storea( column(), index, value );
5599 }
5601 //*************************************************************************************************
5602 
5603 
5604 //*************************************************************************************************
5618 template< typename MT // Type of the dense matrix
5619  , size_t... CCAs > // Compile time column arguments
5621  Column<MT,false,true,true,CCAs...>::storeu( size_t index, const SIMDType& value ) noexcept
5622 {
5623  matrix_.storeu( column(), index, value );
5624 }
5626 //*************************************************************************************************
5627 
5628 
5629 //*************************************************************************************************
5643 template< typename MT // Type of the dense matrix
5644  , size_t... CCAs > // Compile time column arguments
5646  Column<MT,false,true,true,CCAs...>::stream( size_t index, const SIMDType& value ) noexcept
5647 {
5648  matrix_.stream( column(), index, value );
5649 }
5651 //*************************************************************************************************
5652 
5653 
5654 //*************************************************************************************************
5666 template< typename MT // Type of the dense matrix
5667  , size_t... CCAs > // Compile time column arguments
5668 template< typename VT > // Type of the right-hand side dense vector
5669 inline DisableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5670  Column<MT,false,true,true,CCAs...>::assign( const DenseVector<VT,false>& rhs )
5671 {
5672  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5673 
5674  const size_t jpos( (~rhs).size() & size_t(-2) );
5675  for( size_t j=0UL; j<jpos; j+=2UL ) {
5676  matrix_(column(),j ) = (~rhs)[j ];
5677  matrix_(column(),j+1UL) = (~rhs)[j+1UL];
5678  }
5679  if( jpos < (~rhs).size() )
5680  matrix_(column(),jpos) = (~rhs)[jpos];
5681 }
5683 //*************************************************************************************************
5684 
5685 
5686 //*************************************************************************************************
5698 template< typename MT // Type of the dense matrix
5699  , size_t... CCAs > // Compile time column arguments
5700 template< typename VT > // Type of the right-hand side dense vector
5701 inline EnableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedAssign<VT> >
5702  Column<MT,false,true,true,CCAs...>::assign( const DenseVector<VT,false>& rhs )
5703 {
5705 
5706  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5707 
5708  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5709 
5710  const size_t columns( size() );
5711 
5712  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5713  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5714 
5715  size_t j( 0UL );
5716  Iterator left( begin() );
5717  ConstIterator_<VT> right( (~rhs).begin() );
5718 
5719  if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
5720  {
5721  for( ; j<jpos; j+=SIMDSIZE ) {
5722  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5723  }
5724  for( ; remainder && j<columns; ++j ) {
5725  *left = *right; ++left; ++right;
5726  }
5727  }
5728  else
5729  {
5730  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5731  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5732  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5733  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5734  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5735  }
5736  for( ; j<jpos; j+=SIMDSIZE ) {
5737  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5738  }
5739  for( ; remainder && j<columns; ++j ) {
5740  *left = *right; ++left; ++right;
5741  }
5742  }
5743 }
5745 //*************************************************************************************************
5746 
5747 
5748 //*************************************************************************************************
5760 template< typename MT // Type of the dense matrix
5761  , size_t... CCAs > // Compile time column arguments
5762 template< typename VT > // Type of the right-hand side sparse vector
5763 inline void Column<MT,false,true,true,CCAs...>::assign( const SparseVector<VT,false>& rhs )
5764 {
5765  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5766 
5767  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5768  matrix_(column(),element->index()) = element->value();
5769 }
5771 //*************************************************************************************************
5772 
5773 
5774 //*************************************************************************************************
5786 template< typename MT // Type of the dense matrix
5787  , size_t... CCAs > // Compile time column arguments
5788 template< typename VT > // Type of the right-hand side dense vector
5789 inline DisableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5790  Column<MT,false,true,true,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
5791 {
5792  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5793 
5794  const size_t jpos( (~rhs).size() & size_t(-2) );
5795  for( size_t j=0UL; j<jpos; j+=2UL ) {
5796  matrix_(column(),j ) += (~rhs)[j ];
5797  matrix_(column(),j+1UL) += (~rhs)[j+1UL];
5798  }
5799  if( jpos < (~rhs).size() )
5800  matrix_(column(),jpos) += (~rhs)[jpos];
5801 }
5803 //*************************************************************************************************
5804 
5805 
5806 //*************************************************************************************************
5818 template< typename MT // Type of the dense matrix
5819  , size_t... CCAs > // Compile time column arguments
5820 template< typename VT > // Type of the right-hand side dense vector
5821 inline EnableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedAddAssign<VT> >
5822  Column<MT,false,true,true,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
5823 {
5825 
5826  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5827 
5828  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5829 
5830  const size_t columns( size() );
5831 
5832  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5833  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5834 
5835  size_t j( 0UL );
5836  Iterator left( begin() );
5837  ConstIterator_<VT> right( (~rhs).begin() );
5838 
5839  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5840  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5841  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5842  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5843  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5844  }
5845  for( ; j<jpos; j+=SIMDSIZE ) {
5846  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5847  }
5848  for( ; remainder && j<columns; ++j ) {
5849  *left += *right; ++left; ++right;
5850  }
5851 }
5853 //*************************************************************************************************
5854 
5855 
5856 //*************************************************************************************************
5868 template< typename MT // Type of the dense matrix
5869  , size_t... CCAs > // Compile time column arguments
5870 template< typename VT > // Type of the right-hand side sparse vector
5871 inline void Column<MT,false,true,true,CCAs...>::addAssign( const SparseVector<VT,false>& rhs )
5872 {
5873  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5874 
5875  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5876  matrix_(column(),element->index()) += element->value();
5877 }
5879 //*************************************************************************************************
5880 
5881 
5882 //*************************************************************************************************
5894 template< typename MT // Type of the dense matrix
5895  , size_t... CCAs > // Compile time column arguments
5896 template< typename VT > // Type of the right-hand side dense vector
5897 inline DisableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5898  Column<MT,false,true,true,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
5899 {
5900  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5901 
5902  const size_t jpos( (~rhs).size() & size_t(-2) );
5903  for( size_t j=0UL; j<jpos; j+=2UL ) {
5904  matrix_(column(),j ) -= (~rhs)[j ];
5905  matrix_(column(),j+1UL) -= (~rhs)[j+1UL];
5906  }
5907  if( jpos < (~rhs).size() )
5908  matrix_(column(),jpos) -= (~rhs)[jpos];
5909 }
5911 //*************************************************************************************************
5912 
5913 
5914 //*************************************************************************************************
5926 template< typename MT // Type of the dense matrix
5927  , size_t... CCAs > // Compile time column arguments
5928 template< typename VT > // Type of the right-hand side dense vector
5929 inline EnableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedSubAssign<VT> >
5930  Column<MT,false,true,true,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
5931 {
5933 
5934  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5935 
5936  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
5937 
5938  const size_t columns( size() );
5939 
5940  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5941  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5942 
5943  size_t j( 0UL );
5944  Iterator left( begin() );
5945  ConstIterator_<VT> right( (~rhs).begin() );
5946 
5947  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5948  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5949  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5950  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5951  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5952  }
5953  for( ; j<jpos; j+=SIMDSIZE ) {
5954  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5955  }
5956  for( ; remainder && j<columns; ++j ) {
5957  *left -= *right; ++left; ++right;
5958  }
5959 }
5961 //*************************************************************************************************
5962 
5963 
5964 //*************************************************************************************************
5976 template< typename MT // Type of the dense matrix
5977  , size_t... CCAs > // Compile time column arguments
5978 template< typename VT > // Type of the right-hand side sparse vector
5979 inline void Column<MT,false,true,true,CCAs...>::subAssign( const SparseVector<VT,false>& rhs )
5980 {
5981  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5982 
5983  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5984  matrix_(column(),element->index()) -= element->value();
5985 }
5987 //*************************************************************************************************
5988 
5989 
5990 //*************************************************************************************************
6002 template< typename MT // Type of the dense matrix
6003  , size_t... CCAs > // Compile time column arguments
6004 template< typename VT > // Type of the right-hand side dense vector
6005 inline DisableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
6006  Column<MT,false,true,true,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
6007 {
6008  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6009 
6010  const size_t jpos( (~rhs).size() & size_t(-2) );
6011  for( size_t j=0UL; j<jpos; j+=2UL ) {
6012  matrix_(column(),j ) *= (~rhs)[j ];
6013  matrix_(column(),j+1UL) *= (~rhs)[j+1UL];
6014  }
6015  if( jpos < (~rhs).size() )
6016  matrix_(column(),jpos) *= (~rhs)[jpos];
6017 }
6019 //*************************************************************************************************
6020 
6021 
6022 //*************************************************************************************************
6034 template< typename MT // Type of the dense matrix
6035  , size_t... CCAs > // Compile time column arguments
6036 template< typename VT > // Type of the right-hand side dense vector
6037 inline EnableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedMultAssign<VT> >
6038  Column<MT,false,true,true,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
6039 {
6041 
6042  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6043 
6044  constexpr bool remainder( !IsPadded<MT>::value || !IsPadded<VT>::value );
6045 
6046  const size_t columns( size() );
6047 
6048  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
6049  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
6050 
6051  size_t j( 0UL );
6052  Iterator left( begin() );
6053  ConstIterator_<VT> right( (~rhs).begin() );
6054 
6055  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
6056  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6057  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6058  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6059  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6060  }
6061  for( ; j<jpos; j+=SIMDSIZE ) {
6062  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6063  }
6064  for( ; remainder && j<columns; ++j ) {
6065  *left *= *right; ++left; ++right;
6066  }
6067 }
6069 //*************************************************************************************************
6070 
6071 
6072 //*************************************************************************************************
6084 template< typename MT // Type of the dense matrix
6085  , size_t... CCAs > // Compile time column arguments
6086 template< typename VT > // Type of the right-hand side sparse vector
6087 inline void Column<MT,false,true,true,CCAs...>::multAssign( const SparseVector<VT,false>& rhs )
6088 {
6089  using blaze::reset;
6090 
6091  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6092 
6093  size_t j( 0UL );
6094 
6095  for( ConstIterator_<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
6096  const size_t index( element->index() );
6097  for( ; j<index; ++j )
6098  reset( matrix_(column(),j) );
6099  matrix_(column(),j) *= element->value();
6100  ++j;
6101  }
6102 
6103  for( ; j<size(); ++j ) {
6104  reset( matrix_(column(),j) );
6105  }
6106 }
6108 //*************************************************************************************************
6109 
6110 
6111 //*************************************************************************************************
6123 template< typename MT // Type of the dense matrix
6124  , size_t... CCAs > // Compile time column arguments
6125 template< typename VT > // Type of the right-hand side dense vector
6126 inline DisableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
6127  Column<MT,false,true,true,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
6128 {
6129  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6130 
6131  const size_t jpos( (~rhs).size() & size_t(-2) );
6132  for( size_t j=0UL; j<jpos; j+=2UL ) {
6133  matrix_(column(),j ) /= (~rhs)[j ];
6134  matrix_(column(),j+1UL) /= (~rhs)[j+1UL];
6135  }
6136  if( jpos < (~rhs).size() )
6137  matrix_(column(),jpos) /= (~rhs)[jpos];
6138 }
6140 //*************************************************************************************************
6141 
6142 
6143 //*************************************************************************************************
6155 template< typename MT // Type of the dense matrix
6156  , size_t... CCAs > // Compile time column arguments
6157 template< typename VT > // Type of the right-hand side dense vector
6158 inline EnableIf_< typename Column<MT,false,true,true,CCAs...>::BLAZE_TEMPLATE VectorizedDivAssign<VT> >
6159  Column<MT,false,true,true,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
6160 {
6162 
6163  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6164 
6165  const size_t columns( size() );
6166 
6167  const size_t jpos( columns & size_t(-SIMDSIZE) );
6168  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
6169 
6170  size_t j( 0UL );
6171  Iterator left( begin() );
6172  ConstIterator_<VT> right( (~rhs).begin() );
6173 
6174  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
6175  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6176  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6177  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6178  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6179  }
6180  for( ; j<jpos; j+=SIMDSIZE ) {
6181  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6182  }
6183  for( ; j<columns; ++j ) {
6184  *left /= *right; ++left; ++right;
6185  }
6186 }
6188 //*************************************************************************************************
6189 
6190 } // namespace blaze
6191 
6192 #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.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:131
Header file for the blaze::checked and blaze::unchecked instances.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the IsUniUpper type trait.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:522
Header file for basic type definitions.
Header file for the View base class.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a column dense or sparse vector type...
Definition: ColumnVector.h:61
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:61
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3076
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:364
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3074
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:588
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:701
EnableIf_< IsDenseVector< VT1 > > smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP multiplication assignment of a vector to a dense vector...
Definition: DenseVector.h:193
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3078
Header file for the DenseVector base class.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3083
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:560
#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:733
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3084
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
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
STL namespace.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
Header file for the IsUniLower type trait.
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:474
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:408
Constraint on the data type.
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:252
Constraint on the transpose flag of vector types.
Constraint on the data type.
typename ColumnTrait< MT, CCAs... >::Type ColumnTrait_
Auxiliary alias declaration for the ColumnTrait type trait.The ColumnTrait_ alias declaration provide...
Definition: ColumnTrait.h:144
Header file for the DisableIf class template.
Header file for the IsStrictlyUpper type trait.
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3082
Header file for the clear shim.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
#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.
Header file for the implementation of a vector representation of an initializer list.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3079
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:367
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:443
Header file for the Not class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for all SIMD functionality.
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:506
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.
Header file for the IsTriangular type trait.
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.In case the given data type T is not a vectorizable data type...
Definition: Vectorizable.h:61
Constraint on the data type.
Header file for the exception macros of the math module.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:430
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
void clear(const DiagonalProxy< MT > &proxy)
Clearing the represented element.
Definition: DiagonalProxy.h:608
Header file for the IsPadded type trait.
Constraint on the data type.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseVector type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the cross product trait.
Header file for the Unique class template.
Check< false > Unchecked
Type of the blaze::unchecked instance.blaze::Unchecked is the type of the blaze::unchecked instance...
Definition: Check.h:96
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:131
EnableIf_< IsDenseVector< VT1 > > smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs)
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:222
Header file for the cache size of the target architecture.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Header file for the column trait.
Header file for the isDefault shim.
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
Constraints on the storage order of matrix types.
Header file for the HasMutableDataAccess type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
Header file for the RemoveReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:490
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
#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
BLAZE_ALWAYS_INLINE MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:169
EnableIf_< IsNumeric< ST >, MT &> operator/=(DenseMatrix< MT, SO > &mat, ST scalar)
Division assignment operator for the division of a dense matrix by a scalar value ( )...
Definition: DenseMatrix.h:655
Header file for the HasSIMDDiv type trait.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3081
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
Header file for the implementation of the ColumnData class template.
EnableIf_< IsNumeric< ST >, MT &> operator*=(DenseMatrix< MT, SO > &mat, ST scalar)
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( )...
Definition: DenseMatrix.h:593
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.
Constraint on the data type.