Blaze  3.6
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/shims/Reset.h>
65 #include <blaze/math/SIMD.h>
85 #include <blaze/math/views/Check.h>
88 #include <blaze/system/CacheSize.h>
89 #include <blaze/system/Inline.h>
92 #include <blaze/util/Assert.h>
96 #include <blaze/util/DisableIf.h>
97 #include <blaze/util/EnableIf.h>
98 #include <blaze/util/mpl/If.h>
99 #include <blaze/util/TypeList.h>
100 #include <blaze/util/Types.h>
103 
104 
105 namespace blaze {
106 
107 //=================================================================================================
108 //
109 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR DENSE MATRICES
110 //
111 //=================================================================================================
112 
113 //*************************************************************************************************
121 template< typename MT // Type of the dense matrix
122  , bool SF // Symmetry flag
123  , size_t... CCAs > // Compile time column arguments
124 class Column<MT,true,true,SF,CCAs...>
125  : public View< DenseVector< Column<MT,true,true,SF,CCAs...>, false > >
126  , private ColumnData<CCAs...>
127 {
128  private:
129  //**Type definitions****************************************************************************
130  using DataType = ColumnData<CCAs...>;
131  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
132  //**********************************************************************************************
133 
134  public:
135  //**Type definitions****************************************************************************
137  using This = Column<MT,true,true,SF,CCAs...>;
138 
139  using BaseType = DenseVector<This,false>;
140  using ViewedType = MT;
141  using ResultType = ColumnTrait_t<MT,CCAs...>;
142  using TransposeType = TransposeType_t<ResultType>;
143  using ElementType = ElementType_t<MT>;
144  using SIMDType = SIMDTrait_t<ElementType>;
145  using ReturnType = ReturnType_t<MT>;
146  using CompositeType = const Column&;
147 
149  using ConstReference = ConstReference_t<MT>;
150 
152  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
153 
155  using ConstPointer = ConstPointer_t<MT>;
156 
158  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
159 
161  using ConstIterator = ConstIterator_t<MT>;
162 
164  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
165  //**********************************************************************************************
166 
167  //**Compilation flags***************************************************************************
169  static constexpr bool simdEnabled = MT::simdEnabled;
170 
172  static constexpr bool smpAssignable = MT::smpAssignable;
173 
175  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
176  //**********************************************************************************************
177 
178  //**Constructors********************************************************************************
181  template< typename... RCAs >
182  explicit inline Column( MT& matrix, RCAs... args );
183 
184  Column( const Column& ) = default;
186  //**********************************************************************************************
187 
188  //**Destructor**********************************************************************************
191  ~Column() = default;
193  //**********************************************************************************************
194 
195  //**Data access functions***********************************************************************
198  inline Reference operator[]( size_t index );
199  inline ConstReference operator[]( size_t index ) const;
200  inline Reference at( size_t index );
201  inline ConstReference at( size_t index ) const;
202  inline Pointer data () noexcept;
203  inline ConstPointer data () const noexcept;
204  inline Iterator begin ();
205  inline ConstIterator begin () const;
206  inline ConstIterator cbegin() const;
207  inline Iterator end ();
208  inline ConstIterator end () const;
209  inline ConstIterator cend () const;
211  //**********************************************************************************************
212 
213  //**Assignment operators************************************************************************
216  inline Column& operator=( const ElementType& rhs );
217  inline Column& operator=( initializer_list<ElementType> list );
218  inline Column& operator=( const Column& rhs );
219 
220  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
221  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
222  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
223  template< typename VT > inline Column& operator*=( const Vector<VT,false>& rhs );
224  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
225  template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
227  //**********************************************************************************************
228 
229  //**Utility functions***************************************************************************
232  using DataType::column;
233 
234  inline MT& operand() noexcept;
235  inline const MT& operand() const noexcept;
236 
237  inline size_t size() const noexcept;
238  inline size_t spacing() const noexcept;
239  inline size_t capacity() const noexcept;
240  inline size_t nonZeros() const;
241  inline void reset();
243  //**********************************************************************************************
244 
245  //**Numeric functions***************************************************************************
248  template< typename Other > inline Column& scale( const Other& scalar );
250  //**********************************************************************************************
251 
252  private:
253  //**********************************************************************************************
255  template< typename VT >
256  static constexpr bool VectorizedAssign_v =
257  ( useOptimizedKernels &&
258  simdEnabled && VT::simdEnabled &&
259  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > );
260  //**********************************************************************************************
261 
262  //**********************************************************************************************
264  template< typename VT >
265  static constexpr bool VectorizedAddAssign_v =
266  ( useOptimizedKernels &&
267  simdEnabled && VT::simdEnabled &&
268  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > &&
269  HasSIMDAdd_v< ElementType, ElementType_t<VT> > );
270  //**********************************************************************************************
271 
272  //**********************************************************************************************
274  template< typename VT >
275  static constexpr bool VectorizedSubAssign_v =
276  ( useOptimizedKernels &&
277  simdEnabled && VT::simdEnabled &&
278  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > &&
279  HasSIMDSub_v< ElementType, ElementType_t<VT> > );
280  //**********************************************************************************************
281 
282  //**********************************************************************************************
284  template< typename VT >
285  static constexpr bool VectorizedMultAssign_v =
286  ( useOptimizedKernels &&
287  simdEnabled && VT::simdEnabled &&
288  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > &&
289  HasSIMDMult_v< ElementType, ElementType_t<VT> > );
290  //**********************************************************************************************
291 
292  //**********************************************************************************************
294  template< typename VT >
295  static constexpr bool VectorizedDivAssign_v =
296  ( useOptimizedKernels &&
297  simdEnabled && VT::simdEnabled &&
298  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > &&
299  HasSIMDDiv_v< ElementType, ElementType_t<VT> > );
300  //**********************************************************************************************
301 
302  //**SIMD properties*****************************************************************************
304  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
305  //**********************************************************************************************
306 
307  public:
308  //**Expression template evaluation functions****************************************************
311  template< typename Other >
312  inline bool canAlias( const Other* alias ) const noexcept;
313 
314  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
315  inline bool canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
316 
317  template< typename Other >
318  inline bool isAliased( const Other* alias ) const noexcept;
319 
320  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
321  inline bool isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
322 
323  inline bool isAligned () const noexcept;
324  inline bool canSMPAssign() const noexcept;
325 
326  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
327  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
328  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
329 
330  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
331  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
332  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
333  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
334 
335  template< typename VT >
336  inline auto assign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
337 
338  template< typename VT >
339  inline auto assign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
340 
341  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
342 
343  template< typename VT >
344  inline auto addAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
345 
346  template< typename VT >
347  inline auto addAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
348 
349  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
350 
351  template< typename VT >
352  inline auto subAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
353 
354  template< typename VT >
355  inline auto subAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
356 
357  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
358 
359  template< typename VT >
360  inline auto multAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
361 
362  template< typename VT >
363  inline auto multAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
364 
365  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
366 
367  template< typename VT >
368  inline auto divAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
369 
370  template< typename VT >
371  inline auto divAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT> >;
373  //**********************************************************************************************
374 
375  private:
376  //**Member variables****************************************************************************
379  Operand matrix_;
380 
381  //**********************************************************************************************
382 
383  //**Friend declarations*************************************************************************
384  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Column;
385  //**********************************************************************************************
386 
387  //**Compile time checks*************************************************************************
395  //**********************************************************************************************
396 };
398 //*************************************************************************************************
399 
400 
401 
402 
403 //=================================================================================================
404 //
405 // CONSTRUCTORS
406 //
407 //=================================================================================================
408 
409 //*************************************************************************************************
422 template< typename MT // Type of the dense matrix
423  , bool SF // Symmetry flag
424  , size_t... CCAs > // Compile time column arguments
425 template< typename... RCAs > // Runtime column arguments
426 inline Column<MT,true,true,SF,CCAs...>::Column( MT& matrix, RCAs... args )
427  : DataType( args... ) // Base class initialization
428  , matrix_ ( matrix ) // The matrix containing the column
429 {
430  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
431  if( matrix_.columns() <= column() ) {
432  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
433  }
434  }
435  else {
436  BLAZE_USER_ASSERT( column() < matrix_.columns(), "Invalid column access index" );
437  }
438 }
440 //*************************************************************************************************
441 
442 
443 
444 
445 //=================================================================================================
446 //
447 // DATA ACCESS FUNCTIONS
448 //
449 //=================================================================================================
450 
451 //*************************************************************************************************
461 template< typename MT // Type of the dense matrix
462  , bool SF // Symmetry flag
463  , size_t... CCAs > // Compile time column arguments
464 inline typename Column<MT,true,true,SF,CCAs...>::Reference
465  Column<MT,true,true,SF,CCAs...>::operator[]( size_t index )
466 {
467  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
468  return matrix_(index,column());
469 }
471 //*************************************************************************************************
472 
473 
474 //*************************************************************************************************
484 template< typename MT // Type of the dense matrix
485  , bool SF // Symmetry flag
486  , size_t... CCAs > // Compile time column arguments
487 inline typename Column<MT,true,true,SF,CCAs...>::ConstReference
488  Column<MT,true,true,SF,CCAs...>::operator[]( size_t index ) const
489 {
490  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
491  return const_cast<const MT&>( matrix_ )(index,column());
492 }
494 //*************************************************************************************************
495 
496 
497 //*************************************************************************************************
508 template< typename MT // Type of the dense matrix
509  , bool SF // Symmetry flag
510  , size_t... CCAs > // Compile time column arguments
511 inline typename Column<MT,true,true,SF,CCAs...>::Reference
512  Column<MT,true,true,SF,CCAs...>::at( size_t index )
513 {
514  if( index >= size() ) {
515  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
516  }
517  return (*this)[index];
518 }
520 //*************************************************************************************************
521 
522 
523 //*************************************************************************************************
534 template< typename MT // Type of the dense matrix
535  , bool SF // Symmetry flag
536  , size_t... CCAs > // Compile time column arguments
537 inline typename Column<MT,true,true,SF,CCAs...>::ConstReference
538  Column<MT,true,true,SF,CCAs...>::at( size_t index ) const
539 {
540  if( index >= size() ) {
541  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
542  }
543  return (*this)[index];
544 }
546 //*************************************************************************************************
547 
548 
549 //*************************************************************************************************
558 template< typename MT // Type of the dense matrix
559  , bool SF // Symmetry flag
560  , size_t... CCAs > // Compile time column arguments
561 inline typename Column<MT,true,true,SF,CCAs...>::Pointer
563 {
564  return matrix_.data( column() );
565 }
567 //*************************************************************************************************
568 
569 
570 //*************************************************************************************************
579 template< typename MT // Type of the dense matrix
580  , bool SF // Symmetry flag
581  , size_t... CCAs > // Compile time column arguments
582 inline typename Column<MT,true,true,SF,CCAs...>::ConstPointer
584 {
585  return matrix_.data( column() );
586 }
588 //*************************************************************************************************
589 
590 
591 //*************************************************************************************************
599 template< typename MT // Type of the dense matrix
600  , bool SF // Symmetry flag
601  , size_t... CCAs > // Compile time column arguments
602 inline typename Column<MT,true,true,SF,CCAs...>::Iterator
604 {
605  return matrix_.begin( column() );
606 }
608 //*************************************************************************************************
609 
610 
611 //*************************************************************************************************
619 template< typename MT // Type of the dense matrix
620  , bool SF // Symmetry flag
621  , size_t... CCAs > // Compile time column arguments
622 inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
624 {
625  return matrix_.cbegin( column() );
626 }
628 //*************************************************************************************************
629 
630 
631 //*************************************************************************************************
639 template< typename MT // Type of the dense matrix
640  , bool SF // Symmetry flag
641  , size_t... CCAs > // Compile time column arguments
642 inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
644 {
645  return matrix_.cbegin( column() );
646 }
648 //*************************************************************************************************
649 
650 
651 //*************************************************************************************************
659 template< typename MT // Type of the dense matrix
660  , bool SF // Symmetry flag
661  , size_t... CCAs > // Compile time column arguments
662 inline typename Column<MT,true,true,SF,CCAs...>::Iterator
664 {
665  return matrix_.end( column() );
666 }
668 //*************************************************************************************************
669 
670 
671 //*************************************************************************************************
679 template< typename MT // Type of the dense matrix
680  , bool SF // Symmetry flag
681  , size_t... CCAs > // Compile time column arguments
682 inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
684 {
685  return matrix_.cend( column() );
686 }
688 //*************************************************************************************************
689 
690 
691 //*************************************************************************************************
699 template< typename MT // Type of the dense matrix
700  , bool SF // Symmetry flag
701  , size_t... CCAs > // Compile time column arguments
702 inline typename Column<MT,true,true,SF,CCAs...>::ConstIterator
704 {
705  return matrix_.cend( column() );
706 }
708 //*************************************************************************************************
709 
710 
711 
712 
713 //=================================================================================================
714 //
715 // ASSIGNMENT OPERATORS
716 //
717 //=================================================================================================
718 
719 //*************************************************************************************************
730 template< typename MT // Type of the dense matrix
731  , bool SF // Symmetry flag
732  , size_t... CCAs > // Compile time column arguments
733 inline Column<MT,true,true,SF,CCAs...>&
734  Column<MT,true,true,SF,CCAs...>::operator=( const ElementType& rhs )
735 {
736  decltype(auto) left( derestrict( matrix_ ) );
737 
738  const size_t ibegin( ( IsLower_v<MT> )
739  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
740  ?( column()+1UL )
741  :( column() ) )
742  :( 0UL ) );
743  const size_t iend ( ( IsUpper_v<MT> )
744  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
745  ?( column() )
746  :( column()+1UL ) )
747  :( size() ) );
748 
749  for( size_t i=ibegin; i<iend; ++i ) {
750  if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, column(), rhs ) )
751  left(i,column()) = rhs;
752  }
753 
754  return *this;
755 }
757 //*************************************************************************************************
758 
759 
760 //*************************************************************************************************
775 template< typename MT // Type of the dense matrix
776  , bool SF // Symmetry flag
777  , size_t... CCAs > // Compile time column arguments
778 inline Column<MT,true,true,SF,CCAs...>&
779  Column<MT,true,true,SF,CCAs...>::operator=( initializer_list<ElementType> list )
780 {
781  if( list.size() > size() ) {
782  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
783  }
784 
785  if( IsRestricted_v<MT> ) {
786  const InitializerVector<ElementType,false> tmp( list, size() );
787  if( !tryAssign( matrix_, tmp, 0UL, column() ) ) {
788  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
789  }
790  }
791 
792  decltype(auto) left( derestrict( *this ) );
793 
794  std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
795 
796  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
797 
798  return *this;
799 }
801 //*************************************************************************************************
802 
803 
804 //*************************************************************************************************
818 template< typename MT // Type of the dense matrix
819  , bool SF // Symmetry flag
820  , size_t... CCAs > // Compile time column arguments
821 inline Column<MT,true,true,SF,CCAs...>&
822  Column<MT,true,true,SF,CCAs...>::operator=( const Column& rhs )
823 {
824  if( &rhs == this ) return *this;
825 
826  if( size() != rhs.size() ) {
827  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
828  }
829 
830  if( !tryAssign( matrix_, rhs, 0UL, column() ) ) {
831  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
832  }
833 
834  decltype(auto) left( derestrict( *this ) );
835 
836  if( IsExpression_v<MT> && rhs.canAlias( &matrix_ ) ) {
837  const ResultType tmp( rhs );
838  smpAssign( left, tmp );
839  }
840  else {
841  smpAssign( left, rhs );
842  }
843 
844  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
845 
846  return *this;
847 }
849 //*************************************************************************************************
850 
851 
852 //*************************************************************************************************
866 template< typename MT // Type of the dense matrix
867  , bool SF // Symmetry flag
868  , size_t... CCAs > // Compile time column arguments
869 template< typename VT > // Type of the right-hand side vector
870 inline Column<MT,true,true,SF,CCAs...>&
871  Column<MT,true,true,SF,CCAs...>::operator=( const Vector<VT,false>& rhs )
872 {
873  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
875 
876  if( size() != (~rhs).size() ) {
877  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
878  }
879 
880  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
881  Right right( ~rhs );
882 
883  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
884  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
885  }
886 
887  decltype(auto) left( derestrict( *this ) );
888 
889  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
890  const ResultType_t<VT> tmp( right );
891  smpAssign( left, tmp );
892  }
893  else {
894  if( IsSparseVector_v<VT> )
895  reset();
896  smpAssign( left, right );
897  }
898 
899  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
900 
901  return *this;
902 }
904 //*************************************************************************************************
905 
906 
907 //*************************************************************************************************
921 template< typename MT // Type of the dense matrix
922  , bool SF // Symmetry flag
923  , size_t... CCAs > // Compile time column arguments
924 template< typename VT > // Type of the right-hand side vector
925 inline Column<MT,true,true,SF,CCAs...>&
926  Column<MT,true,true,SF,CCAs...>::operator+=( const Vector<VT,false>& rhs )
927 {
928  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
930 
931  if( size() != (~rhs).size() ) {
932  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
933  }
934 
935  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
936  Right right( ~rhs );
937 
938  if( !tryAddAssign( matrix_, right, 0UL, column() ) ) {
939  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
940  }
941 
942  decltype(auto) left( derestrict( *this ) );
943 
944  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
945  const ResultType_t<VT> tmp( right );
946  smpAddAssign( left, tmp );
947  }
948  else {
949  smpAddAssign( left, right );
950  }
951 
952  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
953 
954  return *this;
955 }
957 //*************************************************************************************************
958 
959 
960 //*************************************************************************************************
974 template< typename MT // Type of the dense matrix
975  , bool SF // Symmetry flag
976  , size_t... CCAs > // Compile time column arguments
977 template< typename VT > // Type of the right-hand side vector
978 inline Column<MT,true,true,SF,CCAs...>&
979  Column<MT,true,true,SF,CCAs...>::operator-=( const Vector<VT,false>& rhs )
980 {
981  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
983 
984  if( size() != (~rhs).size() ) {
985  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
986  }
987 
988  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
989  Right right( ~rhs );
990 
991  if( !trySubAssign( matrix_, right, 0UL, column() ) ) {
992  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
993  }
994 
995  decltype(auto) left( derestrict( *this ) );
996 
997  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
998  const ResultType_t<VT> tmp( right );
999  smpSubAssign( left, tmp );
1000  }
1001  else {
1002  smpSubAssign( left, right );
1003  }
1004 
1005  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1006 
1007  return *this;
1008 }
1010 //*************************************************************************************************
1011 
1012 
1013 //*************************************************************************************************
1026 template< typename MT // Type of the dense matrix
1027  , bool SF // Symmetry flag
1028  , size_t... CCAs > // Compile time column arguments
1029 template< typename VT > // Type of the right-hand side vector
1030 inline Column<MT,true,true,SF,CCAs...>&
1031  Column<MT,true,true,SF,CCAs...>::operator*=( const Vector<VT,false>& rhs )
1032 {
1033  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
1035 
1036  if( size() != (~rhs).size() ) {
1037  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1038  }
1039 
1040  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
1041  Right right( ~rhs );
1042 
1043  if( !tryMultAssign( matrix_, right, 0UL, column() ) ) {
1044  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1045  }
1046 
1047  decltype(auto) left( derestrict( *this ) );
1048 
1049  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
1050  const ResultType_t<VT> tmp( right );
1051  smpMultAssign( left, tmp );
1052  }
1053  else {
1054  smpMultAssign( left, right );
1055  }
1056 
1057  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1058 
1059  return *this;
1060 }
1062 //*************************************************************************************************
1063 
1064 
1065 //*************************************************************************************************
1077 template< typename MT // Type of the dense matrix
1078  , bool SF // Symmetry flag
1079  , size_t... CCAs > // Compile time column arguments
1080 template< typename VT > // Type of the right-hand side dense vector
1081 inline Column<MT,true,true,SF,CCAs...>&
1082  Column<MT,true,true,SF,CCAs...>::operator/=( const DenseVector<VT,false>& rhs )
1083 {
1084  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
1086 
1087  if( size() != (~rhs).size() ) {
1088  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
1089  }
1090 
1091  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
1092  Right right( ~rhs );
1093 
1094  if( !tryDivAssign( matrix_, right, 0UL, column() ) ) {
1095  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1096  }
1097 
1098  decltype(auto) left( derestrict( *this ) );
1099 
1100  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
1101  const ResultType_t<VT> tmp( right );
1102  smpDivAssign( left, tmp );
1103  }
1104  else {
1105  smpDivAssign( left, right );
1106  }
1107 
1108  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1109 
1110  return *this;
1111 }
1113 //*************************************************************************************************
1114 
1115 
1116 //*************************************************************************************************
1129 template< typename MT // Type of the dense matrix
1130  , bool SF // Symmetry flag
1131  , size_t... CCAs > // Compile time column arguments
1132 template< typename VT > // Type of the right-hand side vector
1133 inline Column<MT,true,true,SF,CCAs...>&
1134  Column<MT,true,true,SF,CCAs...>::operator%=( const Vector<VT,false>& rhs )
1135 {
1136  using blaze::assign;
1137 
1138  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
1140 
1141  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
1142 
1146 
1147  if( size() != 3UL || (~rhs).size() != 3UL ) {
1148  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
1149  }
1150 
1151  const CrossType right( *this % (~rhs) );
1152 
1153  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
1154  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1155  }
1156 
1157  decltype(auto) left( derestrict( *this ) );
1158 
1159  assign( left, right );
1160 
1161  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1162 
1163  return *this;
1164 }
1166 //*************************************************************************************************
1167 
1168 
1169 
1170 
1171 //=================================================================================================
1172 //
1173 // UTILITY FUNCTIONS
1174 //
1175 //=================================================================================================
1176 
1177 //*************************************************************************************************
1183 template< typename MT // Type of the dense matrix
1184  , bool SF // Symmetry flag
1185  , size_t... CCAs > // Compile time column arguments
1186 inline MT& Column<MT,true,true,SF,CCAs...>::operand() noexcept
1187 {
1188  return matrix_;
1189 }
1191 //*************************************************************************************************
1192 
1193 
1194 //*************************************************************************************************
1200 template< typename MT // Type of the dense matrix
1201  , bool SF // Symmetry flag
1202  , size_t... CCAs > // Compile time column arguments
1203 inline const MT& Column<MT,true,true,SF,CCAs...>::operand() const noexcept
1204 {
1205  return matrix_;
1206 }
1208 //*************************************************************************************************
1209 
1210 
1211 //*************************************************************************************************
1217 template< typename MT // Type of the dense matrix
1218  , bool SF // Symmetry flag
1219  , size_t... CCAs > // Compile time column arguments
1220 inline size_t Column<MT,true,true,SF,CCAs...>::size() const noexcept
1221 {
1222  return matrix_.rows();
1223 }
1225 //*************************************************************************************************
1226 
1227 
1228 //*************************************************************************************************
1237 template< typename MT // Type of the dense matrix
1238  , bool SF // Symmetry flag
1239  , size_t... CCAs > // Compile time column arguments
1240 inline size_t Column<MT,true,true,SF,CCAs...>::spacing() const noexcept
1241 {
1242  return matrix_.spacing();
1243 }
1245 //*************************************************************************************************
1246 
1247 
1248 //*************************************************************************************************
1254 template< typename MT // Type of the dense matrix
1255  , bool SF // Symmetry flag
1256  , size_t... CCAs > // Compile time column arguments
1257 inline size_t Column<MT,true,true,SF,CCAs...>::capacity() const noexcept
1258 {
1259  return matrix_.capacity( column() );
1260 }
1262 //*************************************************************************************************
1263 
1264 
1265 //*************************************************************************************************
1274 template< typename MT // Type of the dense matrix
1275  , bool SF // Symmetry flag
1276  , size_t... CCAs > // Compile time column arguments
1277 inline size_t Column<MT,true,true,SF,CCAs...>::nonZeros() const
1278 {
1279  return matrix_.nonZeros( column() );
1280 }
1282 //*************************************************************************************************
1283 
1284 
1285 //*************************************************************************************************
1291 template< typename MT // Type of the dense matrix
1292  , bool SF // Symmetry flag
1293  , size_t... CCAs > // Compile time column arguments
1295 {
1296  matrix_.reset( column() );
1297 }
1299 //*************************************************************************************************
1300 
1301 
1302 
1303 
1304 //=================================================================================================
1305 //
1306 // NUMERIC FUNCTIONS
1307 //
1308 //=================================================================================================
1309 
1310 //*************************************************************************************************
1323 template< typename MT // Type of the dense matrix
1324  , bool SF // Symmetry flag
1325  , size_t... CCAs > // Compile time column arguments
1326 template< typename Other > // Data type of the scalar value
1327 inline Column<MT,true,true,SF,CCAs...>&
1328  Column<MT,true,true,SF,CCAs...>::scale( const Other& scalar )
1329 {
1331 
1332  const size_t ibegin( ( IsLower_v<MT> )
1333  ?( ( IsStrictlyLower_v<MT> )
1334  ?( column()+1UL )
1335  :( column() ) )
1336  :( 0UL ) );
1337  const size_t iend ( ( IsUpper_v<MT> )
1338  ?( ( IsStrictlyUpper_v<MT> )
1339  ?( column() )
1340  :( column()+1UL ) )
1341  :( size() ) );
1342 
1343  for( size_t i=ibegin; i<iend; ++i ) {
1344  matrix_(i,column()) *= scalar;
1345  }
1346 
1347  return *this;
1348 }
1350 //*************************************************************************************************
1351 
1352 
1353 
1354 
1355 //=================================================================================================
1356 //
1357 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1358 //
1359 //=================================================================================================
1360 
1361 //*************************************************************************************************
1372 template< typename MT // Type of the dense matrix
1373  , bool SF // Symmetry flag
1374  , size_t... CCAs > // Compile time column arguments
1375 template< typename Other > // Data type of the foreign expression
1376 inline bool Column<MT,true,true,SF,CCAs...>::canAlias( const Other* alias ) const noexcept
1377 {
1378  return matrix_.isAliased( alias );
1379 }
1381 //*************************************************************************************************
1382 
1383 
1384 //*************************************************************************************************
1395 template< typename MT // Type of the dense matrix
1396  , bool SF // Symmetry flag
1397  , size_t... CCAs > // Compile time column arguments
1398 template< typename MT2 // Data type of the foreign dense column
1399  , bool SO2 // Storage order of the foreign dense column
1400  , bool SF2 // Symmetry flag of the foreign dense column
1401  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
1402 inline bool
1403  Column<MT,true,true,SF,CCAs...>::canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1404 {
1405  return matrix_.isAliased( alias->matrix_ ) && ( column() == alias->column() );
1406 }
1408 //*************************************************************************************************
1409 
1410 
1411 //*************************************************************************************************
1422 template< typename MT // Type of the dense matrix
1423  , bool SF // Symmetry flag
1424  , size_t... CCAs > // Compile time column arguments
1425 template< typename Other > // Data type of the foreign expression
1426 inline bool Column<MT,true,true,SF,CCAs...>::isAliased( const Other* alias ) const noexcept
1427 {
1428  return matrix_.isAliased( alias );
1429 }
1431 //*************************************************************************************************
1432 
1433 
1434 //*************************************************************************************************
1445 template< typename MT // Type of the dense matrix
1446  , bool SF // Symmetry flag
1447  , size_t... CCAs > // Compile time column arguments
1448 template< typename MT2 // Data type of the foreign dense column
1449  , bool SO2 // Storage order of the foreign dense column
1450  , bool SF2 // Symmetry flag of the foreign dense column
1451  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
1452 inline bool
1453  Column<MT,true,true,SF,CCAs...>::isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1454 {
1455  return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
1456 }
1458 //*************************************************************************************************
1459 
1460 
1461 //*************************************************************************************************
1471 template< typename MT // Type of the dense matrix
1472  , bool SF // Symmetry flag
1473  , size_t... CCAs > // Compile time column arguments
1474 inline bool Column<MT,true,true,SF,CCAs...>::isAligned() const noexcept
1475 {
1476  return matrix_.isAligned();
1477 }
1479 //*************************************************************************************************
1480 
1481 
1482 //*************************************************************************************************
1493 template< typename MT // Type of the dense matrix
1494  , bool SF // Symmetry flag
1495  , size_t... CCAs > // Compile time column arguments
1496 inline bool Column<MT,true,true,SF,CCAs...>::canSMPAssign() const noexcept
1497 {
1498  return ( size() > SMP_DVECASSIGN_THRESHOLD );
1499 }
1501 //*************************************************************************************************
1502 
1503 
1504 //*************************************************************************************************
1516 template< typename MT // Type of the dense matrix
1517  , bool SF // Symmetry flag
1518  , size_t... CCAs > // Compile time column arguments
1519 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF,CCAs...>::SIMDType
1520  Column<MT,true,true,SF,CCAs...>::load( size_t index ) const noexcept
1521 {
1522  return matrix_.load( index, column() );
1523 }
1525 //*************************************************************************************************
1526 
1527 
1528 //*************************************************************************************************
1541 template< typename MT // Type of the dense matrix
1542  , bool SF // Symmetry flag
1543  , size_t... CCAs > // Compile time column arguments
1544 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF,CCAs...>::SIMDType
1545  Column<MT,true,true,SF,CCAs...>::loada( size_t index ) const noexcept
1546 {
1547  return matrix_.loada( index, column() );
1548 }
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1566 template< typename MT // Type of the dense matrix
1567  , bool SF // Symmetry flag
1568  , size_t... CCAs > // Compile time column arguments
1569 BLAZE_ALWAYS_INLINE typename Column<MT,true,true,SF,CCAs...>::SIMDType
1570  Column<MT,true,true,SF,CCAs...>::loadu( size_t index ) const noexcept
1571 {
1572  return matrix_.loadu( index, column() );
1573 }
1575 //*************************************************************************************************
1576 
1577 
1578 //*************************************************************************************************
1591 template< typename MT // Type of the dense matrix
1592  , bool SF // Symmetry flag
1593  , size_t... CCAs > // Compile time column arguments
1595  Column<MT,true,true,SF,CCAs...>::store( size_t index, const SIMDType& value ) noexcept
1596 {
1597  matrix_.store( index, column(), value );
1598 }
1600 //*************************************************************************************************
1601 
1602 
1603 //*************************************************************************************************
1617 template< typename MT // Type of the dense matrix
1618  , bool SF // Symmetry flag
1619  , size_t... CCAs > // Compile time column arguments
1621  Column<MT,true,true,SF,CCAs...>::storea( size_t index, const SIMDType& value ) noexcept
1622 {
1623  matrix_.storea( index, column(), value );
1624 }
1626 //*************************************************************************************************
1627 
1628 
1629 //*************************************************************************************************
1643 template< typename MT // Type of the dense matrix
1644  , bool SF // Symmetry flag
1645  , size_t... CCAs > // Compile time column arguments
1647  Column<MT,true,true,SF,CCAs...>::storeu( size_t index, const SIMDType& value ) noexcept
1648 {
1649  matrix_.storeu( index, column(), value );
1650 }
1652 //*************************************************************************************************
1653 
1654 
1655 //*************************************************************************************************
1669 template< typename MT // Type of the dense matrix
1670  , bool SF // Symmetry flag
1671  , size_t... CCAs > // Compile time column arguments
1673  Column<MT,true,true,SF,CCAs...>::stream( size_t index, const SIMDType& value ) noexcept
1674 {
1675  matrix_.stream( index, column(), value );
1676 }
1678 //*************************************************************************************************
1679 
1680 
1681 //*************************************************************************************************
1693 template< typename MT // Type of the dense matrix
1694  , bool SF // Symmetry flag
1695  , size_t... CCAs > // Compile time column arguments
1696 template< typename VT > // Type of the right-hand side dense vector
1697 inline auto Column<MT,true,true,SF,CCAs...>::assign( const DenseVector<VT,false>& rhs )
1698  -> DisableIf_t< VectorizedAssign_v<VT> >
1699 {
1700  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1701 
1702  const size_t ipos( (~rhs).size() & size_t(-2) );
1703  for( size_t i=0UL; i<ipos; i+=2UL ) {
1704  matrix_(i ,column()) = (~rhs)[i ];
1705  matrix_(i+1UL,column()) = (~rhs)[i+1UL];
1706  }
1707  if( ipos < (~rhs).size() )
1708  matrix_(ipos,column()) = (~rhs)[ipos];
1709 }
1711 //*************************************************************************************************
1712 
1713 
1714 //*************************************************************************************************
1726 template< typename MT // Type of the dense matrix
1727  , bool SF // Symmetry flag
1728  , size_t... CCAs > // Compile time column arguments
1729 template< typename VT > // Type of the right-hand side dense vector
1730 inline auto Column<MT,true,true,SF,CCAs...>::assign( const DenseVector<VT,false>& rhs )
1731  -> EnableIf_t< VectorizedAssign_v<VT> >
1732 {
1734 
1735  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1736 
1737  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1738 
1739  const size_t rows( size() );
1740 
1741  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1742  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1743 
1744  size_t i( 0UL );
1745  Iterator left( begin() );
1746  ConstIterator_t<VT> right( (~rhs).begin() );
1747 
1748  if( useStreaming && rows > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
1749  {
1750  for( ; i<ipos; i+=SIMDSIZE ) {
1751  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1752  }
1753  for( ; remainder && i<rows; ++i ) {
1754  *left = *right; ++left; ++right;
1755  }
1756  }
1757  else
1758  {
1759  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1760  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1761  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1762  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1763  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1764  }
1765  for( ; i<ipos; i+=SIMDSIZE ) {
1766  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1767  }
1768  for( ; remainder && i<rows; ++i ) {
1769  *left = *right; ++left; ++right;
1770  }
1771  }
1772 }
1774 //*************************************************************************************************
1775 
1776 
1777 //*************************************************************************************************
1789 template< typename MT // Type of the dense matrix
1790  , bool SF // Symmetry flag
1791  , size_t... CCAs > // Compile time column arguments
1792 template< typename VT > // Type of the right-hand side sparse vector
1793 inline void Column<MT,true,true,SF,CCAs...>::assign( const SparseVector<VT,false>& rhs )
1794 {
1795  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1796 
1797  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1798  matrix_(element->index(),column()) = element->value();
1799 }
1801 //*************************************************************************************************
1802 
1803 
1804 //*************************************************************************************************
1816 template< typename MT // Type of the dense matrix
1817  , bool SF // Symmetry flag
1818  , size_t... CCAs > // Compile time column arguments
1819 template< typename VT > // Type of the right-hand side dense vector
1820 inline auto Column<MT,true,true,SF,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
1821  -> DisableIf_t< VectorizedAddAssign_v<VT> >
1822 {
1823  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1824 
1825  const size_t ipos( (~rhs).size() & size_t(-2) );
1826  for( size_t i=0UL; i<ipos; i+=2UL ) {
1827  matrix_(i ,column()) += (~rhs)[i ];
1828  matrix_(i+1UL,column()) += (~rhs)[i+1UL];
1829  }
1830  if( ipos < (~rhs).size() )
1831  matrix_(ipos,column()) += (~rhs)[ipos];
1832 }
1834 //*************************************************************************************************
1835 
1836 
1837 //*************************************************************************************************
1849 template< typename MT // Type of the dense matrix
1850  , bool SF // Symmetry flag
1851  , size_t... CCAs > // Compile time column arguments
1852 template< typename VT > // Type of the right-hand side dense vector
1853 inline auto Column<MT,true,true,SF,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
1854  -> EnableIf_t< VectorizedAddAssign_v<VT> >
1855 {
1857 
1858  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1859 
1860  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1861 
1862  const size_t rows( size() );
1863 
1864  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1865  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1866 
1867  size_t i( 0UL );
1868  Iterator left( begin() );
1869  ConstIterator_t<VT> right( (~rhs).begin() );
1870 
1871  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1872  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1873  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1874  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1875  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1876  }
1877  for( ; i<ipos; i+=SIMDSIZE ) {
1878  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1879  }
1880  for( ; remainder && i<rows; ++i ) {
1881  *left += *right; ++left; ++right;
1882  }
1883 }
1885 //*************************************************************************************************
1886 
1887 
1888 //*************************************************************************************************
1900 template< typename MT // Type of the dense matrix
1901  , bool SF // Symmetry flag
1902  , size_t... CCAs > // Compile time column arguments
1903 template< typename VT > // Type of the right-hand side sparse vector
1904 inline void Column<MT,true,true,SF,CCAs...>::addAssign( const SparseVector<VT,false>& rhs )
1905 {
1906  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1907 
1908  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
1909  matrix_(element->index(),column()) += element->value();
1910 }
1912 //*************************************************************************************************
1913 
1914 
1915 //*************************************************************************************************
1927 template< typename MT // Type of the dense matrix
1928  , bool SF // Symmetry flag
1929  , size_t... CCAs > // Compile time column arguments
1930 template< typename VT > // Type of the right-hand side dense vector
1931 inline auto Column<MT,true,true,SF,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
1932  -> DisableIf_t< VectorizedSubAssign_v<VT> >
1933 {
1934  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1935 
1936  const size_t ipos( (~rhs).size() & size_t(-2) );
1937  for( size_t i=0UL; i<ipos; i+=2UL ) {
1938  matrix_(i ,column()) -= (~rhs)[i ];
1939  matrix_(i+1UL,column()) -= (~rhs)[i+1UL];
1940  }
1941  if( ipos < (~rhs).size() )
1942  matrix_(ipos,column()) -= (~rhs)[ipos];
1943 }
1945 //*************************************************************************************************
1946 
1947 
1948 //*************************************************************************************************
1960 template< typename MT // Type of the dense matrix
1961  , bool SF // Symmetry flag
1962  , size_t... CCAs > // Compile time column arguments
1963 template< typename VT > // Type of the right-hand side dense vector
1964 inline auto Column<MT,true,true,SF,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
1965  -> EnableIf_t< VectorizedSubAssign_v<VT> >
1966 {
1968 
1969  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
1970 
1971  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
1972 
1973  const size_t rows( size() );
1974 
1975  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
1976  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
1977 
1978  size_t i( 0UL );
1979  Iterator left( begin() );
1980  ConstIterator_t<VT> right( (~rhs).begin() );
1981 
1982  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
1983  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1984  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1985  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1986  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1987  }
1988  for( ; i<ipos; i+=SIMDSIZE ) {
1989  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
1990  }
1991  for( ; remainder && i<rows; ++i ) {
1992  *left -= *right; ++left; ++right;
1993  }
1994 }
1996 //*************************************************************************************************
1997 
1998 
1999 //*************************************************************************************************
2011 template< typename MT // Type of the dense matrix
2012  , bool SF // Symmetry flag
2013  , size_t... CCAs > // Compile time column arguments
2014 template< typename VT > // Type of the right-hand side sparse vector
2015 inline void Column<MT,true,true,SF,CCAs...>::subAssign( const SparseVector<VT,false>& rhs )
2016 {
2017  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2018 
2019  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
2020  matrix_(element->index(),column()) -= element->value();
2021 }
2023 //*************************************************************************************************
2024 
2025 
2026 //*************************************************************************************************
2038 template< typename MT // Type of the dense matrix
2039  , bool SF // Symmetry flag
2040  , size_t... CCAs > // Compile time column arguments
2041 template< typename VT > // Type of the right-hand side dense vector
2042 inline auto Column<MT,true,true,SF,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
2043  -> DisableIf_t< VectorizedMultAssign_v<VT> >
2044 {
2045  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2046 
2047  const size_t ipos( (~rhs).size() & size_t(-2) );
2048  for( size_t i=0UL; i<ipos; i+=2UL ) {
2049  matrix_(i ,column()) *= (~rhs)[i ];
2050  matrix_(i+1UL,column()) *= (~rhs)[i+1UL];
2051  }
2052  if( ipos < (~rhs).size() )
2053  matrix_(ipos,column()) *= (~rhs)[ipos];
2054 }
2056 //*************************************************************************************************
2057 
2058 
2059 //*************************************************************************************************
2071 template< typename MT // Type of the dense matrix
2072  , bool SF // Symmetry flag
2073  , size_t... CCAs > // Compile time column arguments
2074 template< typename VT > // Type of the right-hand side dense vector
2075 inline auto Column<MT,true,true,SF,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
2076  -> EnableIf_t< VectorizedMultAssign_v<VT> >
2077 {
2079 
2080  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2081 
2082  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
2083 
2084  const size_t rows( size() );
2085 
2086  const size_t ipos( ( remainder )?( rows & size_t(-SIMDSIZE) ):( rows ) );
2087  BLAZE_INTERNAL_ASSERT( !remainder || ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2088 
2089  size_t i( 0UL );
2090  Iterator left( begin() );
2091  ConstIterator_t<VT> right( (~rhs).begin() );
2092 
2093  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2094  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2095  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2096  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2097  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2098  }
2099  for( ; i<ipos; i+=SIMDSIZE ) {
2100  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2101  }
2102  for( ; remainder && i<rows; ++i ) {
2103  *left *= *right; ++left, ++right;
2104  }
2105 }
2107 //*************************************************************************************************
2108 
2109 
2110 //*************************************************************************************************
2122 template< typename MT // Type of the dense matrix
2123  , bool SF // Symmetry flag
2124  , size_t... CCAs > // Compile time column arguments
2125 template< typename VT > // Type of the right-hand side sparse vector
2126 inline void Column<MT,true,true,SF,CCAs...>::multAssign( const SparseVector<VT,false>& rhs )
2127 {
2128  using blaze::reset;
2129 
2130  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2131 
2132  size_t i( 0UL );
2133 
2134  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
2135  const size_t index( element->index() );
2136  for( ; i<index; ++i )
2137  reset( matrix_(i,column()) );
2138  matrix_(i,column()) *= element->value();
2139  ++i;
2140  }
2141 
2142  for( ; i<size(); ++i ) {
2143  reset( matrix_(i,column()) );
2144  }
2145 }
2147 //*************************************************************************************************
2148 
2149 
2150 //*************************************************************************************************
2162 template< typename MT // Type of the dense matrix
2163  , bool SF // Symmetry flag
2164  , size_t... CCAs > // Compile time column arguments
2165 template< typename VT > // Type of the right-hand side dense vector
2166 inline auto Column<MT,true,true,SF,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
2167  -> DisableIf_t< VectorizedDivAssign_v<VT> >
2168 {
2169  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2170 
2171  const size_t ipos( (~rhs).size() & size_t(-2) );
2172  for( size_t i=0UL; i<ipos; i+=2UL ) {
2173  matrix_(i ,column()) /= (~rhs)[i ];
2174  matrix_(i+1UL,column()) /= (~rhs)[i+1UL];
2175  }
2176  if( ipos < (~rhs).size() )
2177  matrix_(ipos,column()) /= (~rhs)[ipos];
2178 }
2180 //*************************************************************************************************
2181 
2182 
2183 //*************************************************************************************************
2195 template< typename MT // Type of the dense matrix
2196  , bool SF // Symmetry flag
2197  , size_t... CCAs > // Compile time column arguments
2198 template< typename VT > // Type of the right-hand side dense vector
2199 inline auto Column<MT,true,true,SF,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
2200  -> EnableIf_t< VectorizedDivAssign_v<VT> >
2201 {
2203 
2204  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
2205 
2206  const size_t rows( size() );
2207 
2208  const size_t ipos( rows & size_t(-SIMDSIZE) );
2209  BLAZE_INTERNAL_ASSERT( ( rows - ( rows % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2210 
2211  size_t i( 0UL );
2212  Iterator left( begin() );
2213  ConstIterator_t<VT> right( (~rhs).begin() );
2214 
2215  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2216  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2217  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2218  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2219  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2220  }
2221  for( ; i<ipos; i+=SIMDSIZE ) {
2222  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2223  }
2224  for( ; i<rows; ++i ) {
2225  *left /= *right; ++left; ++right;
2226  }
2227 }
2229 //*************************************************************************************************
2230 
2231 
2232 
2233 
2234 
2235 
2236 
2237 
2238 //=================================================================================================
2239 //
2240 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
2241 //
2242 //=================================================================================================
2243 
2244 //*************************************************************************************************
2252 template< typename MT // Type of the dense matrix
2253  , size_t... CCAs > // Compile time column arguments
2254 class Column<MT,false,true,false,CCAs...>
2255  : public View< DenseVector< Column<MT,false,true,false,CCAs...>, false > >
2256  , private ColumnData<CCAs...>
2257 {
2258  private:
2259  //**Type definitions****************************************************************************
2260  using DataType = ColumnData<CCAs...>;
2261  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
2262  //**********************************************************************************************
2263 
2264  public:
2265  //**Type definitions****************************************************************************
2267  using This = Column<MT,false,true,false,CCAs...>;
2268 
2269  using BaseType = DenseVector<This,false>;
2270  using ViewedType = MT;
2271  using ResultType = ColumnTrait_t<MT,CCAs...>;
2272  using TransposeType = TransposeType_t<ResultType>;
2273  using ElementType = ElementType_t<MT>;
2274  using ReturnType = ReturnType_t<MT>;
2275  using CompositeType = const Column&;
2276 
2278  using ConstReference = ConstReference_t<MT>;
2279 
2281  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
2282 
2284  using ConstPointer = ConstPointer_t<MT>;
2285 
2287  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
2288  //**********************************************************************************************
2289 
2290  //**ColumnIterator class definition*************************************************************
2293  template< typename MatrixType // Type of the dense matrix
2294  , typename IteratorType > // Type of the dense matrix iterator
2295  class ColumnIterator
2296  {
2297  public:
2298  //**Type definitions*************************************************************************
2300  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
2301 
2303  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
2304 
2306  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
2307 
2309  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
2310 
2312  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
2313 
2314  // STL iterator requirements
2315  using iterator_category = IteratorCategory;
2316  using value_type = ValueType;
2317  using pointer = PointerType;
2318  using reference = ReferenceType;
2319  using difference_type = DifferenceType;
2320  //*******************************************************************************************
2321 
2322  //**Constructor******************************************************************************
2325  inline ColumnIterator() noexcept
2326  : matrix_( nullptr ) // The dense matrix containing the column
2327  , row_ ( 0UL ) // The current row index
2328  , column_( 0UL ) // The current column index
2329  , pos_ ( ) // Iterator to the current dense element
2330  {}
2331  //*******************************************************************************************
2332 
2333  //**Constructor******************************************************************************
2340  inline ColumnIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
2341  : matrix_( &matrix ) // The dense matrix containing the column
2342  , row_ ( row ) // The current row index
2343  , column_( column ) // The current column index
2344  , pos_ ( ) // Iterator to the current dense element
2345  {
2346  if( row_ != matrix_->rows() )
2347  pos_ = matrix_->begin( row_ ) + column_;
2348  }
2349  //*******************************************************************************************
2350 
2351  //**Constructor******************************************************************************
2356  template< typename MatrixType2, typename IteratorType2 >
2357  inline ColumnIterator( const ColumnIterator<MatrixType2,IteratorType2>& it ) noexcept
2358  : matrix_( it.matrix_ ) // The dense matrix containing the column
2359  , row_ ( it.row_ ) // The current row index
2360  , column_( it.column_ ) // The current column index
2361  , pos_ ( it.pos_ ) // Iterator to the current dense element
2362  {}
2363  //*******************************************************************************************
2364 
2365  //**Addition assignment operator*************************************************************
2371  inline ColumnIterator& operator+=( size_t inc ) noexcept {
2372  using blaze::reset;
2373  row_ += inc;
2374  if( row_ != matrix_->rows() )
2375  pos_ = matrix_->begin( row_ ) + column_;
2376  else reset( pos_ );
2377  return *this;
2378  }
2379  //*******************************************************************************************
2380 
2381  //**Subtraction assignment operator**********************************************************
2387  inline ColumnIterator& operator-=( size_t dec ) noexcept {
2388  using blaze::reset;
2389  row_ -= dec;
2390  if( row_ != matrix_->rows() )
2391  pos_ = matrix_->begin( row_ ) + column_;
2392  else reset( pos_ );
2393  return *this;
2394  }
2395  //*******************************************************************************************
2396 
2397  //**Prefix increment operator****************************************************************
2402  inline ColumnIterator& operator++() noexcept {
2403  using blaze::reset;
2404  ++row_;
2405  if( row_ != matrix_->rows() )
2406  pos_ = matrix_->begin( row_ ) + column_;
2407  else reset( pos_ );
2408  return *this;
2409  }
2410  //*******************************************************************************************
2411 
2412  //**Postfix increment operator***************************************************************
2417  inline const ColumnIterator operator++( int ) noexcept {
2418  const ColumnIterator tmp( *this );
2419  ++(*this);
2420  return tmp;
2421  }
2422  //*******************************************************************************************
2423 
2424  //**Prefix decrement operator****************************************************************
2429  inline ColumnIterator& operator--() noexcept {
2430  using blaze::reset;
2431  --row_;
2432  if( row_ != matrix_->rows() )
2433  pos_ = matrix_->begin( row_ ) + column_;
2434  else reset( pos_ );
2435  return *this;
2436  }
2437  //*******************************************************************************************
2438 
2439  //**Postfix decrement operator***************************************************************
2444  inline const ColumnIterator operator--( int ) noexcept {
2445  const ColumnIterator tmp( *this );
2446  --(*this);
2447  return tmp;
2448  }
2449  //*******************************************************************************************
2450 
2451  //**Subscript operator***********************************************************************
2457  inline ReferenceType operator[]( size_t index ) const {
2458  BLAZE_USER_ASSERT( row_+index < matrix_->rows(), "Invalid access index detected" );
2459  const IteratorType pos( matrix_->begin( row_+index ) + column_ );
2460  return *pos;
2461  }
2462  //*******************************************************************************************
2463 
2464  //**Element access operator******************************************************************
2469  inline ReferenceType operator*() const {
2470  return *pos_;
2471  }
2472  //*******************************************************************************************
2473 
2474  //**Element access operator******************************************************************
2479  inline PointerType operator->() const {
2480  return pos_;
2481  }
2482  //*******************************************************************************************
2483 
2484  //**Equality operator************************************************************************
2490  template< typename MatrixType2, typename IteratorType2 >
2491  inline bool operator==( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2492  return row_ == rhs.row_;
2493  }
2494  //*******************************************************************************************
2495 
2496  //**Inequality operator**********************************************************************
2502  template< typename MatrixType2, typename IteratorType2 >
2503  inline bool operator!=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2504  return !( *this == rhs );
2505  }
2506  //*******************************************************************************************
2507 
2508  //**Less-than operator***********************************************************************
2514  template< typename MatrixType2, typename IteratorType2 >
2515  inline bool operator<( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2516  return row_ < rhs.row_;
2517  }
2518  //*******************************************************************************************
2519 
2520  //**Greater-than operator********************************************************************
2526  template< typename MatrixType2, typename IteratorType2 >
2527  inline bool operator>( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2528  return row_ > rhs.row_;
2529  }
2530  //*******************************************************************************************
2531 
2532  //**Less-or-equal-than operator**************************************************************
2538  template< typename MatrixType2, typename IteratorType2 >
2539  inline bool operator<=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2540  return row_ <= rhs.row_;
2541  }
2542  //*******************************************************************************************
2543 
2544  //**Greater-or-equal-than operator***********************************************************
2550  template< typename MatrixType2, typename IteratorType2 >
2551  inline bool operator>=( const ColumnIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
2552  return row_ >= rhs.row_;
2553  }
2554  //*******************************************************************************************
2555 
2556  //**Subtraction operator*********************************************************************
2562  inline DifferenceType operator-( const ColumnIterator& rhs ) const noexcept {
2563  return row_ - rhs.row_;
2564  }
2565  //*******************************************************************************************
2566 
2567  //**Addition operator************************************************************************
2574  friend inline const ColumnIterator operator+( const ColumnIterator& it, size_t inc ) noexcept {
2575  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2576  }
2577  //*******************************************************************************************
2578 
2579  //**Addition operator************************************************************************
2586  friend inline const ColumnIterator operator+( size_t inc, const ColumnIterator& it ) noexcept {
2587  return ColumnIterator( *it.matrix_, it.row_+inc, it.column_ );
2588  }
2589  //*******************************************************************************************
2590 
2591  //**Subtraction operator*********************************************************************
2598  friend inline const ColumnIterator operator-( const ColumnIterator& it, size_t dec ) noexcept {
2599  return ColumnIterator( *it.matrix_, it.row_-dec, it.column_ );
2600  }
2601  //*******************************************************************************************
2602 
2603  private:
2604  //**Member variables*************************************************************************
2605  MatrixType* matrix_;
2606  size_t row_;
2607  size_t column_;
2608  IteratorType pos_;
2609  //*******************************************************************************************
2610 
2611  //**Friend declarations**********************************************************************
2612  template< typename MatrixType2, typename IteratorType2 > friend class ColumnIterator;
2613  //*******************************************************************************************
2614  };
2615  //**********************************************************************************************
2616 
2617  //**Type definitions****************************************************************************
2619  using ConstIterator = ColumnIterator< const MT, ConstIterator_t<MT> >;
2620 
2622  using Iterator = If_t< IsConst_v<MT>, ConstIterator, ColumnIterator< MT, Iterator_t<MT> > >;
2623  //**********************************************************************************************
2624 
2625  //**Compilation flags***************************************************************************
2627  static constexpr bool simdEnabled = false;
2628 
2630  static constexpr bool smpAssignable = MT::smpAssignable;
2631 
2633  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
2634  //**********************************************************************************************
2635 
2636  //**Constructors********************************************************************************
2639  template< typename... RCAs >
2640  explicit inline Column( MT& matrix, RCAs... args );
2641 
2642  Column( const Column& ) = default;
2644  //**********************************************************************************************
2645 
2646  //**Destructor**********************************************************************************
2649  ~Column() = default;
2651  //**********************************************************************************************
2652 
2653  //**Data access functions***********************************************************************
2656  inline Reference operator[]( size_t index );
2657  inline ConstReference operator[]( size_t index ) const;
2658  inline Reference at( size_t index );
2659  inline ConstReference at( size_t index ) const;
2660  inline Pointer data () noexcept;
2661  inline ConstPointer data () const noexcept;
2662  inline Iterator begin ();
2663  inline ConstIterator begin () const;
2664  inline ConstIterator cbegin() const;
2665  inline Iterator end ();
2666  inline ConstIterator end () const;
2667  inline ConstIterator cend () const;
2669  //**********************************************************************************************
2670 
2671  //**Assignment operators************************************************************************
2674  inline Column& operator=( const ElementType& rhs );
2675  inline Column& operator=( initializer_list<ElementType> list );
2676  inline Column& operator=( const Column& rhs );
2677 
2678  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
2679  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
2680  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
2681  template< typename VT > inline Column& operator*=( const Vector<VT,false>& rhs );
2682  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
2683  template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
2685  //**********************************************************************************************
2686 
2687  //**Utility functions***************************************************************************
2690  using DataType::column;
2691 
2692  inline MT& operand() noexcept;
2693  inline const MT& operand() const noexcept;
2694 
2695  inline size_t size() const noexcept;
2696  inline size_t spacing() const noexcept;
2697  inline size_t capacity() const noexcept;
2698  inline size_t nonZeros() const;
2699  inline void reset();
2701  //**********************************************************************************************
2702 
2703  //**Numeric functions***************************************************************************
2706  template< typename Other > inline Column& scale( const Other& scalar );
2708  //**********************************************************************************************
2709 
2710  //**Expression template evaluation functions****************************************************
2713  template< typename Other >
2714  inline bool canAlias ( const Other* alias ) const noexcept;
2715 
2716  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
2717  inline bool canAlias ( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
2718 
2719  template< typename Other >
2720  inline bool isAliased( const Other* alias ) const noexcept;
2721 
2722  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
2723  inline bool isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
2724 
2725  inline bool isAligned () const noexcept;
2726  inline bool canSMPAssign() const noexcept;
2727 
2728  template< typename VT > inline void assign ( const DenseVector <VT,false>& rhs );
2729  template< typename VT > inline void assign ( const SparseVector<VT,false>& rhs );
2730  template< typename VT > inline void addAssign ( const DenseVector <VT,false>& rhs );
2731  template< typename VT > inline void addAssign ( const SparseVector<VT,false>& rhs );
2732  template< typename VT > inline void subAssign ( const DenseVector <VT,false>& rhs );
2733  template< typename VT > inline void subAssign ( const SparseVector<VT,false>& rhs );
2734  template< typename VT > inline void multAssign( const DenseVector <VT,false>& rhs );
2735  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
2736  template< typename VT > inline void divAssign ( const DenseVector <VT,false>& rhs );
2738  //**********************************************************************************************
2739 
2740  private:
2741  //**Member variables****************************************************************************
2744  Operand matrix_;
2745 
2746  //**********************************************************************************************
2747 
2748  //**Friend declarations*************************************************************************
2749  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Column;
2750  //**********************************************************************************************
2751 
2752  //**Compile time checks*************************************************************************
2761  //**********************************************************************************************
2762 };
2764 //*************************************************************************************************
2765 
2766 
2767 
2768 
2769 //=================================================================================================
2770 //
2771 // CONSTRUCTORS
2772 //
2773 //=================================================================================================
2774 
2775 //*************************************************************************************************
2788 template< typename MT // Type of the dense matrix
2789  , size_t... CCAs > // Compile time column arguments
2790 template< typename... RCAs > // Runtime column arguments
2791 inline Column<MT,false,true,false,CCAs...>::Column( MT& matrix, RCAs... args )
2792  : DataType( args... ) // Base class initialization
2793  , matrix_ ( matrix ) // The matrix containing the column
2794 {
2795  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
2796  if( matrix_.columns() <= column() ) {
2797  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
2798  }
2799  }
2800  else {
2801  BLAZE_USER_ASSERT( column() < matrix_.columns(), "Invalid column access index" );
2802  }
2803 }
2805 //*************************************************************************************************
2806 
2807 
2808 
2809 
2810 //=================================================================================================
2811 //
2812 // DATA ACCESS FUNCTIONS
2813 //
2814 //=================================================================================================
2815 
2816 //*************************************************************************************************
2826 template< typename MT // Type of the dense matrix
2827  , size_t... CCAs > // Compile time column arguments
2828 inline typename Column<MT,false,true,false,CCAs...>::Reference
2829  Column<MT,false,true,false,CCAs...>::operator[]( size_t index )
2830 {
2831  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2832  return matrix_(index,column());
2833 }
2835 //*************************************************************************************************
2836 
2837 
2838 //*************************************************************************************************
2848 template< typename MT // Type of the dense matrix
2849  , size_t... CCAs > // Compile time column arguments
2850 inline typename Column<MT,false,true,false,CCAs...>::ConstReference
2851  Column<MT,false,true,false,CCAs...>::operator[]( size_t index ) const
2852 {
2853  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
2854  return const_cast<const MT&>( matrix_ )(index,column());
2855 }
2857 //*************************************************************************************************
2858 
2859 
2860 //*************************************************************************************************
2871 template< typename MT // Type of the dense matrix
2872  , size_t... CCAs > // Compile time column arguments
2873 inline typename Column<MT,false,true,false,CCAs...>::Reference
2874  Column<MT,false,true,false,CCAs...>::at( size_t index )
2875 {
2876  if( index >= size() ) {
2877  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2878  }
2879  return (*this)[index];
2880 }
2882 //*************************************************************************************************
2883 
2884 
2885 //*************************************************************************************************
2896 template< typename MT // Type of the dense matrix
2897  , size_t... CCAs > // Compile time column arguments
2898 inline typename Column<MT,false,true,false,CCAs...>::ConstReference
2899  Column<MT,false,true,false,CCAs...>::at( size_t index ) const
2900 {
2901  if( index >= size() ) {
2902  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
2903  }
2904  return (*this)[index];
2905 }
2907 //*************************************************************************************************
2908 
2909 
2910 //*************************************************************************************************
2919 template< typename MT // Type of the dense matrix
2920  , size_t... CCAs > // Compile time column arguments
2921 inline typename Column<MT,false,true,false,CCAs...>::Pointer
2923 {
2924  return matrix_.data() + column();
2925 }
2927 //*************************************************************************************************
2928 
2929 
2930 //*************************************************************************************************
2939 template< typename MT // Type of the dense matrix
2940  , size_t... CCAs > // Compile time column arguments
2941 inline typename Column<MT,false,true,false,CCAs...>::ConstPointer
2943 {
2944  return matrix_.data() + column();
2945 }
2947 //*************************************************************************************************
2948 
2949 
2950 //*************************************************************************************************
2958 template< typename MT // Type of the dense matrix
2959  , size_t... CCAs > // Compile time column arguments
2960 inline typename Column<MT,false,true,false,CCAs...>::Iterator
2962 {
2963  return Iterator( matrix_, 0UL, column() );
2964 }
2966 //*************************************************************************************************
2967 
2968 
2969 //*************************************************************************************************
2977 template< typename MT // Type of the dense matrix
2978  , size_t... CCAs > // Compile time column arguments
2979 inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
2981 {
2982  return ConstIterator( matrix_, 0UL, column() );
2983 }
2985 //*************************************************************************************************
2986 
2987 
2988 //*************************************************************************************************
2996 template< typename MT // Type of the dense matrix
2997  , size_t... CCAs > // Compile time column arguments
2998 inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
3000 {
3001  return ConstIterator( matrix_, 0UL, column() );
3002 }
3004 //*************************************************************************************************
3005 
3006 
3007 //*************************************************************************************************
3015 template< typename MT // Type of the dense matrix
3016  , size_t... CCAs > // Compile time column arguments
3017 inline typename Column<MT,false,true,false,CCAs...>::Iterator
3019 {
3020  return Iterator( matrix_, size(), column() );
3021 }
3023 //*************************************************************************************************
3024 
3025 
3026 //*************************************************************************************************
3034 template< typename MT // Type of the dense matrix
3035  , size_t... CCAs > // Compile time column arguments
3036 inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
3038 {
3039  return ConstIterator( matrix_, size(), column() );
3040 }
3042 //*************************************************************************************************
3043 
3044 
3045 //*************************************************************************************************
3053 template< typename MT // Type of the dense matrix
3054  , size_t... CCAs > // Compile time column arguments
3055 inline typename Column<MT,false,true,false,CCAs...>::ConstIterator
3057 {
3058  return ConstIterator( matrix_, size(), column() );
3059 }
3061 //*************************************************************************************************
3062 
3063 
3064 
3065 
3066 //=================================================================================================
3067 //
3068 // ASSIGNMENT OPERATORS
3069 //
3070 //=================================================================================================
3071 
3072 //*************************************************************************************************
3083 template< typename MT // Type of the dense matrix
3084  , size_t... CCAs > // Compile time column arguments
3085 inline Column<MT,false,true,false,CCAs...>&
3086  Column<MT,false,true,false,CCAs...>::operator=( const ElementType& rhs )
3087 {
3088  decltype(auto) left( derestrict( matrix_ ) );
3089 
3090  const size_t ibegin( ( IsLower_v<MT> )
3091  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3092  ?( column()+1UL )
3093  :( column() ) )
3094  :( 0UL ) );
3095  const size_t iend ( ( IsUpper_v<MT> )
3096  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3097  ?( column() )
3098  :( column()+1UL ) )
3099  :( size() ) );
3100 
3101  for( size_t i=ibegin; i<iend; ++i ) {
3102  if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, i, column(), rhs ) )
3103  left(i,column()) = rhs;
3104  }
3105 
3106  return *this;
3107 }
3109 //*************************************************************************************************
3110 
3111 
3112 //*************************************************************************************************
3127 template< typename MT // Type of the dense matrix
3128  , size_t... CCAs > // Compile time column arguments
3129 inline Column<MT,false,true,false,CCAs...>&
3130  Column<MT,false,true,false,CCAs...>::operator=( initializer_list<ElementType> list )
3131 {
3132  if( list.size() > size() ) {
3133  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
3134  }
3135 
3136  if( IsRestricted_v<MT> ) {
3137  const InitializerVector<ElementType,false> tmp( list, size() );
3138  if( !tryAssign( matrix_, tmp, 0UL, column() ) ) {
3139  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3140  }
3141  }
3142 
3143  decltype(auto) left( derestrict( *this ) );
3144 
3145  std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
3146 
3147  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3148 
3149  return *this;
3150 }
3152 //*************************************************************************************************
3153 
3154 
3155 //*************************************************************************************************
3169 template< typename MT // Type of the dense matrix
3170  , size_t... CCAs > // Compile time column arguments
3171 inline Column<MT,false,true,false,CCAs...>&
3172  Column<MT,false,true,false,CCAs...>::operator=( const Column& rhs )
3173 {
3174  if( &rhs == this ) return *this;
3175 
3176  if( size() != rhs.size() ) {
3177  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
3178  }
3179 
3180  if( !tryAssign( matrix_, rhs, 0UL, column() ) ) {
3181  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3182  }
3183 
3184  decltype(auto) left( derestrict( *this ) );
3185 
3186  if( IsExpression_v<MT> && rhs.canAlias( &matrix_ ) ) {
3187  const ResultType tmp( rhs );
3188  smpAssign( left, tmp );
3189  }
3190  else {
3191  smpAssign( left, rhs );
3192  }
3193 
3194  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3195 
3196  return *this;
3197 }
3199 //*************************************************************************************************
3200 
3201 
3202 //*************************************************************************************************
3216 template< typename MT // Type of the dense matrix
3217  , size_t... CCAs > // Compile time column arguments
3218 template< typename VT > // Type of the right-hand side vector
3219 inline Column<MT,false,true,false,CCAs...>&
3220  Column<MT,false,true,false,CCAs...>::operator=( const Vector<VT,false>& rhs )
3221 {
3225 
3226  if( size() != (~rhs).size() ) {
3227  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3228  }
3229 
3230  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3231  Right right( ~rhs );
3232 
3233  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
3234  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3235  }
3236 
3237  decltype(auto) left( derestrict( *this ) );
3238 
3239  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
3240  const ResultType tmp( right );
3241  smpAssign( left, tmp );
3242  }
3243  else {
3244  if( IsSparseVector_v<VT> )
3245  reset();
3246  smpAssign( left, right );
3247  }
3248 
3249  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3250 
3251  return *this;
3252 }
3254 //*************************************************************************************************
3255 
3256 
3257 //*************************************************************************************************
3271 template< typename MT // Type of the dense matrix
3272  , size_t... CCAs > // Compile time column arguments
3273 template< typename VT > // Type of the right-hand side vector
3274 inline Column<MT,false,true,false,CCAs...>&
3275  Column<MT,false,true,false,CCAs...>::operator+=( const Vector<VT,false>& rhs )
3276 {
3277  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
3279 
3280  if( size() != (~rhs).size() ) {
3281  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3282  }
3283 
3284  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3285  Right right( ~rhs );
3286 
3287  if( !tryAddAssign( matrix_, right, 0UL, column() ) ) {
3288  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3289  }
3290 
3291  decltype(auto) left( derestrict( *this ) );
3292 
3293  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
3294  const ResultType_t<VT> tmp( right );
3295  smpAddAssign( left, tmp );
3296  }
3297  else {
3298  smpAddAssign( left, right );
3299  }
3300 
3301  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3302 
3303  return *this;
3304 }
3306 //*************************************************************************************************
3307 
3308 
3309 //*************************************************************************************************
3323 template< typename MT // Type of the dense matrix
3324  , size_t... CCAs > // Compile time column arguments
3325 template< typename VT > // Type of the right-hand side vector
3326 inline Column<MT,false,true,false,CCAs...>&
3327  Column<MT,false,true,false,CCAs...>::operator-=( const Vector<VT,false>& rhs )
3328 {
3329  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
3331 
3332  if( size() != (~rhs).size() ) {
3333  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3334  }
3335 
3336  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3337  Right right( ~rhs );
3338 
3339  if( !trySubAssign( matrix_, right, 0UL, column() ) ) {
3340  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3341  }
3342 
3343  decltype(auto) left( derestrict( *this ) );
3344 
3345  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
3346  const ResultType_t<VT> tmp( right );
3347  smpSubAssign( left, tmp );
3348  }
3349  else {
3350  smpSubAssign( left, right );
3351  }
3352 
3353  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3354 
3355  return *this;
3356 }
3358 //*************************************************************************************************
3359 
3360 
3361 //*************************************************************************************************
3374 template< typename MT // Type of the dense matrix
3375  , size_t... CCAs > // Compile time column arguments
3376 template< typename VT > // Type of the right-hand side vector
3377 inline Column<MT,false,true,false,CCAs...>&
3378  Column<MT,false,true,false,CCAs...>::operator*=( const Vector<VT,false>& rhs )
3379 {
3380  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
3382 
3383  if( size() != (~rhs).size() ) {
3384  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3385  }
3386 
3387  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3388  Right right( ~rhs );
3389 
3390  if( !tryMultAssign( matrix_, right, 0UL, column() ) ) {
3391  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3392  }
3393 
3394  decltype(auto) left( derestrict( *this ) );
3395 
3396  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
3397  const ResultType_t<VT> tmp( right );
3398  smpMultAssign( left, tmp );
3399  }
3400  else {
3401  smpMultAssign( left, right );
3402  }
3403 
3404  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3405 
3406  return *this;
3407 }
3409 //*************************************************************************************************
3410 
3411 
3412 //*************************************************************************************************
3424 template< typename MT // Type of the dense matrix
3425  , size_t... CCAs > // Compile time column arguments
3426 template< typename VT > // Type of the right-hand side dense vector
3427 inline Column<MT,false,true,false,CCAs...>&
3428  Column<MT,false,true,false,CCAs...>::operator/=( const DenseVector<VT,false>& rhs )
3429 {
3430  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
3432 
3433  if( size() != (~rhs).size() ) {
3434  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
3435  }
3436 
3437  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
3438  Right right( ~rhs );
3439 
3440  if( !tryDivAssign( matrix_, right, 0UL, column() ) ) {
3441  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3442  }
3443 
3444  decltype(auto) left( derestrict( *this ) );
3445 
3446  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
3447  const ResultType_t<VT> tmp( right );
3448  smpDivAssign( left, tmp );
3449  }
3450  else {
3451  smpDivAssign( left, right );
3452  }
3453 
3454  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3455 
3456  return *this;
3457 }
3459 //*************************************************************************************************
3460 
3461 
3462 //*************************************************************************************************
3475 template< typename MT // Type of the dense matrix
3476  , size_t... CCAs > // Compile time column arguments
3477 template< typename VT > // Type of the right-hand side vector
3478 inline Column<MT,false,true,false,CCAs...>&
3479  Column<MT,false,true,false,CCAs...>::operator%=( const Vector<VT,false>& rhs )
3480 {
3481  using blaze::assign;
3482 
3483  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
3485 
3486  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
3487 
3491 
3492  if( size() != 3UL || (~rhs).size() != 3UL ) {
3493  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
3494  }
3495 
3496  const CrossType right( *this % (~rhs) );
3497 
3498  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
3499  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
3500  }
3501 
3502  decltype(auto) left( derestrict( *this ) );
3503 
3504  assign( left, right );
3505 
3506  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
3507 
3508  return *this;
3509 }
3511 //*************************************************************************************************
3512 
3513 
3514 
3515 
3516 //=================================================================================================
3517 //
3518 // UTILITY FUNCTIONS
3519 //
3520 //=================================================================================================
3521 
3522 //*************************************************************************************************
3528 template< typename MT // Type of the dense matrix
3529  , size_t... CCAs > // Compile time column arguments
3530 inline MT& Column<MT,false,true,false,CCAs...>::operand() noexcept
3531 {
3532  return matrix_;
3533 }
3535 //*************************************************************************************************
3536 
3537 
3538 //*************************************************************************************************
3544 template< typename MT // Type of the dense matrix
3545  , size_t... CCAs > // Compile time column arguments
3546 inline const MT& Column<MT,false,true,false,CCAs...>::operand() const noexcept
3547 {
3548  return matrix_;
3549 }
3551 //*************************************************************************************************
3552 
3553 
3554 //*************************************************************************************************
3560 template< typename MT // Type of the dense matrix
3561  , size_t... CCAs > // Compile time column arguments
3562 inline size_t Column<MT,false,true,false,CCAs...>::size() const noexcept
3563 {
3564  return matrix_.rows();
3565 }
3567 //*************************************************************************************************
3568 
3569 
3570 //*************************************************************************************************
3579 template< typename MT // Type of the dense matrix
3580  , size_t... CCAs > // Compile time column arguments
3581 inline size_t Column<MT,false,true,false,CCAs...>::spacing() const noexcept
3582 {
3583  return matrix_.spacing();
3584 }
3586 //*************************************************************************************************
3587 
3588 
3589 //*************************************************************************************************
3595 template< typename MT // Type of the dense matrix
3596  , size_t... CCAs > // Compile time column arguments
3597 inline size_t Column<MT,false,true,false,CCAs...>::capacity() const noexcept
3598 {
3599  return matrix_.rows();
3600 }
3602 //*************************************************************************************************
3603 
3604 
3605 //*************************************************************************************************
3614 template< typename MT // Type of the dense matrix
3615  , size_t... CCAs > // Compile time column arguments
3617 {
3618  const size_t rows( size() );
3619  size_t nonzeros( 0UL );
3620 
3621  for( size_t i=0UL; i<rows; ++i )
3622  if( !isDefault( matrix_(i,column()) ) )
3623  ++nonzeros;
3624 
3625  return nonzeros;
3626 }
3628 //*************************************************************************************************
3629 
3630 
3631 //*************************************************************************************************
3637 template< typename MT // Type of the dense matrix
3638  , size_t... CCAs > // Compile time column arguments
3640 {
3641  using blaze::clear;
3642 
3643  const size_t ibegin( ( IsLower_v<MT> )
3644  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
3645  ?( column()+1UL )
3646  :( column() ) )
3647  :( 0UL ) );
3648  const size_t iend ( ( IsUpper_v<MT> )
3649  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
3650  ?( column() )
3651  :( column()+1UL ) )
3652  :( size() ) );
3653 
3654  for( size_t i=ibegin; i<iend; ++i )
3655  clear( matrix_(i,column()) );
3656 }
3658 //*************************************************************************************************
3659 
3660 
3661 
3662 
3663 //=================================================================================================
3664 //
3665 // NUMERIC FUNCTIONS
3666 //
3667 //=================================================================================================
3668 
3669 //*************************************************************************************************
3682 template< typename MT // Type of the dense matrix
3683  , size_t... CCAs > // Compile time column arguments
3684 template< typename Other > // Data type of the scalar value
3685 inline Column<MT,false,true,false,CCAs...>&
3686  Column<MT,false,true,false,CCAs...>::scale( const Other& scalar )
3687 {
3689 
3690  const size_t ibegin( ( IsLower_v<MT> )
3691  ?( ( IsStrictlyLower_v<MT> )
3692  ?( column()+1UL )
3693  :( column() ) )
3694  :( 0UL ) );
3695  const size_t iend ( ( IsUpper_v<MT> )
3696  ?( ( IsStrictlyUpper_v<MT> )
3697  ?( column() )
3698  :( column()+1UL ) )
3699  :( size() ) );
3700 
3701  for( size_t i=ibegin; i<iend; ++i ) {
3702  matrix_(i,column()) *= scalar;
3703  }
3704 
3705  return *this;
3706 }
3708 //*************************************************************************************************
3709 
3710 
3711 
3712 
3713 //=================================================================================================
3714 //
3715 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
3716 //
3717 //=================================================================================================
3718 
3719 //*************************************************************************************************
3730 template< typename MT // Type of the dense matrix
3731  , size_t... CCAs > // Compile time column arguments
3732 template< typename Other > // Data type of the foreign expression
3733 inline bool Column<MT,false,true,false,CCAs...>::canAlias( const Other* alias ) const noexcept
3734 {
3735  return matrix_.isAliased( alias );
3736 }
3738 //*************************************************************************************************
3739 
3740 
3741 //*************************************************************************************************
3752 template< typename MT // Type of the dense matrix
3753  , size_t... CCAs > // Compile time column arguments
3754 template< typename MT2 // Data type of the foreign dense column
3755  , bool SO2 // Storage order of the foreign dense column
3756  , bool SF2 // Symmetry flag of the foreign dense column
3757  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
3758 inline bool
3759  Column<MT,false,true,false,CCAs...>::canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
3760 {
3761  return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
3762 }
3764 //*************************************************************************************************
3765 
3766 
3767 //*************************************************************************************************
3778 template< typename MT // Type of the dense matrix
3779  , size_t... CCAs > // Compile time column arguments
3780 template< typename Other > // Data type of the foreign expression
3781 inline bool Column<MT,false,true,false,CCAs...>::isAliased( const Other* alias ) const noexcept
3782 {
3783  return matrix_.isAliased( alias );
3784 }
3786 //*************************************************************************************************
3787 
3788 
3789 //*************************************************************************************************
3800 template< typename MT // Type of the dense matrix
3801  , size_t... CCAs > // Compile time column arguments
3802 template< typename MT2 // Data type of the foreign dense column
3803  , bool SO2 // Storage order of the foreign dense column
3804  , bool SF2 // Symmetry flag of the foreign dense column
3805  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
3806 inline bool
3807  Column<MT,false,true,false,CCAs...>::isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
3808 {
3809  return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
3810 }
3812 //*************************************************************************************************
3813 
3814 
3815 //*************************************************************************************************
3825 template< typename MT // Type of the dense matrix
3826  , size_t... CCAs > // Compile time column arguments
3827 inline bool Column<MT,false,true,false,CCAs...>::isAligned() const noexcept
3828 {
3829  return false;
3830 }
3832 //*************************************************************************************************
3833 
3834 
3835 //*************************************************************************************************
3846 template< typename MT // Type of the dense matrix
3847  , size_t... CCAs > // Compile time column arguments
3848 inline bool Column<MT,false,true,false,CCAs...>::canSMPAssign() const noexcept
3849 {
3850  return ( size() > SMP_DVECASSIGN_THRESHOLD );
3851 }
3853 //*************************************************************************************************
3854 
3855 
3856 //*************************************************************************************************
3868 template< typename MT // Type of the dense matrix
3869  , size_t... CCAs > // Compile time column arguments
3870 template< typename VT > // Type of the right-hand side dense vector
3871 inline void Column<MT,false,true,false,CCAs...>::assign( const DenseVector<VT,false>& rhs )
3872 {
3873  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3874 
3875  const size_t ipos( (~rhs).size() & size_t(-2) );
3876  for( size_t i=0UL; i<ipos; i+=2UL ) {
3877  matrix_(i ,column()) = (~rhs)[i ];
3878  matrix_(i+1UL,column()) = (~rhs)[i+1UL];
3879  }
3880  if( ipos < (~rhs).size() )
3881  matrix_(ipos,column()) = (~rhs)[ipos];
3882 }
3884 //*************************************************************************************************
3885 
3886 
3887 //*************************************************************************************************
3899 template< typename MT // Type of the dense matrix
3900  , size_t... CCAs > // Compile time column arguments
3901 template< typename VT > // Type of the right-hand side sparse vector
3902 inline void Column<MT,false,true,false,CCAs...>::assign( const SparseVector<VT,false>& rhs )
3903 {
3904  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3905 
3906  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3907  matrix_(element->index(),column()) = element->value();
3908 }
3910 //*************************************************************************************************
3911 
3912 
3913 //*************************************************************************************************
3925 template< typename MT // Type of the dense matrix
3926  , size_t... CCAs > // Compile time column arguments
3927 template< typename VT > // Type of the right-hand side dense vector
3928 inline void Column<MT,false,true,false,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
3929 {
3930  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3931 
3932  const size_t ipos( (~rhs).size() & size_t(-2) );
3933  for( size_t i=0UL; i<ipos; i+=2UL ) {
3934  matrix_(i ,column()) += (~rhs)[i ];
3935  matrix_(i+1UL,column()) += (~rhs)[i+1UL];
3936  }
3937  if( ipos < (~rhs).size() )
3938  matrix_(ipos,column()) += (~rhs)[ipos];
3939 }
3941 //*************************************************************************************************
3942 
3943 
3944 //*************************************************************************************************
3956 template< typename MT // Type of the dense matrix
3957  , size_t... CCAs > // Compile time column arguments
3958 template< typename VT > // Type of the right-hand side sparse vector
3959 inline void Column<MT,false,true,false,CCAs...>::addAssign( const SparseVector<VT,false>& rhs )
3960 {
3961  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3962 
3963  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
3964  matrix_(element->index(),column()) += element->value();
3965 }
3967 //*************************************************************************************************
3968 
3969 
3970 //*************************************************************************************************
3982 template< typename MT // Type of the dense matrix
3983  , size_t... CCAs > // Compile time column arguments
3984 template< typename VT > // Type of the right-hand side dense vector
3985 inline void Column<MT,false,true,false,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
3986 {
3987  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
3988 
3989  const size_t ipos( (~rhs).size() & size_t(-2) );
3990  for( size_t i=0UL; i<ipos; i+=2UL ) {
3991  matrix_(i ,column()) -= (~rhs)[i ];
3992  matrix_(i+1UL,column()) -= (~rhs)[i+1UL];
3993  }
3994  if( ipos < (~rhs).size() )
3995  matrix_(ipos,column()) -= (~rhs)[ipos];
3996 }
3998 //*************************************************************************************************
3999 
4000 
4001 //*************************************************************************************************
4013 template< typename MT // Type of the dense matrix
4014  , size_t... CCAs > // Compile time column arguments
4015 template< typename VT > // Type of the right-hand side sparse vector
4016 inline void Column<MT,false,true,false,CCAs...>::subAssign( const SparseVector<VT,false>& rhs )
4017 {
4018  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4019 
4020  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
4021  matrix_(element->index(),column()) -= element->value();
4022 }
4024 //*************************************************************************************************
4025 
4026 
4027 //*************************************************************************************************
4039 template< typename MT // Type of the dense matrix
4040  , size_t... CCAs > // Compile time column arguments
4041 template< typename VT > // Type of the right-hand side dense vector
4042 inline void Column<MT,false,true,false,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
4043 {
4044  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4045 
4046  const size_t ipos( (~rhs).size() & size_t(-2) );
4047  for( size_t i=0UL; i<ipos; i+=2UL ) {
4048  matrix_(i ,column()) *= (~rhs)[i ];
4049  matrix_(i+1UL,column()) *= (~rhs)[i+1UL];
4050  }
4051  if( ipos < (~rhs).size() )
4052  matrix_(ipos,column()) *= (~rhs)[ipos];
4053 }
4055 //*************************************************************************************************
4056 
4057 
4058 //*************************************************************************************************
4070 template< typename MT // Type of the dense matrix
4071  , size_t... CCAs > // Compile time column arguments
4072 template< typename VT > // Type of the right-hand side sparse vector
4073 inline void Column<MT,false,true,false,CCAs...>::multAssign( const SparseVector<VT,false>& rhs )
4074 {
4075  using blaze::reset;
4076 
4077  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4078 
4079  size_t i( 0UL );
4080 
4081  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
4082  const size_t index( element->index() );
4083  for( ; i<index; ++i )
4084  reset( matrix_(i,column()) );
4085  matrix_(i,column()) *= element->value();
4086  ++i;
4087  }
4088 
4089  for( ; i<size(); ++i ) {
4090  reset( matrix_(i,column()) );
4091  }
4092 }
4094 //*************************************************************************************************
4095 
4096 
4097 //*************************************************************************************************
4109 template< typename MT // Type of the dense matrix
4110  , size_t... CCAs > // Compile time column arguments
4111 template< typename VT > // Type of the right-hand side dense vector
4112 inline void Column<MT,false,true,false,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
4113 {
4114  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
4115 
4116  const size_t ipos( (~rhs).size() & size_t(-2) );
4117  for( size_t i=0UL; i<ipos; i+=2UL ) {
4118  matrix_(i ,column()) /= (~rhs)[i ];
4119  matrix_(i+1UL,column()) /= (~rhs)[i+1UL];
4120  }
4121  if( ipos < (~rhs).size() )
4122  matrix_(ipos,column()) /= (~rhs)[ipos];
4123 }
4125 //*************************************************************************************************
4126 
4127 
4128 
4129 
4130 
4131 
4132 
4133 
4134 //=================================================================================================
4135 //
4136 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
4137 //
4138 //=================================================================================================
4139 
4140 //*************************************************************************************************
4148 template< typename MT // Type of the dense matrix
4149  , size_t... CCAs > // Compile time column arguments
4150 class Column<MT,false,true,true,CCAs...>
4151  : public View< DenseVector< Column<MT,false,true,true,CCAs...>, false > >
4152  , private ColumnData<CCAs...>
4153 {
4154  private:
4155  //**Type definitions****************************************************************************
4156  using DataType = ColumnData<CCAs...>;
4157  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
4158  //**********************************************************************************************
4159 
4160  public:
4161  //**Type definitions****************************************************************************
4163  using This = Column<MT,false,true,true,CCAs...>;
4164 
4165  using BaseType = DenseVector<This,false>;
4166  using ViewedType = MT;
4167  using ResultType = ColumnTrait_t<MT,CCAs...>;
4168  using TransposeType = TransposeType_t<ResultType>;
4169  using ElementType = ElementType_t<MT>;
4170  using SIMDType = SIMDTrait_t<ElementType>;
4171  using ReturnType = ReturnType_t<MT>;
4172  using CompositeType = const Column&;
4173 
4175  using ConstReference = ConstReference_t<MT>;
4176 
4178  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
4179 
4181  using ConstPointer = ConstPointer_t<MT>;
4182 
4184  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
4185 
4187  using ConstIterator = ConstIterator_t<MT>;
4188 
4190  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
4191  //**********************************************************************************************
4192 
4193  //**Compilation flags***************************************************************************
4195  static constexpr bool simdEnabled = MT::simdEnabled;
4196 
4198  static constexpr bool smpAssignable = MT::smpAssignable;
4199 
4201  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
4202  //**********************************************************************************************
4203 
4204  //**Constructors********************************************************************************
4207  template< typename... RCAs >
4208  explicit inline Column( MT& matrix, RCAs... args );
4209 
4210  Column( const Column& ) = default;
4212  //**********************************************************************************************
4213 
4214  //**Destructor**********************************************************************************
4217  ~Column() = default;
4219  //**********************************************************************************************
4220 
4221  //**Data access functions***********************************************************************
4224  inline Reference operator[]( size_t index );
4225  inline ConstReference operator[]( size_t index ) const;
4226  inline Reference at( size_t index );
4227  inline ConstReference at( size_t index ) const;
4228  inline Pointer data () noexcept;
4229  inline ConstPointer data () const noexcept;
4230  inline Iterator begin ();
4231  inline ConstIterator begin () const;
4232  inline ConstIterator cbegin() const;
4233  inline Iterator end ();
4234  inline ConstIterator end () const;
4235  inline ConstIterator cend () const;
4237  //**********************************************************************************************
4238 
4239  //**Assignment operators************************************************************************
4242  inline Column& operator=( const ElementType& rhs );
4243  inline Column& operator=( initializer_list<ElementType> list );
4244  inline Column& operator=( const Column& rhs );
4245 
4246  template< typename VT > inline Column& operator= ( const Vector<VT,false>& rhs );
4247  template< typename VT > inline Column& operator+=( const Vector<VT,false>& rhs );
4248  template< typename VT > inline Column& operator-=( const Vector<VT,false>& rhs );
4249  template< typename VT > inline Column& operator*=( const Vector<VT,false>& rhs );
4250  template< typename VT > inline Column& operator/=( const DenseVector<VT,false>& rhs );
4251  template< typename VT > inline Column& operator%=( const Vector<VT,false>& rhs );
4253  //**********************************************************************************************
4254 
4255  //**Utility functions***************************************************************************
4258  using DataType::column;
4259 
4260  inline MT& operand() noexcept;
4261  inline const MT& operand() const noexcept;
4262 
4263  inline size_t size() const noexcept;
4264  inline size_t spacing() const noexcept;
4265  inline size_t capacity() const noexcept;
4266  inline size_t nonZeros() const;
4267  inline void reset();
4269  //**********************************************************************************************
4270 
4271  //**Numeric functions***************************************************************************
4274  template< typename Other > inline Column& scale( const Other& scalar );
4276  //**********************************************************************************************
4277 
4278  private:
4279  //**********************************************************************************************
4281  template< typename VT >
4282  static constexpr bool VectorizedAssign_v =
4283  ( useOptimizedKernels &&
4284  simdEnabled && VT::simdEnabled &&
4285  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > );
4286  //**********************************************************************************************
4287 
4288  //**********************************************************************************************
4290  template< typename VT >
4291  static constexpr bool VectorizedAddAssign_v =
4292  ( useOptimizedKernels &&
4293  simdEnabled && VT::simdEnabled &&
4294  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > &&
4295  HasSIMDAdd_v< ElementType, ElementType_t<VT> > );
4296  //**********************************************************************************************
4297 
4298  //**********************************************************************************************
4300  template< typename VT >
4301  static constexpr bool VectorizedSubAssign_v =
4302  ( useOptimizedKernels &&
4303  simdEnabled && VT::simdEnabled &&
4304  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > &&
4305  HasSIMDSub_v< ElementType, ElementType_t<VT> > );
4306  //**********************************************************************************************
4307 
4308  //**********************************************************************************************
4310  template< typename VT >
4311  static constexpr bool VectorizedMultAssign_v =
4312  ( useOptimizedKernels &&
4313  simdEnabled && VT::simdEnabled &&
4314  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > &&
4315  HasSIMDMult_v< ElementType, ElementType_t<VT> > );
4316  //**********************************************************************************************
4317 
4318  //**********************************************************************************************
4320  template< typename VT >
4321  static constexpr bool VectorizedDivAssign_v =
4322  ( useOptimizedKernels &&
4323  simdEnabled && VT::simdEnabled &&
4324  IsSIMDCombinable_v< ElementType, ElementType_t<VT> > &&
4325  HasSIMDDiv_v< ElementType, ElementType_t<VT> > );
4326  //**********************************************************************************************
4327 
4328  //**SIMD properties*****************************************************************************
4330  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
4331  //**********************************************************************************************
4332 
4333  public:
4334  //**Expression template evaluation functions****************************************************
4337  template< typename Other >
4338  inline bool canAlias( const Other* alias ) const noexcept;
4339 
4340  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
4341  inline bool canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
4342 
4343  template< typename Other >
4344  inline bool isAliased( const Other* alias ) const noexcept;
4345 
4346  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
4347  inline bool isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
4348 
4349  inline bool isAligned () const noexcept;
4350  inline bool canSMPAssign() const noexcept;
4351 
4352  BLAZE_ALWAYS_INLINE SIMDType load ( size_t index ) const noexcept;
4353  BLAZE_ALWAYS_INLINE SIMDType loada( size_t index ) const noexcept;
4354  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t index ) const noexcept;
4355 
4356  BLAZE_ALWAYS_INLINE void store ( size_t index, const SIMDType& value ) noexcept;
4357  BLAZE_ALWAYS_INLINE void storea( size_t index, const SIMDType& value ) noexcept;
4358  BLAZE_ALWAYS_INLINE void storeu( size_t index, const SIMDType& value ) noexcept;
4359  BLAZE_ALWAYS_INLINE void stream( size_t index, const SIMDType& value ) noexcept;
4360 
4361  template< typename VT >
4362  inline auto assign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedAssign_v<VT> >;
4363 
4364  template< typename VT >
4365  inline auto assign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedAssign_v<VT> >;
4366 
4367  template< typename VT > inline void assign( const SparseVector<VT,false>& rhs );
4368 
4369  template< typename VT >
4370  inline auto addAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<VT> >;
4371 
4372  template< typename VT >
4373  inline auto addAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<VT> >;
4374 
4375  template< typename VT > inline void addAssign( const SparseVector<VT,false>& rhs );
4376 
4377  template< typename VT >
4378  inline auto subAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<VT> >;
4379 
4380  template< typename VT >
4381  inline auto subAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<VT> >;
4382 
4383  template< typename VT > inline void subAssign( const SparseVector<VT,false>& rhs );
4384 
4385  template< typename VT >
4386  inline auto multAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedMultAssign_v<VT> >;
4387 
4388  template< typename VT >
4389  inline auto multAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedMultAssign_v<VT> >;
4390 
4391  template< typename VT > inline void multAssign( const SparseVector<VT,false>& rhs );
4392 
4393  template< typename VT >
4394  inline auto divAssign( const DenseVector<VT,false>& rhs ) -> DisableIf_t< VectorizedDivAssign_v<VT> >;
4395 
4396  template< typename VT >
4397  inline auto divAssign( const DenseVector<VT,false>& rhs ) -> EnableIf_t< VectorizedDivAssign_v<VT> >;
4399  //**********************************************************************************************
4400 
4401  private:
4402  //**Member variables****************************************************************************
4405  Operand matrix_;
4406 
4407  //**********************************************************************************************
4408 
4409  //**Friend declarations*************************************************************************
4410  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Column;
4411  //**********************************************************************************************
4412 
4413  //**Compile time checks*************************************************************************
4422  //**********************************************************************************************
4423 };
4425 //*************************************************************************************************
4426 
4427 
4428 
4429 
4430 //=================================================================================================
4431 //
4432 // CONSTRUCTORS
4433 //
4434 //=================================================================================================
4435 
4436 //*************************************************************************************************
4449 template< typename MT // Type of the dense matrix
4450  , size_t... CCAs > // Compile time column arguments
4451 template< typename... RCAs > // Runtime column arguments
4452 inline Column<MT,false,true,true,CCAs...>::Column( MT& matrix, RCAs... args )
4453  : DataType( args... ) // Base class initialization
4454  , matrix_ ( matrix ) // The matrix containing the column
4455 {
4456  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
4457  if( matrix_.columns() <= column() ) {
4458  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
4459  }
4460  }
4461  else {
4462  BLAZE_USER_ASSERT( column() < matrix_.columns(), "Invalid column access index" );
4463  }
4464 }
4466 //*************************************************************************************************
4467 
4468 
4469 
4470 
4471 //=================================================================================================
4472 //
4473 // DATA ACCESS FUNCTIONS
4474 //
4475 //=================================================================================================
4476 
4477 //*************************************************************************************************
4487 template< typename MT // Type of the dense matrix
4488  , size_t... CCAs > // Compile time column arguments
4489 inline typename Column<MT,false,true,true,CCAs...>::Reference
4490  Column<MT,false,true,true,CCAs...>::operator[]( size_t index )
4491 {
4492  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4493  return matrix_(column(),index);
4494 }
4496 //*************************************************************************************************
4497 
4498 
4499 //*************************************************************************************************
4509 template< typename MT // Type of the dense matrix
4510  , size_t... CCAs > // Compile time column arguments
4511 inline typename Column<MT,false,true,true,CCAs...>::ConstReference
4512  Column<MT,false,true,true,CCAs...>::operator[]( size_t index ) const
4513 {
4514  BLAZE_USER_ASSERT( index < size(), "Invalid column access index" );
4515  return const_cast<const MT&>( matrix_ )(column(),index);
4516 }
4518 //*************************************************************************************************
4519 
4520 
4521 //*************************************************************************************************
4532 template< typename MT // Type of the dense matrix
4533  , size_t... CCAs > // Compile time column arguments
4534 inline typename Column<MT,false,true,true,CCAs...>::Reference
4535  Column<MT,false,true,true,CCAs...>::at( size_t index )
4536 {
4537  if( index >= size() ) {
4538  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4539  }
4540  return (*this)[index];
4541 }
4543 //*************************************************************************************************
4544 
4545 
4546 //*************************************************************************************************
4557 template< typename MT // Type of the dense matrix
4558  , size_t... CCAs > // Compile time column arguments
4559 inline typename Column<MT,false,true,true,CCAs...>::ConstReference
4560  Column<MT,false,true,true,CCAs...>::at( size_t index ) const
4561 {
4562  if( index >= size() ) {
4563  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
4564  }
4565  return (*this)[index];
4566 }
4568 //*************************************************************************************************
4569 
4570 
4571 //*************************************************************************************************
4580 template< typename MT // Type of the dense matrix
4581  , size_t... CCAs > // Compile time column arguments
4582 inline typename Column<MT,false,true,true,CCAs...>::Pointer
4584 {
4585  return matrix_.data( column() );
4586 }
4588 //*************************************************************************************************
4589 
4590 
4591 //*************************************************************************************************
4600 template< typename MT // Type of the dense matrix
4601  , size_t... CCAs > // Compile time column arguments
4602 inline typename Column<MT,false,true,true,CCAs...>::ConstPointer
4604 {
4605  return matrix_.data( column() );
4606 }
4608 //*************************************************************************************************
4609 
4610 
4611 //*************************************************************************************************
4619 template< typename MT // Type of the dense matrix
4620  , size_t... CCAs > // Compile time column arguments
4621 inline typename Column<MT,false,true,true,CCAs...>::Iterator
4623 {
4624  return matrix_.begin( column() );
4625 }
4627 //*************************************************************************************************
4628 
4629 
4630 //*************************************************************************************************
4638 template< typename MT // Type of the dense matrix
4639  , size_t... CCAs > // Compile time column arguments
4640 inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4642 {
4643  return matrix_.cbegin( column() );
4644 }
4646 //*************************************************************************************************
4647 
4648 
4649 //*************************************************************************************************
4657 template< typename MT // Type of the dense matrix
4658  , size_t... CCAs > // Compile time column arguments
4659 inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4661 {
4662  return matrix_.cbegin( column() );
4663 }
4665 //*************************************************************************************************
4666 
4667 
4668 //*************************************************************************************************
4676 template< typename MT // Type of the dense matrix
4677  , size_t... CCAs > // Compile time column arguments
4678 inline typename Column<MT,false,true,true,CCAs...>::Iterator
4680 {
4681  return matrix_.end( column() );
4682 }
4684 //*************************************************************************************************
4685 
4686 
4687 //*************************************************************************************************
4695 template< typename MT // Type of the dense matrix
4696  , size_t... CCAs > // Compile time column arguments
4697 inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4699 {
4700  return matrix_.cend( column() );
4701 }
4703 //*************************************************************************************************
4704 
4705 
4706 //*************************************************************************************************
4714 template< typename MT // Type of the dense matrix
4715  , size_t... CCAs > // Compile time column arguments
4716 inline typename Column<MT,false,true,true,CCAs...>::ConstIterator
4718 {
4719  return matrix_.cend( column() );
4720 }
4722 //*************************************************************************************************
4723 
4724 
4725 
4726 
4727 //=================================================================================================
4728 //
4729 // ASSIGNMENT OPERATORS
4730 //
4731 //=================================================================================================
4732 
4733 //*************************************************************************************************
4740 template< typename MT // Type of the dense matrix
4741  , size_t... CCAs > // Compile time column arguments
4742 inline Column<MT,false,true,true,CCAs...>&
4743  Column<MT,false,true,true,CCAs...>::operator=( const ElementType& rhs )
4744 {
4745  decltype(auto) left( derestrict( matrix_ ) );
4746 
4747  const size_t jbegin( ( IsUpper_v<MT> )
4748  ?( ( IsUniUpper_v<MT> || IsStrictlyUpper_v<MT> )
4749  ?( column()+1UL )
4750  :( column() ) )
4751  :( 0UL ) );
4752  const size_t jend ( ( IsLower_v<MT> )
4753  ?( ( IsUniLower_v<MT> || IsStrictlyLower_v<MT> )
4754  ?( column() )
4755  :( column()+1UL ) )
4756  :( size() ) );
4757 
4758  for( size_t j=jbegin; j<jend; ++j ) {
4759  if( !IsRestricted_v<MT> || IsTriangular_v<MT> || trySet( matrix_, column(), j, rhs ) )
4760  left(column(),j) = rhs;
4761  }
4762 
4763  return *this;
4764 }
4766 //*************************************************************************************************
4767 
4768 
4769 //*************************************************************************************************
4784 template< typename MT // Type of the dense matrix
4785  , size_t... CCAs > // Compile time column arguments
4786 inline Column<MT,false,true,true,CCAs...>&
4787  Column<MT,false,true,true,CCAs...>::operator=( initializer_list<ElementType> list )
4788 {
4789  if( list.size() > size() ) {
4790  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column" );
4791  }
4792 
4793  if( IsRestricted_v<MT> ) {
4794  const InitializerVector<ElementType,false> tmp( list, size() );
4795  if( !tryAssign( matrix_, tmp, 0UL, column() ) ) {
4796  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4797  }
4798  }
4799 
4800  decltype(auto) left( derestrict( *this ) );
4801 
4802  std::fill( std::copy( list.begin(), list.end(), left.begin() ), left.end(), ElementType() );
4803 
4804  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4805 
4806  return *this;
4807 }
4809 //*************************************************************************************************
4810 
4811 
4812 //*************************************************************************************************
4826 template< typename MT // Type of the dense matrix
4827  , size_t... CCAs > // Compile time column arguments
4828 inline Column<MT,false,true,true,CCAs...>&
4829  Column<MT,false,true,true,CCAs...>::operator=( const Column& rhs )
4830 {
4831  if( &rhs == this ) return *this;
4832 
4833  if( size() != rhs.size() ) {
4834  BLAZE_THROW_INVALID_ARGUMENT( "Column sizes do not match" );
4835  }
4836 
4837  if( !tryAssign( matrix_, rhs, 0UL, column() ) ) {
4838  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4839  }
4840 
4841  decltype(auto) left( derestrict( *this ) );
4842 
4843  if( IsExpression_v<MT> && rhs.canAlias( &matrix_ ) ) {
4844  const ResultType tmp( rhs );
4845  smpAssign( left, tmp );
4846  }
4847  else {
4848  smpAssign( left, rhs );
4849  }
4850 
4851  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4852 
4853  return *this;
4854 }
4856 //*************************************************************************************************
4857 
4858 
4859 //*************************************************************************************************
4873 template< typename MT // Type of the dense matrix
4874  , size_t... CCAs > // Compile time column arguments
4875 template< typename VT > // Type of the right-hand side vector
4876 inline Column<MT,false,true,true,CCAs...>&
4877  Column<MT,false,true,true,CCAs...>::operator=( const Vector<VT,false>& rhs )
4878 {
4879  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
4881 
4882  if( size() != (~rhs).size() ) {
4883  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4884  }
4885 
4886  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
4887  Right right( ~rhs );
4888 
4889  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
4890  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4891  }
4892 
4893  decltype(auto) left( derestrict( *this ) );
4894 
4895  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
4896  const ResultType_t<VT> tmp( right );
4897  smpAssign( left, tmp );
4898  }
4899  else {
4900  if( IsSparseVector_v<VT> )
4901  reset();
4902  smpAssign( left, right );
4903  }
4904 
4905  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4906 
4907  return *this;
4908 }
4910 //*************************************************************************************************
4911 
4912 
4913 //*************************************************************************************************
4927 template< typename MT // Type of the dense matrix
4928  , size_t... CCAs > // Compile time column arguments
4929 template< typename VT > // Type of the right-hand side vector
4930 inline Column<MT,false,true,true,CCAs...>&
4931  Column<MT,false,true,true,CCAs...>::operator+=( const Vector<VT,false>& rhs )
4932 {
4933  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
4935 
4936  if( size() != (~rhs).size() ) {
4937  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4938  }
4939 
4940  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
4941  Right right( ~rhs );
4942 
4943  if( !tryAddAssign( matrix_, right, 0UL, column() ) ) {
4944  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4945  }
4946 
4947  decltype(auto) left( derestrict( *this ) );
4948 
4949  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
4950  const ResultType_t<VT> tmp( right );
4951  smpAddAssign( left, tmp );
4952  }
4953  else {
4954  smpAddAssign( left, right );
4955  }
4956 
4957  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4958 
4959  return *this;
4960 }
4962 //*************************************************************************************************
4963 
4964 
4965 //*************************************************************************************************
4979 template< typename MT // Type of the dense matrix
4980  , size_t... CCAs > // Compile time column arguments
4981 template< typename VT > // Type of the right-hand side vector
4982 inline Column<MT,false,true,true,CCAs...>&
4983  Column<MT,false,true,true,CCAs...>::operator-=( const Vector<VT,false>& rhs )
4984 {
4985  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
4987 
4988  if( size() != (~rhs).size() ) {
4989  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
4990  }
4991 
4992  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
4993  Right right( ~rhs );
4994 
4995  if( !trySubAssign( matrix_, right, 0UL, column() ) ) {
4996  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4997  }
4998 
4999  decltype(auto) left( derestrict( *this ) );
5000 
5001  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
5002  const ResultType_t<VT> tmp( right );
5003  smpSubAssign( left, tmp );
5004  }
5005  else {
5006  smpSubAssign( left, right );
5007  }
5008 
5009  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5010 
5011  return *this;
5012 }
5014 //*************************************************************************************************
5015 
5016 
5017 //*************************************************************************************************
5030 template< typename MT // Type of the dense matrix
5031  , size_t... CCAs > // Compile time column arguments
5032 template< typename VT > // Type of the right-hand side vector
5033 inline Column<MT,false,true,true,CCAs...>&
5034  Column<MT,false,true,true,CCAs...>::operator*=( const Vector<VT,false>& rhs )
5035 {
5036  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
5038 
5039  if( size() != (~rhs).size() ) {
5040  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5041  }
5042 
5043  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
5044  Right right( ~rhs );
5045 
5046  if( !tryMultAssign( matrix_, right, 0UL, column() ) ) {
5047  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5048  }
5049 
5050  decltype(auto) left( derestrict( *this ) );
5051 
5052  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
5053  const ResultType_t<VT> tmp( right );
5054  smpMultAssign( left, tmp );
5055  }
5056  else {
5057  smpMultAssign( left, right );
5058  }
5059 
5060  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5061 
5062  return *this;
5063 }
5065 //*************************************************************************************************
5066 
5067 
5068 //*************************************************************************************************
5080 template< typename MT // Type of the dense matrix
5081  , size_t... CCAs > // Compile time column arguments
5082 template< typename VT > // Type of the right-hand side dense vector
5083 inline Column<MT,false,true,true,CCAs...>&
5084  Column<MT,false,true,true,CCAs...>::operator/=( const DenseVector<VT,false>& rhs )
5085 {
5086  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
5088 
5089  if( size() != (~rhs).size() ) {
5090  BLAZE_THROW_INVALID_ARGUMENT( "Vector sizes do not match" );
5091  }
5092 
5093  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<VT>, const VT& >;
5094  Right right( ~rhs );
5095 
5096  if( !tryDivAssign( matrix_, right, 0UL, column() ) ) {
5097  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5098  }
5099 
5100  decltype(auto) left( derestrict( *this ) );
5101 
5102  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
5103  const ResultType_t<VT> tmp( right );
5104  smpDivAssign( left, tmp );
5105  }
5106  else {
5107  smpDivAssign( left, right );
5108  }
5109 
5110  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5111 
5112  return *this;
5113 }
5115 //*************************************************************************************************
5116 
5117 
5118 //*************************************************************************************************
5131 template< typename MT // Type of the dense matrix
5132  , size_t... CCAs > // Compile time column arguments
5133 template< typename VT > // Type of the right-hand side vector
5134 inline Column<MT,false,true,true,CCAs...>&
5135  Column<MT,false,true,true,CCAs...>::operator%=( const Vector<VT,false>& rhs )
5136 {
5137  using blaze::assign;
5138 
5139  BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE ( ResultType_t<VT> );
5141 
5142  using CrossType = CrossTrait_t< ResultType, ResultType_t<VT> >;
5143 
5147 
5148  if( size() != 3UL || (~rhs).size() != 3UL ) {
5149  BLAZE_THROW_INVALID_ARGUMENT( "Invalid vector size for cross product" );
5150  }
5151 
5152  const CrossType right( *this % (~rhs) );
5153 
5154  if( !tryAssign( matrix_, right, 0UL, column() ) ) {
5155  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
5156  }
5157 
5158  decltype(auto) left( derestrict( *this ) );
5159 
5160  assign( left, right );
5161 
5162  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
5163 
5164  return *this;
5165 }
5167 //*************************************************************************************************
5168 
5169 
5170 
5171 
5172 //=================================================================================================
5173 //
5174 // UTILITY FUNCTIONS
5175 //
5176 //=================================================================================================
5177 
5178 //*************************************************************************************************
5184 template< typename MT // Type of the dense matrix
5185  , size_t... CCAs > // Compile time column arguments
5186 inline MT& Column<MT,false,true,true,CCAs...>::operand() noexcept
5187 {
5188  return matrix_;
5189 }
5191 //*************************************************************************************************
5192 
5193 
5194 //*************************************************************************************************
5200 template< typename MT // Type of the dense matrix
5201  , size_t... CCAs > // Compile time column arguments
5202 inline const MT& Column<MT,false,true,true,CCAs...>::operand() const noexcept
5203 {
5204  return matrix_;
5205 }
5207 //*************************************************************************************************
5208 
5209 
5210 //*************************************************************************************************
5216 template< typename MT // Type of the dense matrix
5217  , size_t... CCAs > // Compile time column arguments
5218 inline size_t Column<MT,false,true,true,CCAs...>::size() const noexcept
5219 {
5220  return matrix_.rows();
5221 }
5223 //*************************************************************************************************
5224 
5225 
5226 //*************************************************************************************************
5235 template< typename MT // Type of the dense matrix
5236  , size_t... CCAs > // Compile time column arguments
5237 inline size_t Column<MT,false,true,true,CCAs...>::spacing() const noexcept
5238 {
5239  return matrix_.spacing();
5240 }
5242 //*************************************************************************************************
5243 
5244 
5245 //*************************************************************************************************
5251 template< typename MT // Type of the dense matrix
5252  , size_t... CCAs > // Compile time column arguments
5253 inline size_t Column<MT,false,true,true,CCAs...>::capacity() const noexcept
5254 {
5255  return matrix_.capacity( column() );
5256 }
5258 //*************************************************************************************************
5259 
5260 
5261 //*************************************************************************************************
5270 template< typename MT // Type of the dense matrix
5271  , size_t... CCAs > // Compile time column arguments
5273 {
5274  return matrix_.nonZeros( column() );
5275 }
5277 //*************************************************************************************************
5278 
5279 
5280 //*************************************************************************************************
5286 template< typename MT // Type of the dense matrix
5287  , size_t... CCAs > // Compile time column arguments
5289 {
5290  matrix_.reset( column() );
5291 }
5293 //*************************************************************************************************
5294 
5295 
5296 
5297 
5298 //=================================================================================================
5299 //
5300 // NUMERIC FUNCTIONS
5301 //
5302 //=================================================================================================
5303 
5304 //*************************************************************************************************
5317 template< typename MT // Type of the dense matrix
5318  , size_t... CCAs > // Compile time column arguments
5319 template< typename Other > // Data type of the scalar value
5320 inline Column<MT,false,true,true,CCAs...>&
5321  Column<MT,false,true,true,CCAs...>::scale( const Other& scalar )
5322 {
5324 
5325  const size_t jbegin( ( IsUpper_v<MT> )
5326  ?( ( IsStrictlyUpper_v<MT> )
5327  ?( column()+1UL )
5328  :( column() ) )
5329  :( 0UL ) );
5330  const size_t jend ( ( IsLower_v<MT> )
5331  ?( ( IsStrictlyLower_v<MT> )
5332  ?( column() )
5333  :( column()+1UL ) )
5334  :( size() ) );
5335 
5336  for( size_t j=jbegin; j<jend; ++j ) {
5337  matrix_(column(),j) *= scalar;
5338  }
5339 
5340  return *this;
5341 }
5343 //*************************************************************************************************
5344 
5345 
5346 
5347 
5348 //=================================================================================================
5349 //
5350 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
5351 //
5352 //=================================================================================================
5353 
5354 //*************************************************************************************************
5365 template< typename MT // Type of the dense matrix
5366  , size_t... CCAs > // Compile time column arguments
5367 template< typename Other > // Data type of the foreign expression
5368 inline bool Column<MT,false,true,true,CCAs...>::canAlias( const Other* alias ) const noexcept
5369 {
5370  return matrix_.isAliased( alias );
5371 }
5373 //*************************************************************************************************
5374 
5375 
5376 //*************************************************************************************************
5387 template< typename MT // Type of the dense matrix
5388  , size_t... CCAs > // Compile time column arguments
5389 template< typename MT2 // Data type of the foreign dense column
5390  , bool SO2 // Storage order of the foreign dense column
5391  , bool SF2 // Symmetry flag of the foreign dense column
5392  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
5393 inline bool
5394  Column<MT,false,true,true,CCAs...>::canAlias( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5395 {
5396  return matrix_.isAliased( alias->matrix_ ) && ( column() == alias->column() );
5397 }
5399 //*************************************************************************************************
5400 
5401 
5402 //*************************************************************************************************
5413 template< typename MT // Type of the dense matrix
5414  , size_t... CCAs > // Compile time column arguments
5415 template< typename Other > // Data type of the foreign expression
5416 inline bool Column<MT,false,true,true,CCAs...>::isAliased( const Other* alias ) const noexcept
5417 {
5418  return matrix_.isAliased( alias );
5419 }
5421 //*************************************************************************************************
5422 
5423 
5424 //*************************************************************************************************
5435 template< typename MT // Type of the dense matrix
5436  , size_t... CCAs > // Compile time column arguments
5437 template< typename MT2 // Data type of the foreign dense column
5438  , bool SO2 // Storage order of the foreign dense column
5439  , bool SF2 // Symmetry flag of the foreign dense column
5440  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column
5441 inline bool
5442  Column<MT,false,true,true,CCAs...>::isAliased( const Column<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5443 {
5444  return matrix_.isAliased( &alias->matrix_ ) && ( column() == alias->column() );
5445 }
5447 //*************************************************************************************************
5448 
5449 
5450 //*************************************************************************************************
5460 template< typename MT // Type of the dense matrix
5461  , size_t... CCAs > // Compile time column arguments
5462 inline bool Column<MT,false,true,true,CCAs...>::isAligned() const noexcept
5463 {
5464  return matrix_.isAligned();
5465 }
5467 //*************************************************************************************************
5468 
5469 
5470 //*************************************************************************************************
5481 template< typename MT // Type of the dense matrix
5482  , size_t... CCAs > // Compile time column arguments
5483 inline bool Column<MT,false,true,true,CCAs...>::canSMPAssign() const noexcept
5484 {
5485  return ( size() > SMP_DVECASSIGN_THRESHOLD );
5486 }
5488 //*************************************************************************************************
5489 
5490 
5491 //*************************************************************************************************
5503 template< typename MT // Type of the dense matrix
5504  , size_t... CCAs > // Compile time column arguments
5505 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true,CCAs...>::SIMDType
5506  Column<MT,false,true,true,CCAs...>::load( size_t index ) const noexcept
5507 {
5508  return matrix_.load( column(), index );
5509 }
5511 //*************************************************************************************************
5512 
5513 
5514 //*************************************************************************************************
5527 template< typename MT // Type of the dense matrix
5528  , size_t... CCAs > // Compile time column arguments
5529 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true,CCAs...>::SIMDType
5530  Column<MT,false,true,true,CCAs...>::loada( size_t index ) const noexcept
5531 {
5532  return matrix_.loada( column(), index );
5533 }
5535 //*************************************************************************************************
5536 
5537 
5538 //*************************************************************************************************
5551 template< typename MT // Type of the dense matrix
5552  , size_t... CCAs > // Compile time column arguments
5553 BLAZE_ALWAYS_INLINE typename Column<MT,false,true,true,CCAs...>::SIMDType
5554  Column<MT,false,true,true,CCAs...>::loadu( size_t index ) const noexcept
5555 {
5556  return matrix_.loadu( column(), index );
5557 }
5559 //*************************************************************************************************
5560 
5561 
5562 //*************************************************************************************************
5575 template< typename MT // Type of the dense matrix
5576  , size_t... CCAs > // Compile time column arguments
5578  Column<MT,false,true,true,CCAs...>::store( size_t index, const SIMDType& value ) noexcept
5579 {
5580  matrix_.store( column(), index, value );
5581 }
5583 //*************************************************************************************************
5584 
5585 
5586 //*************************************************************************************************
5600 template< typename MT // Type of the dense matrix
5601  , size_t... CCAs > // Compile time column arguments
5603  Column<MT,false,true,true,CCAs...>::storea( size_t index, const SIMDType& value ) noexcept
5604 {
5605  matrix_.storea( column(), index, value );
5606 }
5608 //*************************************************************************************************
5609 
5610 
5611 //*************************************************************************************************
5625 template< typename MT // Type of the dense matrix
5626  , size_t... CCAs > // Compile time column arguments
5628  Column<MT,false,true,true,CCAs...>::storeu( size_t index, const SIMDType& value ) noexcept
5629 {
5630  matrix_.storeu( column(), index, value );
5631 }
5633 //*************************************************************************************************
5634 
5635 
5636 //*************************************************************************************************
5650 template< typename MT // Type of the dense matrix
5651  , size_t... CCAs > // Compile time column arguments
5653  Column<MT,false,true,true,CCAs...>::stream( size_t index, const SIMDType& value ) noexcept
5654 {
5655  matrix_.stream( column(), index, value );
5656 }
5658 //*************************************************************************************************
5659 
5660 
5661 //*************************************************************************************************
5673 template< typename MT // Type of the dense matrix
5674  , size_t... CCAs > // Compile time column arguments
5675 template< typename VT > // Type of the right-hand side dense vector
5676 inline auto Column<MT,false,true,true,CCAs...>::assign( const DenseVector<VT,false>& rhs )
5677  -> DisableIf_t< VectorizedAssign_v<VT> >
5678 {
5679  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5680 
5681  const size_t jpos( (~rhs).size() & size_t(-2) );
5682  for( size_t j=0UL; j<jpos; j+=2UL ) {
5683  matrix_(column(),j ) = (~rhs)[j ];
5684  matrix_(column(),j+1UL) = (~rhs)[j+1UL];
5685  }
5686  if( jpos < (~rhs).size() )
5687  matrix_(column(),jpos) = (~rhs)[jpos];
5688 }
5690 //*************************************************************************************************
5691 
5692 
5693 //*************************************************************************************************
5705 template< typename MT // Type of the dense matrix
5706  , size_t... CCAs > // Compile time column arguments
5707 template< typename VT > // Type of the right-hand side dense vector
5708 inline auto Column<MT,false,true,true,CCAs...>::assign( const DenseVector<VT,false>& rhs )
5709  -> EnableIf_t< VectorizedAssign_v<VT> >
5710 {
5712 
5713  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5714 
5715  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5716 
5717  const size_t columns( size() );
5718 
5719  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5720  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5721 
5722  size_t j( 0UL );
5723  Iterator left( begin() );
5724  ConstIterator_t<VT> right( (~rhs).begin() );
5725 
5726  if( useStreaming && columns > ( cacheSize/( sizeof(ElementType) * 3UL ) ) && !(~rhs).isAliased( this ) )
5727  {
5728  for( ; j<jpos; j+=SIMDSIZE ) {
5729  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5730  }
5731  for( ; remainder && j<columns; ++j ) {
5732  *left = *right; ++left; ++right;
5733  }
5734  }
5735  else
5736  {
5737  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5738  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5739  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5740  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5741  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5742  }
5743  for( ; j<jpos; j+=SIMDSIZE ) {
5744  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5745  }
5746  for( ; remainder && j<columns; ++j ) {
5747  *left = *right; ++left; ++right;
5748  }
5749  }
5750 }
5752 //*************************************************************************************************
5753 
5754 
5755 //*************************************************************************************************
5767 template< typename MT // Type of the dense matrix
5768  , size_t... CCAs > // Compile time column arguments
5769 template< typename VT > // Type of the right-hand side sparse vector
5770 inline void Column<MT,false,true,true,CCAs...>::assign( const SparseVector<VT,false>& rhs )
5771 {
5772  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5773 
5774  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5775  matrix_(column(),element->index()) = element->value();
5776 }
5778 //*************************************************************************************************
5779 
5780 
5781 //*************************************************************************************************
5793 template< typename MT // Type of the dense matrix
5794  , size_t... CCAs > // Compile time column arguments
5795 template< typename VT > // Type of the right-hand side dense vector
5796 inline auto Column<MT,false,true,true,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
5797  -> DisableIf_t< VectorizedAddAssign_v<VT> >
5798 {
5799  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5800 
5801  const size_t jpos( (~rhs).size() & size_t(-2) );
5802  for( size_t j=0UL; j<jpos; j+=2UL ) {
5803  matrix_(column(),j ) += (~rhs)[j ];
5804  matrix_(column(),j+1UL) += (~rhs)[j+1UL];
5805  }
5806  if( jpos < (~rhs).size() )
5807  matrix_(column(),jpos) += (~rhs)[jpos];
5808 }
5810 //*************************************************************************************************
5811 
5812 
5813 //*************************************************************************************************
5825 template< typename MT // Type of the dense matrix
5826  , size_t... CCAs > // Compile time column arguments
5827 template< typename VT > // Type of the right-hand side dense vector
5828 inline auto Column<MT,false,true,true,CCAs...>::addAssign( const DenseVector<VT,false>& rhs )
5829  -> EnableIf_t< VectorizedAddAssign_v<VT> >
5830 {
5832 
5833  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5834 
5835  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5836 
5837  const size_t columns( size() );
5838 
5839  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5840  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5841 
5842  size_t j( 0UL );
5843  Iterator left( begin() );
5844  ConstIterator_t<VT> right( (~rhs).begin() );
5845 
5846  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5847  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5848  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5849  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5850  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5851  }
5852  for( ; j<jpos; j+=SIMDSIZE ) {
5853  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5854  }
5855  for( ; remainder && j<columns; ++j ) {
5856  *left += *right; ++left; ++right;
5857  }
5858 }
5860 //*************************************************************************************************
5861 
5862 
5863 //*************************************************************************************************
5875 template< typename MT // Type of the dense matrix
5876  , size_t... CCAs > // Compile time column arguments
5877 template< typename VT > // Type of the right-hand side sparse vector
5878 inline void Column<MT,false,true,true,CCAs...>::addAssign( const SparseVector<VT,false>& rhs )
5879 {
5880  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5881 
5882  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5883  matrix_(column(),element->index()) += element->value();
5884 }
5886 //*************************************************************************************************
5887 
5888 
5889 //*************************************************************************************************
5901 template< typename MT // Type of the dense matrix
5902  , size_t... CCAs > // Compile time column arguments
5903 template< typename VT > // Type of the right-hand side dense vector
5904 inline auto Column<MT,false,true,true,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
5905  -> DisableIf_t< VectorizedSubAssign_v<VT> >
5906 {
5907  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5908 
5909  const size_t jpos( (~rhs).size() & size_t(-2) );
5910  for( size_t j=0UL; j<jpos; j+=2UL ) {
5911  matrix_(column(),j ) -= (~rhs)[j ];
5912  matrix_(column(),j+1UL) -= (~rhs)[j+1UL];
5913  }
5914  if( jpos < (~rhs).size() )
5915  matrix_(column(),jpos) -= (~rhs)[jpos];
5916 }
5918 //*************************************************************************************************
5919 
5920 
5921 //*************************************************************************************************
5933 template< typename MT // Type of the dense matrix
5934  , size_t... CCAs > // Compile time column arguments
5935 template< typename VT > // Type of the right-hand side dense vector
5936 inline auto Column<MT,false,true,true,CCAs...>::subAssign( const DenseVector<VT,false>& rhs )
5937  -> EnableIf_t< VectorizedSubAssign_v<VT> >
5938 {
5940 
5941  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5942 
5943  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
5944 
5945  const size_t columns( size() );
5946 
5947  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
5948  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
5949 
5950  size_t j( 0UL );
5951  Iterator left( begin() );
5952  ConstIterator_t<VT> right( (~rhs).begin() );
5953 
5954  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
5955  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5956  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5957  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5958  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5959  }
5960  for( ; j<jpos; j+=SIMDSIZE ) {
5961  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
5962  }
5963  for( ; remainder && j<columns; ++j ) {
5964  *left -= *right; ++left; ++right;
5965  }
5966 }
5968 //*************************************************************************************************
5969 
5970 
5971 //*************************************************************************************************
5983 template< typename MT // Type of the dense matrix
5984  , size_t... CCAs > // Compile time column arguments
5985 template< typename VT > // Type of the right-hand side sparse vector
5986 inline void Column<MT,false,true,true,CCAs...>::subAssign( const SparseVector<VT,false>& rhs )
5987 {
5988  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
5989 
5990  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element )
5991  matrix_(column(),element->index()) -= element->value();
5992 }
5994 //*************************************************************************************************
5995 
5996 
5997 //*************************************************************************************************
6009 template< typename MT // Type of the dense matrix
6010  , size_t... CCAs > // Compile time column arguments
6011 template< typename VT > // Type of the right-hand side dense vector
6012 inline auto Column<MT,false,true,true,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
6013  -> DisableIf_t< VectorizedMultAssign_v<VT> >
6014 {
6015  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6016 
6017  const size_t jpos( (~rhs).size() & size_t(-2) );
6018  for( size_t j=0UL; j<jpos; j+=2UL ) {
6019  matrix_(column(),j ) *= (~rhs)[j ];
6020  matrix_(column(),j+1UL) *= (~rhs)[j+1UL];
6021  }
6022  if( jpos < (~rhs).size() )
6023  matrix_(column(),jpos) *= (~rhs)[jpos];
6024 }
6026 //*************************************************************************************************
6027 
6028 
6029 //*************************************************************************************************
6041 template< typename MT // Type of the dense matrix
6042  , size_t... CCAs > // Compile time column arguments
6043 template< typename VT > // Type of the right-hand side dense vector
6044 inline auto Column<MT,false,true,true,CCAs...>::multAssign( const DenseVector<VT,false>& rhs )
6045  -> EnableIf_t< VectorizedMultAssign_v<VT> >
6046 {
6048 
6049  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6050 
6051  constexpr bool remainder( !IsPadded_v<MT> || !IsPadded_v<VT> );
6052 
6053  const size_t columns( size() );
6054 
6055  const size_t jpos( ( remainder )?( columns & size_t(-SIMDSIZE) ):( columns ) );
6056  BLAZE_INTERNAL_ASSERT( !remainder || ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
6057 
6058  size_t j( 0UL );
6059  Iterator left( begin() );
6060  ConstIterator_t<VT> right( (~rhs).begin() );
6061 
6062  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
6063  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6064  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6065  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6066  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6067  }
6068  for( ; j<jpos; j+=SIMDSIZE ) {
6069  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6070  }
6071  for( ; remainder && j<columns; ++j ) {
6072  *left *= *right; ++left; ++right;
6073  }
6074 }
6076 //*************************************************************************************************
6077 
6078 
6079 //*************************************************************************************************
6091 template< typename MT // Type of the dense matrix
6092  , size_t... CCAs > // Compile time column arguments
6093 template< typename VT > // Type of the right-hand side sparse vector
6094 inline void Column<MT,false,true,true,CCAs...>::multAssign( const SparseVector<VT,false>& rhs )
6095 {
6096  using blaze::reset;
6097 
6098  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6099 
6100  size_t j( 0UL );
6101 
6102  for( ConstIterator_t<VT> element=(~rhs).begin(); element!=(~rhs).end(); ++element ) {
6103  const size_t index( element->index() );
6104  for( ; j<index; ++j )
6105  reset( matrix_(column(),j) );
6106  matrix_(column(),j) *= element->value();
6107  ++j;
6108  }
6109 
6110  for( ; j<size(); ++j ) {
6111  reset( matrix_(column(),j) );
6112  }
6113 }
6115 //*************************************************************************************************
6116 
6117 
6118 //*************************************************************************************************
6130 template< typename MT // Type of the dense matrix
6131  , size_t... CCAs > // Compile time column arguments
6132 template< typename VT > // Type of the right-hand side dense vector
6133 inline auto Column<MT,false,true,true,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
6134  -> DisableIf_t< VectorizedDivAssign_v<VT> >
6135 {
6136  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6137 
6138  const size_t jpos( (~rhs).size() & size_t(-2) );
6139  for( size_t j=0UL; j<jpos; j+=2UL ) {
6140  matrix_(column(),j ) /= (~rhs)[j ];
6141  matrix_(column(),j+1UL) /= (~rhs)[j+1UL];
6142  }
6143  if( jpos < (~rhs).size() )
6144  matrix_(column(),jpos) /= (~rhs)[jpos];
6145 }
6147 //*************************************************************************************************
6148 
6149 
6150 //*************************************************************************************************
6162 template< typename MT // Type of the dense matrix
6163  , size_t... CCAs > // Compile time column arguments
6164 template< typename VT > // Type of the right-hand side dense vector
6165 inline auto Column<MT,false,true,true,CCAs...>::divAssign( const DenseVector<VT,false>& rhs )
6166  -> EnableIf_t< VectorizedDivAssign_v<VT> >
6167 {
6169 
6170  BLAZE_INTERNAL_ASSERT( size() == (~rhs).size(), "Invalid vector sizes" );
6171 
6172  const size_t columns( size() );
6173 
6174  const size_t jpos( columns & size_t(-SIMDSIZE) );
6175  BLAZE_INTERNAL_ASSERT( ( columns - ( columns % (SIMDSIZE) ) ) == jpos, "Invalid end calculation" );
6176 
6177  size_t j( 0UL );
6178  Iterator left( begin() );
6179  ConstIterator_t<VT> right( (~rhs).begin() );
6180 
6181  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
6182  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6183  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6184  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6185  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6186  }
6187  for( ; j<jpos; j+=SIMDSIZE ) {
6188  left.store( left.load() / right.load() ); left += SIMDSIZE; right += SIMDSIZE;
6189  }
6190  for( ; j<columns; ++j ) {
6191  *left /= *right; ++left; ++right;
6192  }
6193 }
6195 //*************************************************************************************************
6196 
6197 } // namespace blaze
6198 
6199 #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:133
Header file for the blaze::checked and blaze::unchecked instances.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression,...
Definition: Assert.h:117
Header file for the IsUniUpper type trait.
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:546
Header file for basic type definitions.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:750
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:170
Header file for the View base class.
#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
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
#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
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:332
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
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:595
constexpr bool IsUniUpper_v
Auxiliary variable template for the IsUniUpper type trait.The IsUniUpper_v variable template provides...
Definition: IsUniUpper.h:173
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....
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
constexpr bool IsReference_v
Auxiliary variable template for the IsReference type trait.The IsReference_v variable template provid...
Definition: IsReference.h:95
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
#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
Header file for the reset shim.
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:187
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
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
constexpr bool IsLower_v
Auxiliary variable template for the IsLower type trait.The IsLower_v variable template provides a con...
Definition: IsLower.h:175
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
Header file for the IsUniLower type trait.
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
constexpr bool IsStrictlyLower_v
Auxiliary variable template for the IsStrictlyLower type trait.The IsStrictlyLower_v variable templat...
Definition: IsStrictlyLower.h:173
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:482
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:416
typename T::ElementType ElementType_t
Alias declaration for nested ElementType type definitions.The ElementType_t alias declaration provide...
Definition: Aliases.h:170
auto smpDivAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP division assignment of a vector to a dense vector.
Definition: DenseVector.h:220
Constraint on the data type.
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:253
Constraint on the transpose flag of vector types.
Constraint on the data type.
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.The EnableIf_t alias declaration provides a convenient...
Definition: EnableIf.h:138
typename ColumnTrait< MT, CCAs... >::Type ColumnTrait_t
Auxiliary alias declaration for the ColumnTrait type trait.The ColumnTrait_t alias declaration provid...
Definition: ColumnTrait.h:170
Header file for the DisableIf class template.
Header file for the IsStrictlyUpper type trait.
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
constexpr bool IsStrictlyUpper_v
Auxiliary variable template for the IsStrictlyUpper type trait.The IsStrictlyUpper_v variable templat...
Definition: IsStrictlyUpper.h:173
Header file for the If class template.
Header file for the implementation of a vector representation of an initializer list.
constexpr bool IsExpression_v
Auxiliary variable template for the IsExpression type trait.The IsExpression_v variable template prov...
Definition: IsExpression.h:130
#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
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:9091
#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
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:187
#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:370
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:446
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
Header file for all SIMD functionality.
constexpr bool Contains_v
Auxiliary variable template for the Contains type trait.The Contains_v variable template provides a c...
Definition: Contains.h:138
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
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.
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:438
constexpr bool HasSIMDDiv_v
Auxiliary variable template for the HasSIMDDiv type trait.The HasSIMDDiv_v variable template provides...
Definition: HasSIMDDiv.h:171
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
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:615
Header file for the IsPadded type trait.
Constraint on the data type.
auto operator/=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Division assignment operator for the division of a dense matrix by a scalar value ( ).
Definition: DenseMatrix.h:558
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,...
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.
Header file for run time assertion macros.
Header file for the cross product trait.
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
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:133
constexpr bool IsUniLower_v
Auxiliary variable template for the IsUniLower type trait.The IsUniLower_v variable template provides...
Definition: IsUniLower.h:173
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,...
Definition: Reference.h:79
Header file for the column trait.
Header file for the isDefault shim.
constexpr bool IsUpper_v
Auxiliary variable template for the IsUpper type trait.The IsUpper_v variable template provides a con...
Definition: IsUpper.h:175
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
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.
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:408
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.
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
constexpr const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:718
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:74
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional vector type,...
Definition: DenseVector.h:61
Header file for the HasSIMDDiv type trait.
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:188
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
auto operator *=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Multiplication assignment operator for the multiplication of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:494
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
Header file for the IsUpper type trait.
typename DisableIf< Condition, T >::Type DisableIf_t
Auxiliary type for the DisableIf class template.The DisableIf_t alias declaration provides a convenie...
Definition: DisableIf.h:138
Header file for the implementation of the ColumnData class template.
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,...
Definition: Assert.h:101
auto smpMultAssign(Vector< VT1, TF1 > &lhs, const Vector< VT2, TF2 > &rhs) -> EnableIf_t< IsDenseVector_v< VT1 > >
Default implementation of the SMP multiplication assignment of a vector to a dense vector.
Definition: DenseVector.h:191
Header file for the clear shim.
Header file for the IsExpression type trait class.
Constraint on the data type.