Dense.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_VIEWS_COLUMNS_DENSE_H_
36 #define _BLAZE_MATH_VIEWS_COLUMNS_DENSE_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <blaze/math/Aliases.h>
57 #include <blaze/math/Exception.h>
61 #include <blaze/math/shims/Reset.h>
62 #include <blaze/math/SIMD.h>
81 #include <blaze/math/views/Check.h>
84 #include <blaze/system/Blocking.h>
85 #include <blaze/system/CacheSize.h>
86 #include <blaze/system/Inline.h>
89 #include <blaze/util/Assert.h>
94 #include <blaze/util/DisableIf.h>
95 #include <blaze/util/EnableIf.h>
96 #include <blaze/util/mpl/If.h>
97 #include <blaze/util/TypeList.h>
98 #include <blaze/util/Types.h>
101 #include <blaze/util/Unused.h>
102 
103 
104 namespace blaze {
105 
106 //=================================================================================================
107 //
108 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR DENSE MATRICES
109 //
110 //=================================================================================================
111 
112 //*************************************************************************************************
120 template< typename MT // Type of the dense matrix
121  , bool SF // Symmetry flag
122  , typename... CCAs > // Compile time column arguments
123 class Columns<MT,true,true,SF,CCAs...>
124  : public View< DenseMatrix< Columns<MT,true,true,SF,CCAs...>, true > >
125  , private ColumnsData<CCAs...>
126 {
127  private:
128  //**Type definitions****************************************************************************
129  using DataType = ColumnsData<CCAs...>;
130  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
131  //**********************************************************************************************
132 
133  //**Compile time flags**************************************************************************
134  static constexpr size_t N = sizeof...( CCAs );
135  //**********************************************************************************************
136 
137  //**********************************************************************************************
139  template< typename MT1, typename MT2 >
140  static constexpr bool EnforceEvaluation_v =
141  ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
142  //**********************************************************************************************
143 
144  public:
145  //**Type definitions****************************************************************************
147  using This = Columns<MT,true,true,SF,CCAs...>;
148 
149  using BaseType = DenseMatrix<This,true>;
150  using ViewedType = MT;
151  using ResultType = ColumnsTrait_t<MT,N>;
152  using OppositeType = OppositeType_t<ResultType>;
153  using TransposeType = TransposeType_t<ResultType>;
154  using ElementType = ElementType_t<MT>;
155  using SIMDType = SIMDTrait_t<ElementType>;
156  using ReturnType = ReturnType_t<MT>;
157  using CompositeType = const Columns&;
158 
160  using ConstReference = ConstReference_t<MT>;
161 
163  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
164 
166  using ConstPointer = ConstPointer_t<MT>;
167 
169  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
170 
172  using ConstIterator = ConstIterator_t<MT>;
173 
175  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
176  //**********************************************************************************************
177 
178  //**Compilation flags***************************************************************************
180  static constexpr bool simdEnabled = MT::simdEnabled;
181 
183  static constexpr bool smpAssignable = MT::smpAssignable;
184  //**********************************************************************************************
185 
186  //**Constructors********************************************************************************
189  template< typename... RCAs >
190  explicit inline Columns( MT& matrix, RCAs... args );
191 
192  Columns( const Columns& ) = default;
193  Columns( Columns&& ) = default;
195  //**********************************************************************************************
196 
197  //**Destructor**********************************************************************************
200  ~Columns() = default;
202  //**********************************************************************************************
203 
204  //**Data access functions***********************************************************************
207  inline Reference operator()( size_t i, size_t j );
208  inline ConstReference operator()( size_t i, size_t j ) const;
209  inline Reference at( size_t i, size_t j );
210  inline ConstReference at( size_t i, size_t j ) const;
211  inline Pointer data () noexcept;
212  inline ConstPointer data () const noexcept;
213  inline Pointer data ( size_t j ) noexcept;
214  inline ConstPointer data ( size_t j ) const noexcept;
215  inline Iterator begin ( size_t j );
216  inline ConstIterator begin ( size_t j ) const;
217  inline ConstIterator cbegin( size_t j ) const;
218  inline Iterator end ( size_t j );
219  inline ConstIterator end ( size_t j ) const;
220  inline ConstIterator cend ( size_t j ) const;
222  //**********************************************************************************************
223 
224  //**Assignment operators************************************************************************
227  inline Columns& operator=( const ElementType& rhs );
228  inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
229  inline Columns& operator=( const Columns& rhs );
230 
231  template< typename MT2, bool SO2 >
232  inline Columns& operator=( const Matrix<MT2,SO2>& rhs );
233 
234  template< typename MT2, bool SO2 >
235  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
236  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
237 
238  template< typename MT2, bool SO2 >
239  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
240  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
241 
242  template< typename MT2, bool SO2 >
243  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
244  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
245 
246  template< typename MT2, bool SO2 >
247  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
248  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
249 
250  template< typename MT2, bool SO2 >
251  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
252  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
253 
254  template< typename MT2, bool SO2 >
255  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
256  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
258  //**********************************************************************************************
259 
260  //**Utility functions***************************************************************************
263  using DataType::idx;
264  using DataType::idces;
265  using DataType::columns;
266 
267  inline MT& operand() noexcept;
268  inline const MT& operand() const noexcept;
269 
270  inline size_t rows() const noexcept;
271  inline size_t spacing() const noexcept;
272  inline size_t capacity() const noexcept;
273  inline size_t capacity( size_t j ) const noexcept;
274  inline size_t nonZeros() const;
275  inline size_t nonZeros( size_t j ) const;
276  inline void reset();
277  inline void reset( size_t j );
279  //**********************************************************************************************
280 
281  //**Numeric functions***************************************************************************
284  inline Columns& transpose();
285  inline Columns& ctranspose();
286 
287  template< typename Other > inline Columns& scale( const Other& scalar );
289  //**********************************************************************************************
290 
291  private:
292  //**********************************************************************************************
294  template< typename MT2 >
295  static constexpr bool VectorizedAssign_v =
296  ( useOptimizedKernels &&
297  simdEnabled && MT2::simdEnabled &&
299  //**********************************************************************************************
300 
301  //**********************************************************************************************
303  template< typename MT2 >
304  static constexpr bool VectorizedAddAssign_v =
305  ( useOptimizedKernels &&
306  simdEnabled && MT2::simdEnabled &&
309  !IsDiagonal_v<MT2> );
310  //**********************************************************************************************
311 
312  //**********************************************************************************************
314  template< typename MT2 >
315  static constexpr bool VectorizedSubAssign_v =
316  ( useOptimizedKernels &&
317  simdEnabled && MT2::simdEnabled &&
320  !IsDiagonal_v<MT2> );
321  //**********************************************************************************************
322 
323  //**********************************************************************************************
325  template< typename MT2 >
326  static constexpr bool VectorizedSchurAssign_v =
327  ( useOptimizedKernels &&
328  simdEnabled && MT2::simdEnabled &&
331  //**********************************************************************************************
332 
333  //**SIMD properties*****************************************************************************
335  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
336  //**********************************************************************************************
337 
338  public:
339  //**Expression template evaluation functions****************************************************
342  template< typename Other >
343  inline bool canAlias( const Other* alias ) const noexcept;
344 
345  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
346  inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
347 
348  template< typename Other >
349  inline bool isAliased( const Other* alias ) const noexcept;
350 
351  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
352  inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
353 
354  inline bool isAligned () const noexcept;
355  inline bool canSMPAssign() const noexcept;
356 
357  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
358  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
359  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
360 
361  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
362  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
363  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
364  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
365 
366  template< typename MT2 >
367  inline auto assign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT2> >;
368 
369  template< typename MT2 >
370  inline auto assign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT2> >;
371 
372  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
373 
374  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
375  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
376 
377  template< typename MT2 >
378  inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT2> >;
379 
380  template< typename MT2 >
381  inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT2> >;
382 
383  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
384  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
385  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
386 
387  template< typename MT2 >
388  inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT2> >;
389 
390  template< typename MT2 >
391  inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT2> >;
392 
393  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
394  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
395  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
396 
397  template< typename MT2 >
398  inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT2> >;
399 
400  template< typename MT2 >
401  inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT2> >;
402 
403  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
404  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
405  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
407  //**********************************************************************************************
408 
409  private:
410  //**Member variables****************************************************************************
413  Operand matrix_;
414 
415  //**********************************************************************************************
416 
417  //**Friend declarations*************************************************************************
418  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
419  //**********************************************************************************************
420 
421  //**Compile time checks*************************************************************************
430  //**********************************************************************************************
431 };
433 //*************************************************************************************************
434 
435 
436 
437 
438 //=================================================================================================
439 //
440 // CONSTRUCTORS
441 //
442 //=================================================================================================
443 
444 //*************************************************************************************************
457 template< typename MT // Type of the dense matrix
458  , bool SF // Symmetry flag
459  , typename... CCAs > // Compile time column arguments
460 template< typename... RCAs > // Runtime column arguments
461 inline Columns<MT,true,true,SF,CCAs...>::Columns( MT& matrix, RCAs... args )
462  : DataType( args... ) // Base class initialization
463  , matrix_ ( matrix ) // The matrix containing the columns
464 {
465  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
466  for( size_t j=0UL; j<columns(); ++j ) {
467  if( matrix_.columns() <= idx(j) ) {
468  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
469  }
470  }
471  }
472 }
474 //*************************************************************************************************
475 
476 
477 
478 
479 //=================================================================================================
480 //
481 // DATA ACCESS FUNCTIONS
482 //
483 //=================================================================================================
484 
485 //*************************************************************************************************
496 template< typename MT // Type of the dense matrix
497  , bool SF // Symmetry flag
498  , typename... CCAs > // Compile time column arguments
499 inline typename Columns<MT,true,true,SF,CCAs...>::Reference
500  Columns<MT,true,true,SF,CCAs...>::operator()( size_t i, size_t j )
501 {
502  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
503  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
504 
505  return matrix_(i,idx(j));
506 }
508 //*************************************************************************************************
509 
510 
511 //*************************************************************************************************
522 template< typename MT // Type of the dense matrix
523  , bool SF // Symmetry flag
524  , typename... CCAs > // Compile time column arguments
525 inline typename Columns<MT,true,true,SF,CCAs...>::ConstReference
526  Columns<MT,true,true,SF,CCAs...>::operator()( size_t i, size_t j ) const
527 {
528  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
529  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
530 
531  return const_cast<const MT&>( matrix_ )(i,idx(j));
532 }
534 //*************************************************************************************************
535 
536 
537 //*************************************************************************************************
549 template< typename MT // Type of the dense matrix
550  , bool SF // Symmetry flag
551  , typename... CCAs > // Compile time column arguments
552 inline typename Columns<MT,true,true,SF,CCAs...>::Reference
553  Columns<MT,true,true,SF,CCAs...>::at( size_t i, size_t j )
554 {
555  if( i >= rows() ) {
556  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
557  }
558  if( j >= columns() ) {
559  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
560  }
561  return (*this)(i,j);
562 }
564 //*************************************************************************************************
565 
566 
567 //*************************************************************************************************
579 template< typename MT // Type of the dense matrix
580  , bool SF // Symmetry flag
581  , typename... CCAs > // Compile time column arguments
582 inline typename Columns<MT,true,true,SF,CCAs...>::ConstReference
583  Columns<MT,true,true,SF,CCAs...>::at( size_t i, size_t j ) const
584 {
585  if( i >= rows() ) {
586  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
587  }
588  if( j >= columns() ) {
589  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
590  }
591  return (*this)(i,j);
592 }
594 //*************************************************************************************************
595 
596 
597 //*************************************************************************************************
607 template< typename MT // Type of the dense matrix
608  , bool SF // Symmetry flag
609  , typename... CCAs > // Compile time column arguments
610 inline typename Columns<MT,true,true,SF,CCAs...>::Pointer
612 {
613  return matrix_.data( idx(0UL) );
614 }
616 //*************************************************************************************************
617 
618 
619 //*************************************************************************************************
629 template< typename MT // Type of the dense matrix
630  , bool SF // Symmetry flag
631  , typename... CCAs > // Compile time column arguments
632 inline typename Columns<MT,true,true,SF,CCAs...>::ConstPointer
634 {
635  return matrix_.data( idx(0UL) );
636 }
638 //*************************************************************************************************
639 
640 
641 //*************************************************************************************************
650 template< typename MT // Type of the dense matrix
651  , bool SF // Symmetry flag
652  , typename... CCAs > // Compile time column arguments
653 inline typename Columns<MT,true,true,SF,CCAs...>::Pointer
654  Columns<MT,true,true,SF,CCAs...>::data( size_t j ) noexcept
655 {
656  return matrix_.data( idx(j) );
657 }
659 //*************************************************************************************************
660 
661 
662 //*************************************************************************************************
671 template< typename MT // Type of the dense matrix
672  , bool SF // Symmetry flag
673  , typename... CCAs > // Compile time column arguments
674 inline typename Columns<MT,true,true,SF,CCAs...>::ConstPointer
675  Columns<MT,true,true,SF,CCAs...>::data( size_t j ) const noexcept
676 {
677  return matrix_.data( idx(j) );
678 }
680 //*************************************************************************************************
681 
682 
683 //*************************************************************************************************
692 template< typename MT // Type of the dense matrix
693  , bool SF // Symmetry flag
694  , typename... CCAs > // Compile time column arguments
695 inline typename Columns<MT,true,true,SF,CCAs...>::Iterator
697 {
698  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
699  return matrix_.begin( idx(j) );
700 }
702 //*************************************************************************************************
703 
704 
705 //*************************************************************************************************
714 template< typename MT // Type of the dense matrix
715  , bool SF // Symmetry flag
716  , typename... CCAs > // Compile time column arguments
717 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
719 {
720  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
721  return matrix_.cbegin( idx(j) );
722 }
724 //*************************************************************************************************
725 
726 
727 //*************************************************************************************************
736 template< typename MT // Type of the dense matrix
737  , bool SF // Symmetry flag
738  , typename... CCAs > // Compile time column arguments
739 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
741 {
742  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
743  return matrix_.cbegin( idx(j) );
744 }
746 //*************************************************************************************************
747 
748 
749 //*************************************************************************************************
758 template< typename MT // Type of the dense matrix
759  , bool SF // Symmetry flag
760  , typename... CCAs > // Compile time column arguments
761 inline typename Columns<MT,true,true,SF,CCAs...>::Iterator
763 {
764  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
765  return matrix_.end( idx(j) );
766 }
768 //*************************************************************************************************
769 
770 
771 //*************************************************************************************************
780 template< typename MT // Type of the dense matrix
781  , bool SF // Symmetry flag
782  , typename... CCAs > // Compile time column arguments
783 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
784  Columns<MT,true,true,SF,CCAs...>::end( size_t j ) const
785 {
786  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
787  return matrix_.cend( idx(j) );
788 }
790 //*************************************************************************************************
791 
792 
793 //*************************************************************************************************
802 template< typename MT // Type of the dense matrix
803  , bool SF // Symmetry flag
804  , typename... CCAs > // Compile time column arguments
805 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
807 {
808  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
809  return matrix_.cend( idx(j) );
810 }
812 //*************************************************************************************************
813 
814 
815 
816 
817 //=================================================================================================
818 //
819 // ASSIGNMENT OPERATORS
820 //
821 //=================================================================================================
822 
823 //*************************************************************************************************
834 template< typename MT // Type of the dense matrix
835  , bool SF // Symmetry flag
836  , typename... CCAs > // Compile time column arguments
837 inline Columns<MT,true,true,SF,CCAs...>&
838  Columns<MT,true,true,SF,CCAs...>::operator=( const ElementType& rhs )
839 {
840  for( size_t j=0UL; j<columns(); ++j ) {
841  column( matrix_, idx(j), unchecked ) = rhs;
842  }
843 
844  return *this;
845 }
847 //*************************************************************************************************
848 
849 
850 //*************************************************************************************************
866 template< typename MT // Type of the dense matrix
867  , bool SF // Symmetry flag
868  , typename... CCAs > // Compile time column arguments
869 inline Columns<MT,true,true,SF,CCAs...>&
870  Columns<MT,true,true,SF,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
871 {
874 
875  if( list.size() != rows() ) {
876  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
877  }
878 
879  if( IsRestricted_v<MT> ) {
880  const InitializerMatrix<ElementType> tmp( list, columns() );
881  for( size_t j=0UL; j<columns(); ++j ) {
882  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
883  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
884  }
885  }
886  }
887 
888  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
889  size_t i( 0UL );
890 
891  for( const auto& rowList : list ) {
892  size_t j( 0UL );
893  for( const auto& element : rowList ) {
894  matrix_(i,idx(j)) = element;
895  ++j;
896  }
897  for( ; j<columns(); ++j ) {
898  matrix_(i,idx(j)) = ElementType();
899  }
900  ++i;
901  }
902 
903  return *this;
904 }
906 //*************************************************************************************************
907 
908 
909 //*************************************************************************************************
924 template< typename MT // Type of the dense matrix
925  , bool SF // Symmetry flag
926  , typename... CCAs > // Compile time column arguments
927 inline Columns<MT,true,true,SF,CCAs...>&
928  Columns<MT,true,true,SF,CCAs...>::operator=( const Columns& rhs )
929 {
932 
935 
936  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
937  return *this;
938 
939  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
940  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
941  }
942 
943  if( IsRestricted_v<MT> ) {
944  for( size_t j=0UL; j<columns(); ++j ) {
945  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( rhs, j, unchecked ), 0UL ) ) {
946  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
947  }
948  }
949  }
950 
951  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
952 
953  if( rhs.canAlias( &matrix_ ) ) {
954  const ResultType tmp( rhs );
955  smpAssign( left, tmp );
956  }
957  else {
958  smpAssign( left, rhs );
959  }
960 
961  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
962 
963  return *this;
964 }
966 //*************************************************************************************************
967 
968 
969 //*************************************************************************************************
984 template< typename MT // Type of the dense matrix
985  , bool SF // Symmetry flag
986  , typename... CCAs > // Compile time column arguments
987 template< typename MT2 // Type of the right-hand side matrix
988  , bool SO2 > // Storage order of the right-hand side matrix
989 inline Columns<MT,true,true,SF,CCAs...>&
990  Columns<MT,true,true,SF,CCAs...>::operator=( const Matrix<MT2,SO2>& rhs )
991 {
994 
996 
997  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
998  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
999  }
1000 
1001  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
1002  Right right( ~rhs );
1003 
1004  if( IsRestricted_v<MT> ) {
1005  for( size_t j=0UL; j<columns(); ++j ) {
1006  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( right, j, unchecked ), 0UL ) ) {
1007  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1008  }
1009  }
1010  }
1011 
1012  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1013 
1014  if( IsSparseMatrix_v<MT2> ) {
1015  reset();
1016  }
1017 
1018  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
1019  const ResultType_t<MT2> tmp( right );
1020  smpAssign( left, tmp );
1021  }
1022  else {
1023  smpAssign( left, right );
1024  }
1025 
1026  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1027 
1028  return *this;
1029 }
1031 //*************************************************************************************************
1032 
1033 
1034 //*************************************************************************************************
1048 template< typename MT // Type of the dense matrix
1049  , bool SF // Symmetry flag
1050  , typename... CCAs > // Compile time column arguments
1051 template< typename MT2 // Type of the right-hand side matrix
1052  , bool SO2 > // Storage order of the right-hand side matrix
1053 inline auto Columns<MT,true,true,SF,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1054  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1055 {
1058 
1061  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1062 
1063  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1064 
1067 
1068  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1069  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1070  }
1071 
1072  if( IsRestricted_v<MT> ) {
1073  for( size_t j=0UL; j<columns(); ++j ) {
1074  if( !tryAddAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
1075  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1076  }
1077  }
1078  }
1079 
1080  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1081 
1082  if( (~rhs).canAlias( &matrix_ ) ) {
1083  const AddType tmp( *this + (~rhs) );
1084  smpAssign( left, tmp );
1085  }
1086  else {
1087  smpAddAssign( left, ~rhs );
1088  }
1089 
1090  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1091 
1092  return *this;
1093 }
1095 //*************************************************************************************************
1096 
1097 
1098 //*************************************************************************************************
1112 template< typename MT // Type of the dense matrix
1113  , bool SF // Symmetry flag
1114  , typename... CCAs > // Compile time column arguments
1115 template< typename MT2 // Type of the right-hand side matrix
1116  , bool SO2 > // Storage order of the right-hand side matrix
1117 inline auto Columns<MT,true,true,SF,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1118  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1119 {
1122 
1125  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1126 
1127  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1128 
1131 
1132  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1133  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1134  }
1135 
1136  const AddType tmp( *this + (~rhs) );
1137 
1138  if( IsRestricted_v<MT> ) {
1139  for( size_t j=0UL; j<columns(); ++j ) {
1140  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1141  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1142  }
1143  }
1144  }
1145 
1146  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1147 
1148  smpAssign( left, tmp );
1149 
1150  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1151 
1152  return *this;
1153 }
1155 //*************************************************************************************************
1156 
1157 
1158 //*************************************************************************************************
1172 template< typename MT // Type of the dense matrix
1173  , bool SF // Symmetry flag
1174  , typename... CCAs > // Compile time column arguments
1175 template< typename MT2 // Type of the right-hand side matrix
1176  , bool SO2 > // Storage order of the right-hand side matrix
1177 inline auto Columns<MT,true,true,SF,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1178  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1179 {
1182 
1185  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1186 
1187  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1188 
1191 
1192  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1193  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1194  }
1195 
1196  if( IsRestricted_v<MT> ) {
1197  for( size_t j=0UL; j<columns(); ++j ) {
1198  if( !trySubAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
1199  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1200  }
1201  }
1202  }
1203 
1204  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1205 
1206  if( (~rhs).canAlias( &matrix_ ) ) {
1207  const SubType tmp( *this - (~rhs ) );
1208  smpAssign( left, tmp );
1209  }
1210  else {
1211  smpSubAssign( left, ~rhs );
1212  }
1213 
1214  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1215 
1216  return *this;
1217 }
1219 //*************************************************************************************************
1220 
1221 
1222 //*************************************************************************************************
1236 template< typename MT // Type of the dense matrix
1237  , bool SF // Symmetry flag
1238  , typename... CCAs > // Compile time column arguments
1239 template< typename MT2 // Type of the right-hand side matrix
1240  , bool SO2 > // Storage order of the right-hand side matrix
1241 inline auto Columns<MT,true,true,SF,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1242  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1243 {
1246 
1249  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1250 
1251  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1252 
1255 
1256  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1257  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1258  }
1259 
1260  const SubType tmp( *this - (~rhs) );
1261 
1262  if( IsRestricted_v<MT> ) {
1263  for( size_t j=0UL; j<columns(); ++j ) {
1264  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1265  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1266  }
1267  }
1268  }
1269 
1270  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1271 
1272  smpAssign( left, tmp );
1273 
1274  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1275 
1276  return *this;
1277 }
1279 //*************************************************************************************************
1280 
1281 
1282 //*************************************************************************************************
1296 template< typename MT // Type of the dense matrix
1297  , bool SF // Symmetry flag
1298  , typename... CCAs > // Compile time column arguments
1299 template< typename MT2 // Type of the right-hand side matrix
1300  , bool SO2 > // Storage order of the right-hand side matrix
1301 inline auto Columns<MT,true,true,SF,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1302  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1303 {
1306 
1309  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1310 
1311  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1312 
1314 
1315  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1316  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1317  }
1318 
1319  if( IsRestricted_v<MT> ) {
1320  for( size_t j=0UL; j<columns(); ++j ) {
1321  if( !tryMultAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
1322  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1323  }
1324  }
1325  }
1326 
1327  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1328 
1329  if( (~rhs).canAlias( &matrix_ ) ) {
1330  const SchurType tmp( *this % (~rhs) );
1331  if( IsSparseMatrix_v<SchurType> )
1332  reset();
1333  smpAssign( left, tmp );
1334  }
1335  else {
1336  smpSchurAssign( left, ~rhs );
1337  }
1338 
1339  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1340 
1341  return *this;
1342 }
1344 //*************************************************************************************************
1345 
1346 
1347 //*************************************************************************************************
1361 template< typename MT // Type of the dense matrix
1362  , bool SF // Symmetry flag
1363  , typename... CCAs > // Compile time column arguments
1364 template< typename MT2 // Type of the right-hand side matrix
1365  , bool SO2 > // Storage order of the right-hand side matrix
1366 inline auto Columns<MT,true,true,SF,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1367  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1368 {
1371 
1374  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1375 
1376  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1377 
1379 
1380  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1381  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1382  }
1383 
1384  const SchurType tmp( *this % (~rhs) );
1385 
1386  if( IsRestricted_v<MT> ) {
1387  for( size_t j=0UL; j<columns(); ++j ) {
1388  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1389  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1390  }
1391  }
1392  }
1393 
1394  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1395 
1396  if( IsSparseMatrix_v<SchurType> ) {
1397  reset();
1398  }
1399 
1400  smpAssign( left, tmp );
1401 
1402  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1403 
1404  return *this;
1405 }
1407 //*************************************************************************************************
1408 
1409 
1410 
1411 
1412 //=================================================================================================
1413 //
1414 // UTILITY FUNCTIONS
1415 //
1416 //=================================================================================================
1417 
1418 //*************************************************************************************************
1424 template< typename MT // Type of the dense matrix
1425  , bool SF // Symmetry flag
1426  , typename... CCAs > // Compile time column arguments
1427 inline MT& Columns<MT,true,true,SF,CCAs...>::operand() noexcept
1428 {
1429  return matrix_;
1430 }
1432 //*************************************************************************************************
1433 
1434 
1435 //*************************************************************************************************
1441 template< typename MT // Type of the dense matrix
1442  , bool SF // Symmetry flag
1443  , typename... CCAs > // Compile time column arguments
1444 inline const MT& Columns<MT,true,true,SF,CCAs...>::operand() const noexcept
1445 {
1446  return matrix_;
1447 }
1449 //*************************************************************************************************
1450 
1451 
1452 //*************************************************************************************************
1458 template< typename MT // Type of the dense matrix
1459  , bool SF // Symmetry flag
1460  , typename... CCAs > // Compile time column arguments
1461 inline size_t Columns<MT,true,true,SF,CCAs...>::rows() const noexcept
1462 {
1463  return matrix_.rows();
1464 }
1466 //*************************************************************************************************
1467 
1468 
1469 //*************************************************************************************************
1478 template< typename MT // Type of the dense matrix
1479  , bool SF // Symmetry flag
1480  , typename... CCAs > // Compile time column arguments
1481 inline size_t Columns<MT,true,true,SF,CCAs...>::spacing() const noexcept
1482 {
1483  return matrix_.spacing();
1484 }
1486 //*************************************************************************************************
1487 
1488 
1489 //*************************************************************************************************
1495 template< typename MT // Type of the dense matrix
1496  , bool SF // Symmetry flag
1497  , typename... CCAs > // Compile time column arguments
1498 inline size_t Columns<MT,true,true,SF,CCAs...>::capacity() const noexcept
1499 {
1500  return rows() * columns();
1501 }
1503 //*************************************************************************************************
1504 
1505 
1506 //*************************************************************************************************
1515 template< typename MT // Type of the dense matrix
1516  , bool SF // Symmetry flag
1517  , typename... CCAs > // Compile time column arguments
1518 inline size_t Columns<MT,true,true,SF,CCAs...>::capacity( size_t j ) const noexcept
1519 {
1520  UNUSED_PARAMETER( j );
1521 
1522  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1523 
1524  return rows();
1525 }
1527 //*************************************************************************************************
1528 
1529 
1530 //*************************************************************************************************
1536 template< typename MT // Type of the dense matrix
1537  , bool SF // Symmetry flag
1538  , typename... CCAs > // Compile time column arguments
1539 inline size_t Columns<MT,true,true,SF,CCAs...>::nonZeros() const
1540 {
1541  size_t nonzeros( 0UL );
1542 
1543  for( size_t j=0UL; j<columns(); ++j ) {
1544  nonzeros += matrix_.nonZeros( idx(j) );
1545  }
1546 
1547  return nonzeros;
1548 }
1550 //*************************************************************************************************
1551 
1552 
1553 //*************************************************************************************************
1562 template< typename MT // Type of the dense matrix
1563  , bool SF // Symmetry flag
1564  , typename... CCAs > // Compile time column arguments
1565 inline size_t Columns<MT,true,true,SF,CCAs...>::nonZeros( size_t j ) const
1566 {
1567  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1568 
1569  return matrix_.nonZeros( idx(j) );
1570 }
1572 //*************************************************************************************************
1573 
1574 
1575 //*************************************************************************************************
1581 template< typename MT // Type of the dense matrix
1582  , bool SF // Symmetry flag
1583  , typename... CCAs > // Compile time column arguments
1585 {
1586  for( size_t j=0UL; j<columns(); ++j ) {
1587  matrix_.reset( idx(j) );
1588  }
1589 }
1591 //*************************************************************************************************
1592 
1593 
1594 //*************************************************************************************************
1603 template< typename MT // Type of the dense matrix
1604  , bool SF // Symmetry flag
1605  , typename... CCAs > // Compile time column arguments
1606 inline void Columns<MT,true,true,SF,CCAs...>::reset( size_t j )
1607 {
1608  matrix_.reset( idx(j) );
1609 }
1611 //*************************************************************************************************
1612 
1613 
1614 
1615 
1616 //=================================================================================================
1617 //
1618 // NUMERIC FUNCTIONS
1619 //
1620 //=================================================================================================
1621 
1622 //*************************************************************************************************
1635 template< typename MT // Type of the dense matrix
1636  , bool SF // Symmetry flag
1637  , typename... CCAs > // Compile time column arguments
1638 inline Columns<MT,true,true,SF,CCAs...>&
1640 {
1643 
1644  if( rows() != columns() ) {
1645  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1646  }
1647 
1648  const ResultType tmp( trans( *this ) );
1649 
1650  if( IsRestricted_v<MT> ) {
1651  for( size_t j=0UL; j<columns(); ++j ) {
1652  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
1653  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1654  }
1655  }
1656  }
1657 
1658  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1659 
1660  smpAssign( left, tmp );
1661 
1662  return *this;
1663 }
1665 //*************************************************************************************************
1666 
1667 
1668 //*************************************************************************************************
1681 template< typename MT // Type of the dense matrix
1682  , bool SF // Symmetry flag
1683  , typename... CCAs > // Compile time column arguments
1684 inline Columns<MT,true,true,SF,CCAs...>&
1686 {
1689 
1690  if( rows() != columns() ) {
1691  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1692  }
1693 
1694  const ResultType tmp( ctrans( *this ) );
1695 
1696  if( IsRestricted_v<MT> ) {
1697  for( size_t j=0UL; j<columns(); ++j ) {
1698  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
1699  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1700  }
1701  }
1702  }
1703 
1704  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1705 
1706  smpAssign( left, tmp );
1707 
1708  return *this;
1709 }
1711 //*************************************************************************************************
1712 
1713 
1714 //*************************************************************************************************
1727 template< typename MT // Type of the dense matrix
1728  , bool SF // Symmetry flag
1729  , typename... CCAs > // Compile time column arguments
1730 template< typename Other > // Data type of the scalar value
1731 inline Columns<MT,true,true,SF,CCAs...>&
1732  Columns<MT,true,true,SF,CCAs...>::scale( const Other& scalar )
1733 {
1737 
1738  for( size_t j=0UL; j<columns(); ++j )
1739  {
1740  const size_t index ( idx(j) );
1741  const size_t ibegin( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index+1UL : index ) : 0UL );
1742  const size_t iend ( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index : index+1UL ) : rows() );
1743 
1744  for( size_t i=ibegin; i<iend; ++i ) {
1745  matrix_(i,index) *= scalar;
1746  }
1747  }
1748 
1749  return *this;
1750 }
1752 //*************************************************************************************************
1753 
1754 
1755 
1756 
1757 //=================================================================================================
1758 //
1759 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1760 //
1761 //=================================================================================================
1762 
1763 //*************************************************************************************************
1774 template< typename MT // Type of the dense matrix
1775  , bool SF // Symmetry flag
1776  , typename... CCAs > // Compile time column arguments
1777 template< typename Other > // Data type of the foreign expression
1778 inline bool Columns<MT,true,true,SF,CCAs...>::canAlias( const Other* alias ) const noexcept
1779 {
1780  return matrix_.isAliased( alias );
1781 }
1783 //*************************************************************************************************
1784 
1785 
1786 //*************************************************************************************************
1798 template< typename MT // Type of the dense matrix
1799  , bool SF // Symmetry flag
1800  , typename... CCAs > // Compile time column arguments
1801 template< typename MT2 // Data type of the foreign dense column selection
1802  , bool SO2 // Storage order of the foreign dense column selection
1803  , bool SF2 // Symmetry flag of the foreign dense column selection
1804  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
1805 inline bool
1806  Columns<MT,true,true,SF,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1807 {
1808  return matrix_.isAliased( &alias->matrix_ );
1809 }
1811 //*************************************************************************************************
1812 
1813 
1814 //*************************************************************************************************
1825 template< typename MT // Type of the dense matrix
1826  , bool SF // Symmetry flag
1827  , typename... CCAs > // Compile time column arguments
1828 template< typename Other > // Data type of the foreign expression
1829 inline bool Columns<MT,true,true,SF,CCAs...>::isAliased( const Other* alias ) const noexcept
1830 {
1831  return matrix_.isAliased( alias );
1832 }
1834 //*************************************************************************************************
1835 
1836 
1837 //*************************************************************************************************
1849 template< typename MT // Type of the dense matrix
1850  , bool SF // Symmetry flag
1851  , typename... CCAs > // Compile time column arguments
1852 template< typename MT2 // Data type of the foreign dense column selection
1853  , bool SO2 // Storage order of the foreign dense column selection
1854  , bool SF2 // Symmetry flag of the foreign dense column selection
1855  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
1856 inline bool
1857  Columns<MT,true,true,SF,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1858 {
1859  return matrix_.isAliased( &alias->matrix_ );
1860 }
1862 //*************************************************************************************************
1863 
1864 
1865 //*************************************************************************************************
1875 template< typename MT // Type of the dense matrix
1876  , bool SF // Symmetry flag
1877  , typename... CCAs > // Compile time column arguments
1878 inline bool Columns<MT,true,true,SF,CCAs...>::isAligned() const noexcept
1879 {
1880  return matrix_.isAligned();
1881 }
1883 //*************************************************************************************************
1884 
1885 
1886 //*************************************************************************************************
1897 template< typename MT // Type of the dense matrix
1898  , bool SF // Symmetry flag
1899  , typename... CCAs > // Compile time column arguments
1900 inline bool Columns<MT,true,true,SF,CCAs...>::canSMPAssign() const noexcept
1901 {
1902  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
1903 }
1905 //*************************************************************************************************
1906 
1907 
1908 //*************************************************************************************************
1923 template< typename MT // Type of the dense matrix
1924  , bool SF // Symmetry flag
1925  , typename... CCAs > // Compile time column arguments
1926 BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1927  Columns<MT,true,true,SF,CCAs...>::load( size_t i, size_t j ) const noexcept
1928 {
1929  return matrix_.load( i, idx(j) );
1930 }
1932 //*************************************************************************************************
1933 
1934 
1935 //*************************************************************************************************
1950 template< typename MT // Type of the dense matrix
1951  , bool SF // Symmetry flag
1952  , typename... CCAs > // Compile time column arguments
1953 BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1954  Columns<MT,true,true,SF,CCAs...>::loada( size_t i, size_t j ) const noexcept
1955 {
1956  return matrix_.loada( i, idx(j) );
1957 }
1959 //*************************************************************************************************
1960 
1961 
1962 //*************************************************************************************************
1977 template< typename MT // Type of the dense matrix
1978  , bool SF // Symmetry flag
1979  , typename... CCAs > // Compile time column arguments
1980 BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1981  Columns<MT,true,true,SF,CCAs...>::loadu( size_t i, size_t j ) const noexcept
1982 {
1983  return matrix_.loadu( i, idx(j) );
1984 }
1986 //*************************************************************************************************
1987 
1988 
1989 //*************************************************************************************************
2005 template< typename MT // Type of the dense matrix
2006  , bool SF // Symmetry flag
2007  , typename... CCAs > // Compile time column arguments
2009  Columns<MT,true,true,SF,CCAs...>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2010 {
2011  matrix_.store( i, idx(j), value );
2012 }
2014 //*************************************************************************************************
2015 
2016 
2017 //*************************************************************************************************
2033 template< typename MT // Type of the dense matrix
2034  , bool SF // Symmetry flag
2035  , typename... CCAs > // Compile time column arguments
2037  Columns<MT,true,true,SF,CCAs...>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2038 {
2039  matrix_.storea( i, idx(j), value );
2040 }
2042 //*************************************************************************************************
2043 
2044 
2045 //*************************************************************************************************
2061 template< typename MT // Type of the dense matrix
2062  , bool SF // Symmetry flag
2063  , typename... CCAs > // Compile time column arguments
2065  Columns<MT,true,true,SF,CCAs...>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2066 {
2067  matrix_.storeu( i, idx(j), value );
2068 }
2070 //*************************************************************************************************
2071 
2072 
2073 //*************************************************************************************************
2089 template< typename MT // Type of the dense matrix
2090  , bool SF // Symmetry flag
2091  , typename... CCAs > // Compile time column arguments
2093  Columns<MT,true,true,SF,CCAs...>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2094 {
2095  matrix_.stream( i, idx(j), value );
2096 }
2098 //*************************************************************************************************
2099 
2100 
2101 //*************************************************************************************************
2113 template< typename MT // Type of the dense matrix
2114  , bool SF // Symmetry flag
2115  , typename... CCAs > // Compile time column arguments
2116 template< typename MT2 > // Type of the right-hand side dense matrix
2117 inline auto Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2118  -> DisableIf_t< VectorizedAssign_v<MT2> >
2119 {
2122 
2123  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2124  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2125 
2126  const size_t ipos( rows() & size_t(-2) );
2127  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2128 
2129  for( size_t j=0UL; j<columns(); ++j ) {
2130  const size_t index( idx(j) );
2131  for( size_t i=0UL; i<ipos; i+=2UL ) {
2132  matrix_(i ,index) = (~rhs)(i ,j);
2133  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
2134  }
2135  if( ipos < rows() ) {
2136  matrix_(ipos,index) = (~rhs)(ipos,j);
2137  }
2138  }
2139 }
2141 //*************************************************************************************************
2142 
2143 
2144 //*************************************************************************************************
2156 template< typename MT // Type of the dense matrix
2157  , bool SF // Symmetry flag
2158  , typename... CCAs > // Compile time column arguments
2159 template< typename MT2 > // Type of the right-hand side dense matrix
2160 inline auto Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2161  -> EnableIf_t< VectorizedAssign_v<MT2> >
2162 {
2165 
2167 
2168  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2169  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2170 
2171  const size_t ipos( rows() & size_t(-SIMDSIZE) );
2172  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2173 
2174  if( useStreaming &&
2175  rows()*columns() > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2176  !(~rhs).isAliased( &matrix_ ) )
2177  {
2178  for( size_t j=0UL; j<columns(); ++j )
2179  {
2180  size_t i( 0UL );
2181  Iterator left( begin(j) );
2182  ConstIterator_t<MT2> right( (~rhs).begin(j) );
2183 
2184  for( ; i<ipos; i+=SIMDSIZE ) {
2185  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2186  }
2187  for( ; i<rows(); ++i ) {
2188  *left = *right;
2189  }
2190  }
2191  }
2192  else
2193  {
2194  for( size_t j=0UL; j<columns(); ++j )
2195  {
2196  size_t i( 0UL );
2197  Iterator left( begin(j) );
2198  ConstIterator_t<MT2> right( (~rhs).begin(j) );
2199 
2200  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2201  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2202  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2203  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2204  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2205  }
2206  for( ; i<ipos; i+=SIMDSIZE ) {
2207  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2208  }
2209  for( ; i<rows(); ++i ) {
2210  *left = *right; ++left; ++right;
2211  }
2212  }
2213  }
2214 }
2216 //*************************************************************************************************
2217 
2218 
2219 //*************************************************************************************************
2231 template< typename MT // Type of the dense matrix
2232  , bool SF // Symmetry flag
2233  , typename... CCAs > // Compile time column arguments
2234 template< typename MT2 > // Type of the right-hand side dense matrix
2235 inline void Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2236 {
2239 
2241 
2242  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2243  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2244 
2245  constexpr size_t block( BLOCK_SIZE );
2246 
2247  if( rows() < block && columns() < block )
2248  {
2249  const size_t ipos( (~rhs).rows() & size_t(-2) );
2250  for( size_t j=0UL; j<columns(); ++j ) {
2251  const size_t index( idx(j) );
2252  for( size_t i=0UL; i<ipos; i+=2UL ) {
2253  matrix_(i ,index) = (~rhs)(i ,j);
2254  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
2255  }
2256  if( ipos < (~rhs).rows() ) {
2257  matrix_(ipos,index) = (~rhs)(ipos,j);
2258  }
2259  }
2260  }
2261  else
2262  {
2263  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2264  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2265  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2266  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2267  for( size_t j=jj; j<jend; ++j ) {
2268  const size_t index( idx(j) );
2269  for( size_t i=ii; i<iend; ++i ) {
2270  matrix_(i,index) = (~rhs)(i,j);
2271  }
2272  }
2273  }
2274  }
2275  }
2276 }
2278 //*************************************************************************************************
2279 
2280 
2281 //*************************************************************************************************
2293 template< typename MT // Type of the dense matrix
2294  , bool SF // Symmetry flag
2295  , typename... CCAs > // Compile time column arguments
2296 template< typename MT2 > // Type of the right-hand side sparse matrix
2297 inline void Columns<MT,true,true,SF,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2298 {
2301 
2302  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2303  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2304 
2305  for( size_t j=0UL; j<columns(); ++j ) {
2306  const size_t index( idx(j) );
2307  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2308  matrix_(element->index(),index) = element->value();
2309  }
2310 }
2312 //*************************************************************************************************
2313 
2314 
2315 //*************************************************************************************************
2327 template< typename MT // Type of the dense matrix
2328  , bool SF // Symmetry flag
2329  , typename... CCAs > // Compile time column arguments
2330 template< typename MT2 > // Type of the right-hand side sparse matrix
2331 inline void Columns<MT,true,true,SF,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2332 {
2335 
2337 
2338  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2339  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2340 
2341  for( size_t i=0UL; i<rows(); ++i ) {
2342  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2343  matrix_(i,idx(element->index())) = element->value();
2344  }
2345 }
2347 //*************************************************************************************************
2348 
2349 
2350 //*************************************************************************************************
2362 template< typename MT // Type of the dense matrix
2363  , bool SF // Symmetry flag
2364  , typename... CCAs > // Compile time column arguments
2365 template< typename MT2 > // Type of the right-hand side dense matrix
2366 inline auto Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2367  -> DisableIf_t< VectorizedAddAssign_v<MT2> >
2368 {
2371 
2372  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2373  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2374 
2375  const size_t ipos( rows() & size_t(-2) );
2376  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2377 
2378  for( size_t j=0UL; j<columns(); ++j )
2379  {
2380  const size_t index( idx(j) );
2381  if( IsDiagonal_v<MT2> ) {
2382  matrix_(j,index) += (~rhs)(j,j);
2383  }
2384  else {
2385  for( size_t i=0UL; i<ipos; i+=2UL ) {
2386  matrix_(i ,index) += (~rhs)(i ,j);
2387  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
2388  }
2389  if( ipos < rows() ) {
2390  matrix_(ipos,index) += (~rhs)(ipos,j);
2391  }
2392  }
2393  }
2394 }
2396 //*************************************************************************************************
2397 
2398 
2399 //*************************************************************************************************
2411 template< typename MT // Type of the dense matrix
2412  , bool SF // Symmetry flag
2413  , typename... CCAs > // Compile time column arguments
2414 template< typename MT2 > // Type of the right-hand side dense matrix
2415 inline auto Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2416  -> EnableIf_t< VectorizedAddAssign_v<MT2> >
2417 {
2420 
2422 
2423  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2424  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2425 
2426  for( size_t j=0UL; j<columns(); ++j )
2427  {
2428  const size_t ibegin( ( IsLower_v<MT2> )
2429  ?( ( IsStrictlyLower_v<MT2> ? j+1UL : j ) & size_t(-SIMDSIZE) )
2430  :( 0UL ) );
2431  const size_t iend ( ( IsUpper_v<MT2> )
2432  ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
2433  :( rows() ) );
2434  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
2435 
2436  const size_t ipos( iend & size_t(-SIMDSIZE) );
2437  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2438 
2439  size_t i( ibegin );
2440  Iterator left( begin(j) + ibegin );
2441  ConstIterator_t<MT2> right( (~rhs).begin(j) + ibegin );
2442 
2443  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2444  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2445  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2446  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2447  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2448  }
2449  for( ; i<ipos; i+=SIMDSIZE ) {
2450  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2451  }
2452  for( ; i<iend; ++i ) {
2453  *left += *right; ++left; ++right;
2454  }
2455  }
2456 }
2458 //*************************************************************************************************
2459 
2460 
2461 //*************************************************************************************************
2473 template< typename MT // Type of the dense matrix
2474  , bool SF // Symmetry flag
2475  , typename... CCAs > // Compile time column arguments
2476 template< typename MT2 > // Type of the right-hand side dense matrix
2477 inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2478 {
2481 
2483 
2484  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2485  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2486 
2487  constexpr size_t block( BLOCK_SIZE );
2488 
2489  if( rows() < block && columns() < block )
2490  {
2491  const size_t ipos( (~rhs).rows() & size_t(-2) );
2492  for( size_t j=0UL; j<columns(); ++j ) {
2493  const size_t index( idx(j) );
2494  for( size_t i=0UL; i<ipos; i+=2UL ) {
2495  matrix_(i ,index) += (~rhs)(i ,j);
2496  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
2497  }
2498  if( ipos < (~rhs).rows() )
2499  matrix_(ipos,index) += (~rhs)(ipos,j);
2500  }
2501  }
2502  else
2503  {
2504  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2505  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2506  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2507  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2508  for( size_t j=jj; j<jend; ++j ) {
2509  const size_t index( idx(j) );
2510  for( size_t i=ii; i<iend; ++i ) {
2511  matrix_(i,index) += (~rhs)(i,j);
2512  }
2513  }
2514  }
2515  }
2516  }
2517 }
2519 //*************************************************************************************************
2520 
2521 
2522 //*************************************************************************************************
2534 template< typename MT // Type of the dense matrix
2535  , bool SF // Symmetry flag
2536  , typename... CCAs > // Compile time column arguments
2537 template< typename MT2 > // Type of the right-hand side sparse matrix
2538 inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
2539 {
2542 
2543  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2544  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2545 
2546  for( size_t j=0UL; j<columns(); ++j ) {
2547  const size_t index( idx(j) );
2548  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2549  matrix_(element->index(),index) += element->value();
2550  }
2551 }
2553 //*************************************************************************************************
2554 
2555 
2556 //*************************************************************************************************
2568 template< typename MT // Type of the dense matrix
2569  , bool SF // Symmetry flag
2570  , typename... CCAs > // Compile time column arguments
2571 template< typename MT2 > // Type of the right-hand side sparse matrix
2572 inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
2573 {
2576 
2578 
2579  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2580  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2581 
2582  for( size_t i=0UL; i<rows(); ++i ) {
2583  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2584  matrix_(i,idx(element->index())) += element->value();
2585  }
2586 }
2588 //*************************************************************************************************
2589 
2590 
2591 //*************************************************************************************************
2603 template< typename MT // Type of the dense matrix
2604  , bool SF // Symmetry flag
2605  , typename... CCAs > // Compile time column arguments
2606 template< typename MT2 > // Type of the right-hand side dense matrix
2607 inline auto Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2608  -> DisableIf_t< VectorizedSubAssign_v<MT2> >
2609 {
2612 
2613  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2614  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2615 
2616  const size_t ipos( rows() & size_t(-2) );
2617  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2618 
2619  for( size_t j=0UL; j<columns(); ++j )
2620  {
2621  const size_t index( idx(j) );
2622 
2623  if( IsDiagonal_v<MT2> ) {
2624  matrix_(j,index) -= (~rhs)(j,j);
2625  }
2626  else {
2627  for( size_t i=0UL; i<ipos; i+=2UL ) {
2628  matrix_(i ,index) -= (~rhs)(i ,j);
2629  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
2630  }
2631  if( ipos < rows() ) {
2632  matrix_(ipos,index) -= (~rhs)(ipos,j);
2633  }
2634  }
2635  }
2636 }
2638 //*************************************************************************************************
2639 
2640 
2641 //*************************************************************************************************
2653 template< typename MT // Type of the dense matrix
2654  , bool SF // Symmetry flag
2655  , typename... CCAs > // Compile time column arguments
2656 template< typename MT2 > // Type of the right-hand side dense matrix
2657 inline auto Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2658  -> EnableIf_t< VectorizedSubAssign_v<MT2> >
2659 {
2662 
2664 
2665  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2666  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2667 
2668  for( size_t j=0UL; j<columns(); ++j )
2669  {
2670  const size_t ibegin( ( IsLower_v<MT2> )
2671  ?( ( IsStrictlyLower_v<MT2> ? j+1UL : j ) & size_t(-SIMDSIZE) )
2672  :( 0UL ) );
2673  const size_t iend ( ( IsUpper_v<MT2> )
2674  ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
2675  :( rows() ) );
2676  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
2677 
2678  const size_t ipos( iend & size_t(-SIMDSIZE) );
2679  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2680 
2681  size_t i( ibegin );
2682  Iterator left( begin(j) + ibegin );
2683  ConstIterator_t<MT2> right( (~rhs).begin(j) + ibegin );
2684 
2685  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2686  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2687  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2688  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2689  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2690  }
2691  for( ; i<ipos; i+=SIMDSIZE ) {
2692  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2693  }
2694  for( ; i<iend; ++i ) {
2695  *left -= *right; ++left; ++right;
2696  }
2697  }
2698 }
2700 //*************************************************************************************************
2701 
2702 
2703 //*************************************************************************************************
2715 template< typename MT // Type of the dense matrix
2716  , bool SF // Symmetry flag
2717  , typename... CCAs > // Compile time column arguments
2718 template< typename MT2 > // Type of the right-hand side dense matrix
2719 inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2720 {
2723 
2725 
2726  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2727  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2728 
2729  constexpr size_t block( BLOCK_SIZE );
2730 
2731  if( rows() < block && columns() < block )
2732  {
2733  const size_t ipos( (~rhs).rows() & size_t(-2) );
2734  for( size_t j=0UL; j<columns(); ++j ) {
2735  const size_t index( idx(j) );
2736  for( size_t i=0UL; i<ipos; i+=2UL ) {
2737  matrix_(i ,index) -= (~rhs)(i ,j);
2738  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
2739  }
2740  if( ipos < (~rhs).rows() )
2741  matrix_(ipos,index) -= (~rhs)(ipos,j);
2742  }
2743  }
2744  else
2745  {
2746  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2747  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2748  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2749  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2750  for( size_t j=jj; j<jend; ++j ) {
2751  const size_t index( idx(j) );
2752  for( size_t i=ii; i<iend; ++i ) {
2753  matrix_(i,index) -= (~rhs)(i,j);
2754  }
2755  }
2756  }
2757  }
2758  }
2759 }
2761 //*************************************************************************************************
2762 
2763 
2764 //*************************************************************************************************
2776 template< typename MT // Type of the dense matrix
2777  , bool SF // Symmetry flag
2778  , typename... CCAs > // Compile time column arguments
2779 template< typename MT2 > // Type of the right-hand side sparse matrix
2780 inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
2781 {
2784 
2785  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2786  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2787 
2788  for( size_t j=0UL; j<columns(); ++j ) {
2789  const size_t index( idx(j) );
2790  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2791  matrix_(element->index(),index) -= element->value();
2792  }
2793 }
2795 //*************************************************************************************************
2796 
2797 
2798 //*************************************************************************************************
2810 template< typename MT // Type of the dense matrix
2811  , bool SF // Symmetry flag
2812  , typename... CCAs > // Compile time column arguments
2813 template< typename MT2 > // Type of the right-hand side sparse matrix
2814 inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
2815 {
2818 
2820 
2821  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2822  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2823 
2824  for( size_t i=0UL; i<rows(); ++i ) {
2825  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2826  matrix_(i,idx(element->index())) -= element->value();
2827  }
2828 }
2830 //*************************************************************************************************
2831 
2832 
2833 //*************************************************************************************************
2845 template< typename MT // Type of the dense matrix
2846  , bool SF // Symmetry flag
2847  , typename... CCAs > // Compile time column arguments
2848 template< typename MT2 > // Type of the right-hand side dense matrix
2849 inline auto Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2850  -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
2851 {
2854 
2855  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2856  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2857 
2858  const size_t ipos( rows() & size_t(-2) );
2859  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2860 
2861  for( size_t j=0UL; j<columns(); ++j ) {
2862  const size_t index( idx(j) );
2863  for( size_t i=0UL; i<ipos; i+=2UL ) {
2864  matrix_(i ,index) *= (~rhs)(i ,j);
2865  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
2866  }
2867  if( ipos < rows() ) {
2868  matrix_(ipos,index) *= (~rhs)(ipos,j);
2869  }
2870  }
2871 }
2873 //*************************************************************************************************
2874 
2875 
2876 //*************************************************************************************************
2889 template< typename MT // Type of the dense matrix
2890  , bool SF // Symmetry flag
2891  , typename... CCAs > // Compile time column arguments
2892 template< typename MT2 > // Type of the right-hand side dense matrix
2893 inline auto Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2894  -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
2895 {
2898 
2900 
2901  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2902  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2903 
2904  for( size_t j=0UL; j<columns(); ++j )
2905  {
2906  const size_t ipos( rows() & size_t(-SIMDSIZE) );
2907  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2908 
2909  size_t i( 0UL );
2910  Iterator left( begin(j) );
2911  ConstIterator_t<MT2> right( (~rhs).begin(j) );
2912 
2913  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2914  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2915  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2916  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2917  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2918  }
2919  for( ; i<ipos; i+=SIMDSIZE ) {
2920  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2921  }
2922  for( ; i<rows(); ++i ) {
2923  *left *= *right; ++left; ++right;
2924  }
2925  }
2926 }
2928 //*************************************************************************************************
2929 
2930 
2931 //*************************************************************************************************
2943 template< typename MT // Type of the dense matrix
2944  , bool SF // Symmetry flag
2945  , typename... CCAs > // Compile time column arguments
2946 template< typename MT2 > // Type of the right-hand side dense matrix
2947 inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2948 {
2951 
2953 
2954  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2955  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2956 
2957  constexpr size_t block( BLOCK_SIZE );
2958 
2959  if( rows() < block && columns() < block )
2960  {
2961  const size_t ipos( (~rhs).rows() & size_t(-2) );
2962  for( size_t j=0UL; j<columns(); ++j ) {
2963  const size_t index( idx(j) );
2964  for( size_t i=0UL; i<ipos; i+=2UL ) {
2965  matrix_(i ,index) *= (~rhs)(i ,j);
2966  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
2967  }
2968  if( ipos < (~rhs).rows() )
2969  matrix_(ipos,index) *= (~rhs)(ipos,j);
2970  }
2971  }
2972  else
2973  {
2974  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2975  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2976  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2977  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2978  for( size_t j=jj; j<jend; ++j ) {
2979  const size_t index( idx(j) );
2980  for( size_t i=ii; i<iend; ++i ) {
2981  matrix_(i,index) *= (~rhs)(i,j);
2982  }
2983  }
2984  }
2985  }
2986  }
2987 }
2989 //*************************************************************************************************
2990 
2991 
2992 //*************************************************************************************************
3004 template< typename MT // Type of the dense matrix
3005  , bool SF // Symmetry flag
3006  , typename... CCAs > // Compile time column arguments
3007 template< typename MT2 > // Type of the right-hand side sparse matrix
3008 inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
3009 {
3012 
3013  using blaze::reset;
3014 
3015  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3016  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3017 
3018  for( size_t j=0UL; j<columns(); ++j )
3019  {
3020  const size_t index( idx(j) );
3021  size_t i( 0UL );
3022 
3023  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
3024  for( ; i<element->index(); ++i )
3025  reset( matrix_(i,index) );
3026  matrix_(i,index) *= element->value();
3027  ++i;
3028  }
3029 
3030  for( ; i<rows(); ++i ) {
3031  reset( matrix_(i,index) );
3032  }
3033  }
3034 }
3036 //*************************************************************************************************
3037 
3038 
3039 //*************************************************************************************************
3051 template< typename MT // Type of the dense matrix
3052  , bool SF // Symmetry flag
3053  , typename... CCAs > // Compile time column arguments
3054 template< typename MT2 > // Type of the right-hand side sparse matrix
3055 inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
3056 {
3059 
3060  using blaze::reset;
3061 
3063 
3064  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3065  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3066 
3067  for( size_t i=0UL; i<rows(); ++i )
3068  {
3069  size_t j( 0UL );
3070 
3071  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
3072  for( ; j<element->index(); ++j )
3073  reset( matrix_(i,idx(j)) );
3074  matrix_(i,idx(j)) *= element->value();
3075  ++j;
3076  }
3077 
3078  for( ; j<columns(); ++j ) {
3079  reset( matrix_(i,idx(j)) );
3080  }
3081  }
3082 }
3084 //*************************************************************************************************
3085 
3086 
3087 
3088 
3089 
3090 
3091 
3092 
3093 //=================================================================================================
3094 //
3095 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
3096 //
3097 //=================================================================================================
3098 
3099 //*************************************************************************************************
3107 template< typename MT // Type of the dense matrix
3108  , typename... CCAs > // Compile time column arguments
3109 class Columns<MT,false,true,false,CCAs...>
3110  : public View< DenseMatrix< Columns<MT,false,true,false,CCAs...>, true > >
3111  , private ColumnsData<CCAs...>
3112 {
3113  private:
3114  //**Type definitions****************************************************************************
3115  using DataType = ColumnsData<CCAs...>;
3116  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
3117  //**********************************************************************************************
3118 
3119  //**Compile time flags**************************************************************************
3120  static constexpr size_t N = sizeof...( CCAs );
3121  //**********************************************************************************************
3122 
3123  //**********************************************************************************************
3125  template< typename MT1, typename MT2 >
3126  static constexpr bool EnforceEvaluation_v =
3127  ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
3128  //**********************************************************************************************
3129 
3130  public:
3131  //**Type definitions****************************************************************************
3133  using This = Columns<MT,false,true,false,CCAs...>;
3134 
3135  using BaseType = DenseMatrix<This,true>;
3136  using ViewedType = MT;
3137  using ResultType = ColumnsTrait_t<MT,N>;
3138  using OppositeType = OppositeType_t<ResultType>;
3139  using TransposeType = TransposeType_t<ResultType>;
3140  using ElementType = ElementType_t<MT>;
3141  using ReturnType = ReturnType_t<MT>;
3142  using CompositeType = const Columns&;
3143 
3145  using ConstReference = ConstReference_t<MT>;
3146 
3148  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
3149 
3151  using ConstPointer = ConstPointer_t<MT>;
3152 
3154  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
3155  //**********************************************************************************************
3156 
3157  //**ColumnsIterator class definition************************************************************
3160  template< typename MatrixType // Type of the dense matrix
3161  , typename IteratorType > // Type of the dense matrix iterator
3162  class ColumnsIterator
3163  {
3164  public:
3165  //**Type definitions*************************************************************************
3167  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
3168 
3170  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
3171 
3173  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
3174 
3176  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
3177 
3179  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
3180 
3181  // STL iterator requirements
3182  using iterator_category = IteratorCategory;
3183  using value_type = ValueType;
3184  using pointer = PointerType;
3185  using reference = ReferenceType;
3186  using difference_type = DifferenceType;
3187  //*******************************************************************************************
3188 
3189  //**Constructor******************************************************************************
3192  inline ColumnsIterator() noexcept
3193  : matrix_( nullptr ) // The dense matrix containing the column
3194  , row_ ( 0UL ) // The current row index
3195  , column_( 0UL ) // The current column index
3196  , pos_ ( ) // Iterator to the current dense element
3197  {}
3198  //*******************************************************************************************
3199 
3200  //**Constructor******************************************************************************
3207  inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
3208  : matrix_( &matrix ) // The dense matrix containing the selected column
3209  , row_ ( row ) // The current row index
3210  , column_( column ) // The current column index
3211  , pos_ ( ) // Iterator to the current dense element
3212  {
3213  if( row_ != matrix_->rows() )
3214  pos_ = matrix_->begin( row_ ) + column_;
3215  }
3216  //*******************************************************************************************
3217 
3218  //**Constructor******************************************************************************
3223  template< typename MatrixType2, typename IteratorType2 >
3224  inline ColumnsIterator( const ColumnsIterator<MatrixType2,IteratorType2>& it ) noexcept
3225  : matrix_( it.matrix_ ) // The dense matrix containing the seleted column
3226  , row_ ( it.row_ ) // The current row index
3227  , column_( it.column_ ) // The current column index
3228  , pos_ ( it.pos_ ) // Iterator to the current dense element
3229  {}
3230  //*******************************************************************************************
3231 
3232  //**Addition assignment operator*************************************************************
3238  inline ColumnsIterator& operator+=( size_t inc ) noexcept {
3239  using blaze::reset;
3240  row_ += inc;
3241  if( row_ != matrix_->rows() )
3242  pos_ = matrix_->begin( row_ ) + column_;
3243  else reset( pos_ );
3244  return *this;
3245  }
3246  //*******************************************************************************************
3247 
3248  //**Subtraction assignment operator**********************************************************
3254  inline ColumnsIterator& operator-=( size_t dec ) noexcept {
3255  using blaze::reset;
3256  row_ -= dec;
3257  if( row_ != matrix_->rows() )
3258  pos_ = matrix_->begin( row_ ) + column_;
3259  else reset( pos_ );
3260  return *this;
3261  }
3262  //*******************************************************************************************
3263 
3264  //**Prefix increment operator****************************************************************
3269  inline ColumnsIterator& operator++() noexcept {
3270  using blaze::reset;
3271  ++row_;
3272  if( row_ != matrix_->rows() )
3273  pos_ = matrix_->begin( row_ ) + column_;
3274  else reset( pos_ );
3275  return *this;
3276  }
3277  //*******************************************************************************************
3278 
3279  //**Postfix increment operator***************************************************************
3284  inline const ColumnsIterator operator++( int ) noexcept {
3285  const ColumnsIterator tmp( *this );
3286  ++(*this);
3287  return tmp;
3288  }
3289  //*******************************************************************************************
3290 
3291  //**Prefix decrement operator****************************************************************
3296  inline ColumnsIterator& operator--() noexcept {
3297  using blaze::reset;
3298  --row_;
3299  if( row_ != matrix_->rows() )
3300  pos_ = matrix_->begin( row_ ) + column_;
3301  else reset( pos_ );
3302  return *this;
3303  }
3304  //*******************************************************************************************
3305 
3306  //**Postfix decrement operator***************************************************************
3311  inline const ColumnsIterator operator--( int ) noexcept {
3312  const ColumnsIterator tmp( *this );
3313  --(*this);
3314  return tmp;
3315  }
3316  //*******************************************************************************************
3317 
3318  //**Subscript operator***********************************************************************
3324  inline ReferenceType operator[]( size_t index ) const {
3325  BLAZE_USER_ASSERT( row_+index < matrix_->rows(), "Invalid access index detected" );
3326  const IteratorType pos( matrix_->begin( row_+index ) + column_ );
3327  return *pos;
3328  }
3329  //*******************************************************************************************
3330 
3331  //**Element access operator******************************************************************
3336  inline ReferenceType operator*() const {
3337  return *pos_;
3338  }
3339  //*******************************************************************************************
3340 
3341  //**Element access operator******************************************************************
3346  inline PointerType operator->() const {
3347  return pos_;
3348  }
3349  //*******************************************************************************************
3350 
3351  //**Equality operator************************************************************************
3357  template< typename MatrixType2, typename IteratorType2 >
3358  inline bool operator==( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3359  return row_ == rhs.row_;
3360  }
3361  //*******************************************************************************************
3362 
3363  //**Inequality operator**********************************************************************
3369  template< typename MatrixType2, typename IteratorType2 >
3370  inline bool operator!=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3371  return !( *this == rhs );
3372  }
3373  //*******************************************************************************************
3374 
3375  //**Less-than operator***********************************************************************
3381  template< typename MatrixType2, typename IteratorType2 >
3382  inline bool operator<( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3383  return row_ < rhs.row_;
3384  }
3385  //*******************************************************************************************
3386 
3387  //**Greater-than operator********************************************************************
3393  template< typename MatrixType2, typename IteratorType2 >
3394  inline bool operator>( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3395  return row_ > rhs.row_;
3396  }
3397  //*******************************************************************************************
3398 
3399  //**Less-or-equal-than operator**************************************************************
3405  template< typename MatrixType2, typename IteratorType2 >
3406  inline bool operator<=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3407  return row_ <= rhs.row_;
3408  }
3409  //*******************************************************************************************
3410 
3411  //**Greater-or-equal-than operator***********************************************************
3417  template< typename MatrixType2, typename IteratorType2 >
3418  inline bool operator>=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3419  return row_ >= rhs.row_;
3420  }
3421  //*******************************************************************************************
3422 
3423  //**Subtraction operator*********************************************************************
3429  inline DifferenceType operator-( const ColumnsIterator& rhs ) const noexcept {
3430  return row_ - rhs.row_;
3431  }
3432  //*******************************************************************************************
3433 
3434  //**Addition operator************************************************************************
3441  friend inline const ColumnsIterator operator+( const ColumnsIterator& it, size_t inc ) noexcept {
3442  return ColumnsIterator( *it.matrix_, it.row_+inc, it.column_ );
3443  }
3444  //*******************************************************************************************
3445 
3446  //**Addition operator************************************************************************
3453  friend inline const ColumnsIterator operator+( size_t inc, const ColumnsIterator& it ) noexcept {
3454  return ColumnsIterator( *it.matrix_, it.row_+inc, it.column_ );
3455  }
3456  //*******************************************************************************************
3457 
3458  //**Subtraction operator*********************************************************************
3465  friend inline const ColumnsIterator operator-( const ColumnsIterator& it, size_t dec ) noexcept {
3466  return ColumnsIterator( *it.matrix_, it.row_-dec, it.column_ );
3467  }
3468  //*******************************************************************************************
3469 
3470  private:
3471  //**Member variables*************************************************************************
3472  MatrixType* matrix_;
3473  size_t row_;
3474  size_t column_;
3475  IteratorType pos_;
3476  //*******************************************************************************************
3477 
3478  //**Friend declarations**********************************************************************
3479  template< typename MatrixType2, typename IteratorType2 > friend class ColumnsIterator;
3480  //*******************************************************************************************
3481  };
3482  //**********************************************************************************************
3483 
3484  //**Type definitions****************************************************************************
3486  using ConstIterator = ColumnsIterator< const MT, ConstIterator_t<MT> >;
3487 
3489  using Iterator = If_t< IsConst_v<MT>, ConstIterator, ColumnsIterator< MT, Iterator_t<MT> > >;
3490  //**********************************************************************************************
3491 
3492  //**Compilation flags***************************************************************************
3494  static constexpr bool simdEnabled = false;
3495 
3497  static constexpr bool smpAssignable = MT::smpAssignable;
3498  //**********************************************************************************************
3499 
3500  //**Constructors********************************************************************************
3503  template< typename... RCAs >
3504  explicit inline Columns( MT& matrix, RCAs... args );
3505 
3506  Columns( const Columns& ) = default;
3507  Columns( Columns&& ) = default;
3509  //**********************************************************************************************
3510 
3511  //**Destructor**********************************************************************************
3514  ~Columns() = default;
3516  //**********************************************************************************************
3517 
3518  //**Data access functions***********************************************************************
3521  inline Reference operator()( size_t i, size_t j );
3522  inline ConstReference operator()( size_t i, size_t j ) const;
3523  inline Reference at( size_t i, size_t j );
3524  inline ConstReference at( size_t i, size_t j ) const;
3525  inline Pointer data () noexcept;
3526  inline ConstPointer data () const noexcept;
3527  inline Pointer data ( size_t j ) noexcept;
3528  inline ConstPointer data ( size_t j ) const noexcept;
3529  inline Iterator begin ( size_t j );
3530  inline ConstIterator begin ( size_t j ) const;
3531  inline ConstIterator cbegin( size_t j ) const;
3532  inline Iterator end ( size_t j );
3533  inline ConstIterator end ( size_t j ) const;
3534  inline ConstIterator cend ( size_t j ) const;
3536  //**********************************************************************************************
3537 
3538  //**Assignment operators************************************************************************
3541  inline Columns& operator=( const ElementType& rhs );
3542  inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
3543  inline Columns& operator=( const Columns& rhs );
3544 
3545  template< typename MT2, bool SO2 >
3546  inline Columns& operator=( const Matrix<MT2,SO2>& rhs );
3547 
3548  template< typename MT2, bool SO2 >
3549  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3550  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3551 
3552  template< typename MT2, bool SO2 >
3553  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3554  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3555 
3556  template< typename MT2, bool SO2 >
3557  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3558  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3559 
3560  template< typename MT2, bool SO2 >
3561  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3562  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3563 
3564  template< typename MT2, bool SO2 >
3565  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3566  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3567 
3568  template< typename MT2, bool SO2 >
3569  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3570  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3572  //**********************************************************************************************
3573 
3574  //**Utility functions***************************************************************************
3577  using DataType::idx;
3578  using DataType::idces;
3579  using DataType::columns;
3580 
3581  inline MT& operand() noexcept;
3582  inline const MT& operand() const noexcept;
3583 
3584  inline size_t rows() const noexcept;
3585  inline size_t spacing() const noexcept;
3586  inline size_t capacity() const noexcept;
3587  inline size_t capacity( size_t j ) const noexcept;
3588  inline size_t nonZeros() const;
3589  inline size_t nonZeros( size_t j ) const;
3590  inline void reset();
3591  inline void reset( size_t j );
3593  //**********************************************************************************************
3594 
3595  //**Numeric functions***************************************************************************
3598  inline Columns& transpose();
3599  inline Columns& ctranspose();
3600 
3601  template< typename Other > inline Columns& scale( const Other& scalar );
3603  //**********************************************************************************************
3604 
3605  //**Expression template evaluation functions****************************************************
3608  template< typename Other >
3609  inline bool canAlias( const Other* alias ) const noexcept;
3610 
3611  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
3612  inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
3613 
3614  template< typename Other >
3615  inline bool isAliased( const Other* alias ) const noexcept;
3616 
3617  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
3618  inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
3619 
3620  inline bool isAligned () const noexcept;
3621  inline bool canSMPAssign() const noexcept;
3622 
3623  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
3624  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3625  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3626  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3627 
3628  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
3629  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3630  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3631  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3632 
3633  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
3634  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3635  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3636  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3637 
3638  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
3639  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
3640  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
3641  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
3643  //**********************************************************************************************
3644 
3645  private:
3646  //**Member variables****************************************************************************
3649  Operand matrix_;
3650 
3651  //**********************************************************************************************
3652 
3653  //**Friend declarations*************************************************************************
3654  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
3655  //**********************************************************************************************
3656 
3657  //**Compile time checks*************************************************************************
3667  //**********************************************************************************************
3668 };
3670 //*************************************************************************************************
3671 
3672 
3673 
3674 
3675 //=================================================================================================
3676 //
3677 // CONSTRUCTORS
3678 //
3679 //=================================================================================================
3680 
3681 //*************************************************************************************************
3694 template< typename MT // Type of the dense matrix
3695  , typename... CCAs > // Compile time column arguments
3696 template< typename... RCAs > // Runtime column arguments
3697 inline Columns<MT,false,true,false,CCAs...>::Columns( MT& matrix, RCAs... args )
3698  : DataType( args... ) // Base class initialization
3699  , matrix_ ( matrix ) // The matrix containing the columns
3700 {
3701  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
3702  for( size_t j=0UL; j<columns(); ++j ) {
3703  if( matrix_.columns() <= idx(j) ) {
3704  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3705  }
3706  }
3707  }
3708 }
3710 //*************************************************************************************************
3711 
3712 
3713 
3714 
3715 //=================================================================================================
3716 //
3717 // DATA ACCESS FUNCTIONS
3718 //
3719 //=================================================================================================
3720 
3721 //*************************************************************************************************
3732 template< typename MT // Type of the dense matrix
3733  , typename... CCAs > // Compile time column arguments
3734 inline typename Columns<MT,false,true,false,CCAs...>::Reference
3735  Columns<MT,false,true,false,CCAs...>::operator()( size_t i, size_t j )
3736 {
3737  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3738  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3739 
3740  return matrix_(i,idx(j));
3741 }
3743 //*************************************************************************************************
3744 
3745 
3746 //*************************************************************************************************
3757 template< typename MT // Type of the dense matrix
3758  , typename... CCAs > // Compile time column arguments
3759 inline typename Columns<MT,false,true,false,CCAs...>::ConstReference
3760  Columns<MT,false,true,false,CCAs...>::operator()( size_t i, size_t j ) const
3761 {
3762  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3763  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3764 
3765  return const_cast<const MT&>( matrix_ )(i,idx(j));
3766 }
3768 //*************************************************************************************************
3769 
3770 
3771 //*************************************************************************************************
3783 template< typename MT // Type of the dense matrix
3784  , typename... CCAs > // Compile time column arguments
3785 inline typename Columns<MT,false,true,false,CCAs...>::Reference
3786  Columns<MT,false,true,false,CCAs...>::at( size_t i, size_t j )
3787 {
3788  if( i >= rows() ) {
3789  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3790  }
3791  if( j >= columns() ) {
3792  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3793  }
3794  return (*this)(i,j);
3795 }
3797 //*************************************************************************************************
3798 
3799 
3800 //*************************************************************************************************
3812 template< typename MT // Type of the dense matrix
3813  , typename... CCAs > // Compile time column arguments
3814 inline typename Columns<MT,false,true,false,CCAs...>::ConstReference
3815  Columns<MT,false,true,false,CCAs...>::at( size_t i, size_t j ) const
3816 {
3817  if( i >= rows() ) {
3818  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3819  }
3820  if( j >= columns() ) {
3821  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3822  }
3823  return (*this)(i,j);
3824 }
3826 //*************************************************************************************************
3827 
3828 
3829 //*************************************************************************************************
3839 template< typename MT // Type of the dense matrix
3840  , typename... CCAs > // Compile time column arguments
3841 inline typename Columns<MT,false,true,false,CCAs...>::Pointer
3843 {
3844  return matrix_.data() + idx(0UL);
3845 }
3847 //*************************************************************************************************
3848 
3849 
3850 //*************************************************************************************************
3860 template< typename MT // Type of the dense matrix
3861  , typename... CCAs > // Compile time column arguments
3862 inline typename Columns<MT,false,true,false,CCAs...>::ConstPointer
3864 {
3865  return matrix_.data() + idx(0UL);
3866 }
3868 //*************************************************************************************************
3869 
3870 
3871 //*************************************************************************************************
3880 template< typename MT // Type of the dense matrix
3881  , typename... CCAs > // Compile time column arguments
3882 inline typename Columns<MT,false,true,false,CCAs...>::Pointer
3883  Columns<MT,false,true,false,CCAs...>::data( size_t j ) noexcept
3884 {
3885  return matrix_.data() + idx(j);
3886 }
3888 //*************************************************************************************************
3889 
3890 
3891 //*************************************************************************************************
3900 template< typename MT // Type of the dense matrix
3901  , typename... CCAs > // Compile time column arguments
3902 inline typename Columns<MT,false,true,false,CCAs...>::ConstPointer
3903  Columns<MT,false,true,false,CCAs...>::data( size_t j ) const noexcept
3904 {
3905  return matrix_.data() + idx(j);
3906 }
3908 //*************************************************************************************************
3909 
3910 
3911 //*************************************************************************************************
3920 template< typename MT // Type of the dense matrix
3921  , typename... CCAs > // Compile time column arguments
3922 inline typename Columns<MT,false,true,false,CCAs...>::Iterator
3924 {
3925  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3926  return Iterator( matrix_, 0UL, idx(j) );
3927 }
3929 //*************************************************************************************************
3930 
3931 
3932 //*************************************************************************************************
3941 template< typename MT // Type of the dense matrix
3942  , typename... CCAs > // Compile time column arguments
3943 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
3945 {
3946  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3947  return ConstIterator( matrix_, 0UL, idx(j) );
3948 }
3950 //*************************************************************************************************
3951 
3952 
3953 //*************************************************************************************************
3962 template< typename MT // Type of the dense matrix
3963  , typename... CCAs > // Compile time column arguments
3964 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
3966 {
3967  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3968  return ConstIterator( matrix_, 0UL, idx(j) );
3969 }
3971 //*************************************************************************************************
3972 
3973 
3974 //*************************************************************************************************
3983 template< typename MT // Type of the dense matrix
3984  , typename... CCAs > // Compile time column arguments
3985 inline typename Columns<MT,false,true,false,CCAs...>::Iterator
3987 {
3988  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3989  return Iterator( matrix_, rows(), idx(j) );
3990 }
3992 //*************************************************************************************************
3993 
3994 
3995 //*************************************************************************************************
4004 template< typename MT // Type of the dense matrix
4005  , typename... CCAs > // Compile time column arguments
4006 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
4008 {
4009  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4010  return ConstIterator( matrix_, rows(), idx(j) );
4011 }
4013 //*************************************************************************************************
4014 
4015 
4016 //*************************************************************************************************
4025 template< typename MT // Type of the dense matrix
4026  , typename... CCAs > // Compile time column arguments
4027 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
4029 {
4030  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4031  return ConstIterator( matrix_, rows(), idx(j) );
4032 }
4034 //*************************************************************************************************
4035 
4036 
4037 
4038 
4039 //=================================================================================================
4040 //
4041 // ASSIGNMENT OPERATORS
4042 //
4043 //=================================================================================================
4044 
4045 //*************************************************************************************************
4056 template< typename MT // Type of the dense matrix
4057  , typename... CCAs > // Compile time column arguments
4058 inline Columns<MT,false,true,false,CCAs...>&
4059  Columns<MT,false,true,false,CCAs...>::operator=( const ElementType& rhs )
4060 {
4061  for( size_t j=0UL; j<columns(); ++j ) {
4062  column( matrix_, idx(j), unchecked ) = rhs;
4063  }
4064 
4065  return *this;
4066 }
4068 //*************************************************************************************************
4069 
4070 
4071 //*************************************************************************************************
4087 template< typename MT // Type of the dense matrix
4088  , typename... CCAs > // Compile time column arguments
4089 inline Columns<MT,false,true,false,CCAs...>&
4090  Columns<MT,false,true,false,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
4091 {
4094 
4095  if( list.size() != rows() ) {
4096  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
4097  }
4098 
4099  if( IsRestricted_v<MT> ) {
4100  const InitializerMatrix<ElementType> tmp( list, columns() );
4101  for( size_t j=0UL; j<columns(); ++j ) {
4102  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4103  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4104  }
4105  }
4106  }
4107 
4108  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4109  size_t i( 0UL );
4110 
4111  for( const auto& rowList : list ) {
4112  size_t j( 0UL );
4113  for( const auto& element : rowList ) {
4114  matrix_(i,idx(j)) = element;
4115  ++j;
4116  }
4117  for( ; j<columns(); ++j ) {
4118  matrix_(i,idx(j)) = ElementType();
4119  }
4120  ++i;
4121  }
4122 
4123  return *this;
4124 }
4126 //*************************************************************************************************
4127 
4128 
4129 //*************************************************************************************************
4144 template< typename MT // Type of the dense matrix
4145  , typename... CCAs > // Compile time column arguments
4146 inline Columns<MT,false,true,false,CCAs...>&
4147  Columns<MT,false,true,false,CCAs...>::operator=( const Columns& rhs )
4148 {
4151 
4154 
4155  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
4156  return *this;
4157 
4158  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
4159  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4160  }
4161 
4162  if( IsRestricted_v<MT> ) {
4163  for( size_t j=0UL; j<columns(); ++j ) {
4164  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( rhs, j, unchecked ), 0UL ) ) {
4165  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4166  }
4167  }
4168  }
4169 
4170  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4171 
4172  if( rhs.canAlias( &matrix_ ) ) {
4173  const ResultType tmp( rhs );
4174  smpAssign( left, tmp );
4175  }
4176  else {
4177  smpAssign( left, rhs );
4178  }
4179 
4180  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4181 
4182  return *this;
4183 }
4185 //*************************************************************************************************
4186 
4187 
4188 //*************************************************************************************************
4203 template< typename MT // Type of the dense matrix
4204  , typename... CCAs > // Compile time column arguments
4205 template< typename MT2 // Type of the right-hand side matrix
4206  , bool SO2 > // Storage order of the right-hand side matrix
4207 inline Columns<MT,false,true,false,CCAs...>&
4208  Columns<MT,false,true,false,CCAs...>::operator=( const Matrix<MT2,SO2>& rhs )
4209 {
4212 
4213  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4214 
4215  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4216  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4217  }
4218 
4219  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
4220  Right right( ~rhs );
4221 
4222  if( IsRestricted_v<MT> ) {
4223  for( size_t j=0UL; j<columns(); ++j ) {
4224  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( right, j, unchecked ), 0UL ) ) {
4225  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4226  }
4227  }
4228  }
4229 
4230  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4231 
4232  if( IsSparseMatrix_v<MT2> ) {
4233  reset();
4234  }
4235 
4236  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
4237  const ResultType_t<MT2> tmp( right );
4238  smpAssign( left, tmp );
4239  }
4240  else {
4241  smpAssign( left, right );
4242  }
4243 
4244  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4245 
4246  return *this;
4247 }
4249 //*************************************************************************************************
4250 
4251 
4252 //*************************************************************************************************
4266 template< typename MT // Type of the dense matrix
4267  , typename... CCAs > // Compile time column arguments
4268 template< typename MT2 // Type of the right-hand side matrix
4269  , bool SO2 > // Storage order of the right-hand side matrix
4270 inline auto Columns<MT,false,true,false,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4271  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4272 {
4275 
4278  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4279 
4280  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4281 
4284 
4285  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4286  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4287  }
4288 
4289  if( IsRestricted_v<MT> ) {
4290  for( size_t j=0UL; j<columns(); ++j ) {
4291  if( !tryAddAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
4292  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4293  }
4294  }
4295  }
4296 
4297  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4298 
4299  if( (~rhs).canAlias( &matrix_ ) ) {
4300  const AddType tmp( *this + (~rhs) );
4301  smpAssign( left, tmp );
4302  }
4303  else {
4304  smpAddAssign( left, ~rhs );
4305  }
4306 
4307  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4308 
4309  return *this;
4310 }
4312 //*************************************************************************************************
4313 
4314 
4315 //*************************************************************************************************
4329 template< typename MT // Type of the dense matrix
4330  , typename... CCAs > // Compile time column arguments
4331 template< typename MT2 // Type of the right-hand side matrix
4332  , bool SO2 > // Storage order of the right-hand side matrix
4333 inline auto Columns<MT,false,true,false,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4334  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4335 {
4338 
4341  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4342 
4343  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4344 
4347 
4348  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4349  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4350  }
4351 
4352  const AddType tmp( *this + (~rhs) );
4353 
4354  if( IsRestricted_v<MT> ) {
4355  for( size_t j=0UL; j<columns(); ++j ) {
4356  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4357  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4358  }
4359  }
4360  }
4361 
4362  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4363 
4364  smpAssign( left, tmp );
4365 
4366  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4367 
4368  return *this;
4369 }
4371 //*************************************************************************************************
4372 
4373 
4374 //*************************************************************************************************
4388 template< typename MT // Type of the dense matrix
4389  , typename... CCAs > // Compile time column arguments
4390 template< typename MT2 // Type of the right-hand side matrix
4391  , bool SO2 > // Storage order of the right-hand side matrix
4392 inline auto Columns<MT,false,true,false,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4393  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4394 {
4397 
4400  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4401 
4402  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4403 
4406 
4407  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4408  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4409  }
4410 
4411  if( IsRestricted_v<MT> ) {
4412  for( size_t j=0UL; j<columns(); ++j ) {
4413  if( !trySubAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
4414  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4415  }
4416  }
4417  }
4418 
4419  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4420 
4421  if( (~rhs).canAlias( &matrix_ ) ) {
4422  const SubType tmp( *this - (~rhs ) );
4423  smpAssign( left, tmp );
4424  }
4425  else {
4426  smpSubAssign( left, ~rhs );
4427  }
4428 
4429  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4430 
4431  return *this;
4432 }
4434 //*************************************************************************************************
4435 
4436 
4437 //*************************************************************************************************
4451 template< typename MT // Type of the dense matrix
4452  , typename... CCAs > // Compile time column arguments
4453 template< typename MT2 // Type of the right-hand side matrix
4454  , bool SO2 > // Storage order of the right-hand side matrix
4455 inline auto Columns<MT,false,true,false,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4456  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4457 {
4460 
4463  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4464 
4465  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4466 
4469 
4470  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4471  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4472  }
4473 
4474  const SubType tmp( *this - (~rhs) );
4475 
4476  if( IsRestricted_v<MT> ) {
4477  for( size_t j=0UL; j<columns(); ++j ) {
4478  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4479  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4480  }
4481  }
4482  }
4483 
4484  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4485 
4486  smpAssign( left, tmp );
4487 
4488  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4489 
4490  return *this;
4491 }
4493 //*************************************************************************************************
4494 
4495 
4496 //*************************************************************************************************
4510 template< typename MT // Type of the dense matrix
4511  , typename... CCAs > // Compile time column arguments
4512 template< typename MT2 // Type of the right-hand side matrix
4513  , bool SO2 > // Storage order of the right-hand side matrix
4514 inline auto Columns<MT,false,true,false,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4515  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4516 {
4519 
4522  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4523 
4524  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4525 
4527 
4528  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4529  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4530  }
4531 
4532  if( IsRestricted_v<MT> ) {
4533  for( size_t j=0UL; j<columns(); ++j ) {
4534  if( !tryMultAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
4535  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4536  }
4537  }
4538  }
4539 
4540  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4541 
4542  if( (~rhs).canAlias( &matrix_ ) ) {
4543  const SchurType tmp( *this % (~rhs) );
4544  if( IsSparseMatrix_v<SchurType> )
4545  reset();
4546  smpAssign( left, tmp );
4547  }
4548  else {
4549  smpSchurAssign( left, ~rhs );
4550  }
4551 
4552  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4553 
4554  return *this;
4555 }
4557 //*************************************************************************************************
4558 
4559 
4560 //*************************************************************************************************
4574 template< typename MT // Type of the dense matrix
4575  , typename... CCAs > // Compile time column arguments
4576 template< typename MT2 // Type of the right-hand side matrix
4577  , bool SO2 > // Storage order of the right-hand side matrix
4578 inline auto Columns<MT,false,true,false,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4579  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4580 {
4583 
4586  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4587 
4588  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4589 
4591 
4592  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4593  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4594  }
4595 
4596  const SchurType tmp( *this % (~rhs) );
4597 
4598  if( IsRestricted_v<MT> ) {
4599  for( size_t j=0UL; j<columns(); ++j ) {
4600  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4601  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4602  }
4603  }
4604  }
4605 
4606  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4607 
4608  if( IsSparseMatrix_v<SchurType> ) {
4609  reset();
4610  }
4611 
4612  smpAssign( left, tmp );
4613 
4614  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4615 
4616  return *this;
4617 }
4619 //*************************************************************************************************
4620 
4621 
4622 
4623 
4624 //=================================================================================================
4625 //
4626 // UTILITY FUNCTIONS
4627 //
4628 //=================================================================================================
4629 
4630 //*************************************************************************************************
4636 template< typename MT // Type of the dense matrix
4637  , typename... CCAs > // Compile time column arguments
4638 inline MT& Columns<MT,false,true,false,CCAs...>::operand() noexcept
4639 {
4640  return matrix_;
4641 }
4643 //*************************************************************************************************
4644 
4645 
4646 //*************************************************************************************************
4652 template< typename MT // Type of the dense matrix
4653  , typename... CCAs > // Compile time column arguments
4654 inline const MT& Columns<MT,false,true,false,CCAs...>::operand() const noexcept
4655 {
4656  return matrix_;
4657 }
4659 //*************************************************************************************************
4660 
4661 
4662 //*************************************************************************************************
4668 template< typename MT // Type of the dense matrix
4669  , typename... CCAs > // Compile time column arguments
4670 inline size_t Columns<MT,false,true,false,CCAs...>::rows() const noexcept
4671 {
4672  return matrix_.rows();
4673 }
4675 //*************************************************************************************************
4676 
4677 
4678 //*************************************************************************************************
4687 template< typename MT // Type of the dense matrix
4688  , typename... CCAs > // Compile time column arguments
4689 inline size_t Columns<MT,false,true,false,CCAs...>::spacing() const noexcept
4690 {
4691  return matrix_.rows();
4692 }
4694 //*************************************************************************************************
4695 
4696 
4697 //*************************************************************************************************
4703 template< typename MT // Type of the dense matrix
4704  , typename... CCAs > // Compile time column arguments
4705 inline size_t Columns<MT,false,true,false,CCAs...>::capacity() const noexcept
4706 {
4707  return rows() * columns();
4708 }
4710 //*************************************************************************************************
4711 
4712 
4713 //*************************************************************************************************
4722 template< typename MT // Type of the dense matrix
4723  , typename... CCAs > // Compile time column arguments
4724 inline size_t Columns<MT,false,true,false,CCAs...>::capacity( size_t j ) const noexcept
4725 {
4726  UNUSED_PARAMETER( j );
4727 
4728  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4729 
4730  return rows();
4731 }
4733 //*************************************************************************************************
4734 
4735 
4736 //*************************************************************************************************
4742 template< typename MT // Type of the dense matrix
4743  , typename... CCAs > // Compile time column arguments
4745 {
4746  size_t nonzeros( 0UL );
4747 
4748  for( size_t j=0UL; j<columns(); ++j ) {
4749  nonzeros += nonZeros( j );
4750  }
4751 
4752  return nonzeros;
4753 }
4755 //*************************************************************************************************
4756 
4757 
4758 //*************************************************************************************************
4767 template< typename MT // Type of the dense matrix
4768  , typename... CCAs > // Compile time column arguments
4769 inline size_t Columns<MT,false,true,false,CCAs...>::nonZeros( size_t j ) const
4770 {
4771  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4772 
4773  size_t nonzeros( 0UL );
4774 
4775  const size_t index( idx(j) );
4776  for( size_t i=0UL; i<rows(); ++i ) {
4777  if( !isDefault( matrix_( i, index ) ) )
4778  ++nonzeros;
4779  }
4780 
4781  return nonzeros;
4782 }
4784 //*************************************************************************************************
4785 
4786 
4787 //*************************************************************************************************
4793 template< typename MT // Type of the dense matrix
4794  , typename... CCAs > // Compile time column arguments
4796 {
4797  for( size_t j=0UL; j<columns(); ++j ) {
4798  reset( j );
4799  }
4800 }
4802 //*************************************************************************************************
4803 
4804 
4805 //*************************************************************************************************
4814 template< typename MT // Type of the dense matrix
4815  , typename... CCAs > // Compile time column arguments
4816 inline void Columns<MT,false,true,false,CCAs...>::reset( size_t j )
4817 {
4818  using blaze::reset;
4819 
4820  const size_t index( idx(j) );
4821  for( size_t i=0UL; i<rows(); ++i ) {
4822  reset( matrix_( i, index ) );
4823  }
4824 }
4826 //*************************************************************************************************
4827 
4828 
4829 
4830 
4831 //=================================================================================================
4832 //
4833 // NUMERIC FUNCTIONS
4834 //
4835 //=================================================================================================
4836 
4837 //*************************************************************************************************
4850 template< typename MT // Type of the dense matrix
4851  , typename... CCAs > // Compile time column arguments
4852 inline Columns<MT,false,true,false,CCAs...>&
4854 {
4857 
4858  if( rows() != columns() ) {
4859  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4860  }
4861 
4862  const ResultType tmp( trans( *this ) );
4863 
4864  if( IsRestricted_v<MT> ) {
4865  for( size_t j=0UL; j<columns(); ++j ) {
4866  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4867  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4868  }
4869  }
4870  }
4871 
4872  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4873 
4874  smpAssign( left, tmp );
4875 
4876  return *this;
4877 }
4879 //*************************************************************************************************
4880 
4881 
4882 //*************************************************************************************************
4895 template< typename MT // Type of the dense matrix
4896  , typename... CCAs > // Compile time column arguments
4897 inline Columns<MT,false,true,false,CCAs...>&
4899 {
4902 
4903  if( rows() != columns() ) {
4904  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4905  }
4906 
4907  const ResultType tmp( ctrans( *this ) );
4908 
4909  if( IsRestricted_v<MT> ) {
4910  for( size_t j=0UL; j<columns(); ++j ) {
4911  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4912  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4913  }
4914  }
4915  }
4916 
4917  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4918 
4919  smpAssign( left, tmp );
4920 
4921  return *this;
4922 }
4924 //*************************************************************************************************
4925 
4926 
4927 //*************************************************************************************************
4940 template< typename MT // Type of the dense matrix
4941  , typename... CCAs > // Compile time column arguments
4942 template< typename Other > // Data type of the scalar value
4943 inline Columns<MT,false,true,false,CCAs...>&
4944  Columns<MT,false,true,false,CCAs...>::scale( const Other& scalar )
4945 {
4949 
4950  for( size_t j=0UL; j<columns(); ++j )
4951  {
4952  const size_t index ( idx(j) );
4953  const size_t ibegin( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index+1UL : index ) : 0UL );
4954  const size_t iend ( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index : index+1UL ) : rows() );
4955 
4956  for( size_t i=ibegin; i<iend; ++i ) {
4957  matrix_(i,index) *= scalar;
4958  }
4959  }
4960 
4961  return *this;
4962 }
4964 //*************************************************************************************************
4965 
4966 
4967 
4968 
4969 //=================================================================================================
4970 //
4971 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4972 //
4973 //=================================================================================================
4974 
4975 //*************************************************************************************************
4986 template< typename MT // Type of the dense matrix
4987  , typename... CCAs > // Compile time column arguments
4988 template< typename Other > // Data type of the foreign expression
4989 inline bool Columns<MT,false,true,false,CCAs...>::canAlias( const Other* alias ) const noexcept
4990 {
4991  return matrix_.isAliased( alias );
4992 }
4994 //*************************************************************************************************
4995 
4996 
4997 //*************************************************************************************************
5009 template< typename MT // Type of the dense matrix
5010  , typename... CCAs > // Compile time column arguments
5011 template< typename MT2 // Data type of the foreign dense column selection
5012  , bool SO2 // Storage order of the foreign dense column selection
5013  , bool SF2 // Symmetry flag of the foreign dense column selection
5014  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
5015 inline bool
5016  Columns<MT,false,true,false,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5017 {
5018  return matrix_.isAliased( &alias->matrix_ );
5019 }
5021 //*************************************************************************************************
5022 
5023 
5024 //*************************************************************************************************
5035 template< typename MT // Type of the dense matrix
5036  , typename... CCAs > // Compile time column arguments
5037 template< typename Other > // Data type of the foreign expression
5038 inline bool Columns<MT,false,true,false,CCAs...>::isAliased( const Other* alias ) const noexcept
5039 {
5040  return matrix_.isAliased( alias );
5041 }
5043 //*************************************************************************************************
5044 
5045 
5046 //*************************************************************************************************
5058 template< typename MT // Type of the dense matrix
5059  , typename... CCAs > // Compile time column arguments
5060 template< typename MT2 // Data type of the foreign dense column selection
5061  , bool SO2 // Storage order of the foreign dense column selection
5062  , bool SF2 // Symmetry flag of the foreign dense column selection
5063  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
5064 inline bool
5065  Columns<MT,false,true,false,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5066 {
5067  return matrix_.isAliased( &alias->matrix_ );
5068 }
5070 //*************************************************************************************************
5071 
5072 
5073 //*************************************************************************************************
5083 template< typename MT // Type of the dense matrix
5084  , typename... CCAs > // Compile time column arguments
5085 inline bool Columns<MT,false,true,false,CCAs...>::isAligned() const noexcept
5086 {
5087  return false;
5088 }
5090 //*************************************************************************************************
5091 
5092 
5093 //*************************************************************************************************
5104 template< typename MT // Type of the dense matrix
5105  , typename... CCAs > // Compile time column arguments
5106 inline bool Columns<MT,false,true,false,CCAs...>::canSMPAssign() const noexcept
5107 {
5108  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
5109 }
5111 //*************************************************************************************************
5112 
5113 
5114 //*************************************************************************************************
5126 template< typename MT // Type of the dense matrix
5127  , typename... CCAs > // Compile time column arguments
5128 template< typename MT2 > // Type of the right-hand side dense matrix
5129 inline void Columns<MT,false,true,false,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
5130 {
5133 
5134  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5135  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5136 
5137  const size_t ipos( rows() & size_t(-2) );
5138  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5139 
5140  for( size_t j=0UL; j<columns(); ++j ) {
5141  const size_t index( idx(j) );
5142  for( size_t i=0UL; i<ipos; i+=2UL ) {
5143  matrix_(i ,index) = (~rhs)(i ,j);
5144  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
5145  }
5146  if( ipos < rows() ) {
5147  matrix_(ipos,index) = (~rhs)(ipos,j);
5148  }
5149  }
5150 }
5152 //*************************************************************************************************
5153 
5154 
5155 //*************************************************************************************************
5167 template< typename MT // Type of the dense matrix
5168  , typename... CCAs > // Compile time column arguments
5169 template< typename MT2 > // Type of the right-hand side dense matrix
5170 inline void Columns<MT,false,true,false,CCAs...>::assign( const DenseMatrix<MT2,false>& rhs )
5171 {
5174 
5176 
5177  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5178  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5179 
5180  constexpr size_t block( BLOCK_SIZE );
5181 
5182  if( rows() < block && columns() < block )
5183  {
5184  const size_t ipos( (~rhs).rows() & size_t(-2) );
5185  for( size_t j=0UL; j<columns(); ++j ) {
5186  const size_t index( idx(j) );
5187  for( size_t i=0UL; i<ipos; i+=2UL ) {
5188  matrix_(i ,index) = (~rhs)(i ,j);
5189  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
5190  }
5191  if( ipos < (~rhs).rows() ) {
5192  matrix_(ipos,index) = (~rhs)(ipos,j);
5193  }
5194  }
5195  }
5196  else
5197  {
5198  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5199  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5200  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5201  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5202  for( size_t j=jj; j<jend; ++j ) {
5203  const size_t index( idx(j) );
5204  for( size_t i=ii; i<iend; ++i ) {
5205  matrix_(i,index) = (~rhs)(i,j);
5206  }
5207  }
5208  }
5209  }
5210  }
5211 }
5213 //*************************************************************************************************
5214 
5215 
5216 //*************************************************************************************************
5228 template< typename MT // Type of the dense matrix
5229  , typename... CCAs > // Compile time column arguments
5230 template< typename MT2 > // Type of the right-hand side sparse matrix
5231 inline void Columns<MT,false,true,false,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
5232 {
5235 
5236  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5237  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5238 
5239  for( size_t j=0UL; j<columns(); ++j ) {
5240  const size_t index( idx(j) );
5241  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5242  matrix_(element->index(),index) = element->value();
5243  }
5244 }
5246 //*************************************************************************************************
5247 
5248 
5249 //*************************************************************************************************
5261 template< typename MT // Type of the dense matrix
5262  , typename... CCAs > // Compile time column arguments
5263 template< typename MT2 > // Type of the right-hand side sparse matrix
5264 inline void Columns<MT,false,true,false,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
5265 {
5268 
5270 
5271  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5272  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5273 
5274  for( size_t i=0UL; i<rows(); ++i ) {
5275  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5276  matrix_(i,idx(element->index())) = element->value();
5277  }
5278 }
5280 //*************************************************************************************************
5281 
5282 
5283 //*************************************************************************************************
5295 template< typename MT // Type of the dense matrix
5296  , typename... CCAs > // Compile time column arguments
5297 template< typename MT2 > // Type of the right-hand side dense matrix
5298 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
5299 {
5302 
5303  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5304  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5305 
5306  const size_t ipos( rows() & size_t(-2) );
5307  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5308 
5309  for( size_t j=0UL; j<columns(); ++j )
5310  {
5311  const size_t index( idx(j) );
5312  if( IsDiagonal_v<MT2> ) {
5313  matrix_(j,index) += (~rhs)(j,j);
5314  }
5315  else {
5316  for( size_t i=0UL; i<ipos; i+=2UL ) {
5317  matrix_(i ,index) += (~rhs)(i ,j);
5318  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
5319  }
5320  if( ipos < rows() ) {
5321  matrix_(ipos,index) += (~rhs)(ipos,j);
5322  }
5323  }
5324  }
5325 }
5327 //*************************************************************************************************
5328 
5329 
5330 //*************************************************************************************************
5342 template< typename MT // Type of the dense matrix
5343  , typename... CCAs > // Compile time column arguments
5344 template< typename MT2 > // Type of the right-hand side dense matrix
5345 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
5346 {
5349 
5351 
5352  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5353  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5354 
5355  constexpr size_t block( BLOCK_SIZE );
5356 
5357  if( rows() < block && columns() < block )
5358  {
5359  const size_t ipos( (~rhs).rows() & size_t(-2) );
5360  for( size_t j=0UL; j<columns(); ++j ) {
5361  const size_t index( idx(j) );
5362  for( size_t i=0UL; i<ipos; i+=2UL ) {
5363  matrix_(i ,index) += (~rhs)(i ,j);
5364  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
5365  }
5366  if( ipos < (~rhs).rows() )
5367  matrix_(ipos,index) += (~rhs)(ipos,j);
5368  }
5369  }
5370  else
5371  {
5372  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5373  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5374  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5375  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5376  for( size_t j=jj; j<jend; ++j ) {
5377  const size_t index( idx(j) );
5378  for( size_t i=ii; i<iend; ++i ) {
5379  matrix_(i,index) += (~rhs)(i,j);
5380  }
5381  }
5382  }
5383  }
5384  }
5385 }
5387 //*************************************************************************************************
5388 
5389 
5390 //*************************************************************************************************
5402 template< typename MT // Type of the dense matrix
5403  , typename... CCAs > // Compile time column arguments
5404 template< typename MT2 > // Type of the right-hand side sparse matrix
5405 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
5406 {
5409 
5410  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5411  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5412 
5413  for( size_t j=0UL; j<columns(); ++j ) {
5414  const size_t index( idx(j) );
5415  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5416  matrix_(element->index(),index) += element->value();
5417  }
5418 }
5420 //*************************************************************************************************
5421 
5422 
5423 //*************************************************************************************************
5435 template< typename MT // Type of the dense matrix
5436  , typename... CCAs > // Compile time column arguments
5437 template< typename MT2 > // Type of the right-hand side sparse matrix
5438 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
5439 {
5442 
5444 
5445  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5446  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5447 
5448  for( size_t i=0UL; i<rows(); ++i ) {
5449  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5450  matrix_(i,idx(element->index())) += element->value();
5451  }
5452 }
5454 //*************************************************************************************************
5455 
5456 
5457 //*************************************************************************************************
5469 template< typename MT // Type of the dense matrix
5470  , typename... CCAs > // Compile time column arguments
5471 template< typename MT2 > // Type of the right-hand side dense matrix
5472 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
5473 {
5476 
5477  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5478  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5479 
5480  const size_t ipos( rows() & size_t(-2) );
5481  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5482 
5483  for( size_t j=0UL; j<columns(); ++j )
5484  {
5485  const size_t index( idx(j) );
5486 
5487  if( IsDiagonal_v<MT2> ) {
5488  matrix_(j,index) -= (~rhs)(j,j);
5489  }
5490  else {
5491  for( size_t i=0UL; i<ipos; i+=2UL ) {
5492  matrix_(i ,index) -= (~rhs)(i ,j);
5493  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
5494  }
5495  if( ipos < rows() ) {
5496  matrix_(ipos,index) -= (~rhs)(ipos,j);
5497  }
5498  }
5499  }
5500 }
5502 //*************************************************************************************************
5503 
5504 
5505 //*************************************************************************************************
5517 template< typename MT // Type of the dense matrix
5518  , typename... CCAs > // Compile time column arguments
5519 template< typename MT2 > // Type of the right-hand side dense matrix
5520 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
5521 {
5524 
5526 
5527  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5528  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5529 
5530  constexpr size_t block( BLOCK_SIZE );
5531 
5532  if( rows() < block && columns() < block )
5533  {
5534  const size_t ipos( (~rhs).rows() & size_t(-2) );
5535  for( size_t j=0UL; j<columns(); ++j ) {
5536  const size_t index( idx(j) );
5537  for( size_t i=0UL; i<ipos; i+=2UL ) {
5538  matrix_(i ,index) -= (~rhs)(i ,j);
5539  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
5540  }
5541  if( ipos < (~rhs).rows() )
5542  matrix_(ipos,index) -= (~rhs)(ipos,j);
5543  }
5544  }
5545  else
5546  {
5547  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5548  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5549  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5550  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5551  for( size_t j=jj; j<jend; ++j ) {
5552  const size_t index( idx(j) );
5553  for( size_t i=ii; i<iend; ++i ) {
5554  matrix_(i,index) -= (~rhs)(i,j);
5555  }
5556  }
5557  }
5558  }
5559  }
5560 }
5562 //*************************************************************************************************
5563 
5564 
5565 //*************************************************************************************************
5577 template< typename MT // Type of the dense matrix
5578  , typename... CCAs > // Compile time column arguments
5579 template< typename MT2 > // Type of the right-hand side sparse matrix
5580 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
5581 {
5584 
5585  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5586  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5587 
5588  for( size_t j=0UL; j<columns(); ++j ) {
5589  const size_t index( idx(j) );
5590  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5591  matrix_(element->index(),index) -= element->value();
5592  }
5593 }
5595 //*************************************************************************************************
5596 
5597 
5598 //*************************************************************************************************
5610 template< typename MT // Type of the dense matrix
5611  , typename... CCAs > // Compile time column arguments
5612 template< typename MT2 > // Type of the right-hand side sparse matrix
5613 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
5614 {
5617 
5619 
5620  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5621  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5622 
5623  for( size_t i=0UL; i<rows(); ++i ) {
5624  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5625  matrix_(i,idx(element->index())) -= element->value();
5626  }
5627 }
5629 //*************************************************************************************************
5630 
5631 
5632 //*************************************************************************************************
5644 template< typename MT // Type of the dense matrix
5645  , typename... CCAs > // Compile time column arguments
5646 template< typename MT2 > // Type of the right-hand side dense matrix
5647 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
5648 {
5651 
5652  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5653  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5654 
5655  const size_t ipos( rows() & size_t(-2) );
5656  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5657 
5658  for( size_t j=0UL; j<columns(); ++j ) {
5659  const size_t index( idx(j) );
5660  for( size_t i=0UL; i<ipos; i+=2UL ) {
5661  matrix_(i ,index) *= (~rhs)(i ,j);
5662  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
5663  }
5664  if( ipos < rows() ) {
5665  matrix_(ipos,index) *= (~rhs)(ipos,j);
5666  }
5667  }
5668 }
5670 //*************************************************************************************************
5671 
5672 
5673 //*************************************************************************************************
5685 template< typename MT // Type of the dense matrix
5686  , typename... CCAs > // Compile time column arguments
5687 template< typename MT2 > // Type of the right-hand side dense matrix
5688 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
5689 {
5692 
5694 
5695  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5696  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5697 
5698  constexpr size_t block( BLOCK_SIZE );
5699 
5700  if( rows() < block && columns() < block )
5701  {
5702  const size_t ipos( (~rhs).rows() & size_t(-2) );
5703  for( size_t j=0UL; j<columns(); ++j ) {
5704  const size_t index( idx(j) );
5705  for( size_t i=0UL; i<ipos; i+=2UL ) {
5706  matrix_(i ,index) *= (~rhs)(i ,j);
5707  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
5708  }
5709  if( ipos < (~rhs).rows() )
5710  matrix_(ipos,index) *= (~rhs)(ipos,j);
5711  }
5712  }
5713  else
5714  {
5715  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5716  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5717  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5718  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5719  for( size_t j=jj; j<jend; ++j ) {
5720  const size_t index( idx(j) );
5721  for( size_t i=ii; i<iend; ++i ) {
5722  matrix_(i,index) *= (~rhs)(i,j);
5723  }
5724  }
5725  }
5726  }
5727  }
5728 }
5730 //*************************************************************************************************
5731 
5732 
5733 //*************************************************************************************************
5745 template< typename MT // Type of the dense matrix
5746  , typename... CCAs > // Compile time column arguments
5747 template< typename MT2 > // Type of the right-hand side sparse matrix
5748 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
5749 {
5750  using blaze::reset;
5751 
5754 
5755  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5756  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5757 
5758  for( size_t j=0UL; j<columns(); ++j )
5759  {
5760  const size_t index( idx(j) );
5761  size_t i( 0UL );
5762 
5763  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
5764  for( ; i<element->index(); ++i )
5765  reset( matrix_(i,index) );
5766  matrix_(i,index) *= element->value();
5767  ++i;
5768  }
5769 
5770  for( ; i<rows(); ++i ) {
5771  reset( matrix_(i,index) );
5772  }
5773  }
5774 }
5776 //*************************************************************************************************
5777 
5778 
5779 //*************************************************************************************************
5791 template< typename MT // Type of the dense matrix
5792  , typename... CCAs > // Compile time column arguments
5793 template< typename MT2 > // Type of the right-hand side sparse matrix
5794 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
5795 {
5796  using blaze::reset;
5797 
5800 
5802 
5803  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5804  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5805 
5806  for( size_t i=0UL; i<rows(); ++i )
5807  {
5808  size_t j( 0UL );
5809 
5810  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
5811  for( ; j<element->index(); ++j )
5812  reset( matrix_(i,idx(j)) );
5813  matrix_(i,idx(j)) *= element->value();
5814  ++j;
5815  }
5816 
5817  for( ; j<columns(); ++j ) {
5818  reset( matrix_(i,idx(j)) );
5819  }
5820  }
5821 }
5823 //*************************************************************************************************
5824 
5825 
5826 
5827 
5828 
5829 
5830 
5831 
5832 //=================================================================================================
5833 //
5834 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
5835 //
5836 //=================================================================================================
5837 
5838 //*************************************************************************************************
5846 template< typename MT // Type of the dense matrix
5847  , typename... CCAs > // Compile time column arguments
5848 class Columns<MT,false,true,true,CCAs...>
5849  : public View< DenseMatrix< Columns<MT,false,true,true,CCAs...>, true > >
5850  , private ColumnsData<CCAs...>
5851 {
5852  private:
5853  //**Type definitions****************************************************************************
5854  using DataType = ColumnsData<CCAs...>;
5855  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
5856  //**********************************************************************************************
5857 
5858  //**Compile time flags**************************************************************************
5859  static constexpr size_t N = sizeof...( CCAs );
5860  //**********************************************************************************************
5861 
5862  public:
5863  //**Type definitions****************************************************************************
5865  using This = Columns<MT,false,true,true,CCAs...>;
5866 
5867  using BaseType = DenseMatrix<This,true>;
5868  using ViewedType = MT;
5869  using ResultType = ColumnsTrait_t<MT,N>;
5870  using OppositeType = OppositeType_t<ResultType>;
5871  using TransposeType = TransposeType_t<ResultType>;
5872  using ElementType = ElementType_t<MT>;
5873  using SIMDType = SIMDTrait_t<ElementType>;
5874  using ReturnType = ReturnType_t<MT>;
5875  using CompositeType = const Columns&;
5876 
5878  using ConstReference = ConstReference_t<MT>;
5879 
5881  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
5882 
5884  using ConstPointer = ConstPointer_t<MT>;
5885 
5887  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
5888 
5890  using ConstIterator = ConstIterator_t<MT>;
5891 
5893  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
5894  //**********************************************************************************************
5895 
5896  //**Compilation flags***************************************************************************
5898  static constexpr bool simdEnabled = MT::simdEnabled;
5899 
5901  static constexpr bool smpAssignable = MT::smpAssignable;
5902  //**********************************************************************************************
5903 
5904  //**Constructors********************************************************************************
5907  template< typename... RCAs >
5908  explicit inline Columns( MT& matrix, RCAs... args );
5909 
5910  Columns( const Columns& ) = default;
5911  Columns( Columns&& ) = default;
5913  //**********************************************************************************************
5914 
5915  //**Destructor**********************************************************************************
5918  ~Columns() = default;
5920  //**********************************************************************************************
5921 
5922  //**Data access functions***********************************************************************
5925  inline Reference operator()( size_t i, size_t j );
5926  inline ConstReference operator()( size_t i, size_t j ) const;
5927  inline Reference at( size_t i, size_t j );
5928  inline ConstReference at( size_t i, size_t j ) const;
5929  inline Pointer data () noexcept;
5930  inline ConstPointer data () const noexcept;
5931  inline Pointer data ( size_t j ) noexcept;
5932  inline ConstPointer data ( size_t j ) const noexcept;
5933  inline Iterator begin ( size_t j );
5934  inline ConstIterator begin ( size_t j ) const;
5935  inline ConstIterator cbegin( size_t j ) const;
5936  inline Iterator end ( size_t j );
5937  inline ConstIterator end ( size_t j ) const;
5938  inline ConstIterator cend ( size_t j ) const;
5940  //**********************************************************************************************
5941 
5942  //**Assignment operators************************************************************************
5945  inline Columns& operator=( const ElementType& rhs );
5946 
5947  Columns& operator=( const Columns& ) = delete;
5949  //**********************************************************************************************
5950 
5951  //**Utility functions***************************************************************************
5954  using DataType::idx;
5955  using DataType::idces;
5956  using DataType::columns;
5957 
5958  inline MT& operand() noexcept;
5959  inline const MT& operand() const noexcept;
5960 
5961  inline size_t rows() const noexcept;
5962  inline size_t spacing() const noexcept;
5963  inline size_t capacity() const noexcept;
5964  inline size_t capacity( size_t j ) const noexcept;
5965  inline size_t nonZeros() const;
5966  inline size_t nonZeros( size_t j ) const;
5967  inline void reset();
5968  inline void reset( size_t j );
5970  //**********************************************************************************************
5971 
5972  //**Expression template evaluation functions****************************************************
5975  template< typename Other >
5976  inline bool canAlias( const Other* alias ) const noexcept;
5977 
5978  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
5979  inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
5980 
5981  template< typename Other >
5982  inline bool isAliased( const Other* alias ) const noexcept;
5983 
5984  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
5985  inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
5986 
5987  inline bool isAligned () const noexcept;
5988  inline bool canSMPAssign() const noexcept;
5989 
5990  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
5991  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
5992  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
5994  //**********************************************************************************************
5995 
5996  private:
5997  //**Member variables****************************************************************************
6000  Operand matrix_;
6001 
6002  //**********************************************************************************************
6003 
6004  //**Friend declarations*************************************************************************
6005  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
6006  //**********************************************************************************************
6007 
6008  //**Compile time checks*************************************************************************
6018  //**********************************************************************************************
6019 };
6021 //*************************************************************************************************
6022 
6023 
6024 
6025 
6026 //=================================================================================================
6027 //
6028 // CONSTRUCTORS
6029 //
6030 //=================================================================================================
6031 
6032 //*************************************************************************************************
6045 template< typename MT // Type of the dense matrix
6046  , typename... CCAs > // Compile time column arguments
6047 template< typename... RCAs > // Runtime column arguments
6048 inline Columns<MT,false,true,true,CCAs...>::Columns( MT& matrix, RCAs... args )
6049  : DataType( args... ) // Base class initialization
6050  , matrix_ ( matrix ) // The matrix containing the columns
6051 {
6052  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
6053  for( size_t j=0UL; j<columns(); ++j ) {
6054  if( matrix_.columns() <= idx(j) ) {
6055  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
6056  }
6057  }
6058  }
6059 }
6061 //*************************************************************************************************
6062 
6063 
6064 
6065 
6066 //=================================================================================================
6067 //
6068 // DATA ACCESS FUNCTIONS
6069 //
6070 //=================================================================================================
6071 
6072 //*************************************************************************************************
6083 template< typename MT // Type of the dense matrix
6084  , typename... CCAs > // Compile time column arguments
6085 inline typename Columns<MT,false,true,true,CCAs...>::Reference
6086  Columns<MT,false,true,true,CCAs...>::operator()( size_t i, size_t j )
6087 {
6088  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6089  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6090 
6091  return matrix_(idx(j),i);
6092 }
6094 //*************************************************************************************************
6095 
6096 
6097 //*************************************************************************************************
6108 template< typename MT // Type of the dense matrix
6109  , typename... CCAs > // Compile time column arguments
6110 inline typename Columns<MT,false,true,true,CCAs...>::ConstReference
6111  Columns<MT,false,true,true,CCAs...>::operator()( size_t i, size_t j ) const
6112 {
6113  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6114  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6115 
6116  return const_cast<const MT&>( matrix_ )(idx(j),i);
6117 }
6119 //*************************************************************************************************
6120 
6121 
6122 //*************************************************************************************************
6134 template< typename MT // Type of the dense matrix
6135  , typename... CCAs > // Compile time column arguments
6136 inline typename Columns<MT,false,true,true,CCAs...>::Reference
6137  Columns<MT,false,true,true,CCAs...>::at( size_t i, size_t j )
6138 {
6139  if( i >= rows() ) {
6140  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6141  }
6142  if( j >= columns() ) {
6143  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6144  }
6145  return (*this)(i,j);
6146 }
6148 //*************************************************************************************************
6149 
6150 
6151 //*************************************************************************************************
6163 template< typename MT // Type of the dense matrix
6164  , typename... CCAs > // Compile time column arguments
6165 inline typename Columns<MT,false,true,true,CCAs...>::ConstReference
6166  Columns<MT,false,true,true,CCAs...>::at( size_t i, size_t j ) const
6167 {
6168  if( i >= rows() ) {
6169  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6170  }
6171  if( j >= columns() ) {
6172  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6173  }
6174  return (*this)(i,j);
6175 }
6177 //*************************************************************************************************
6178 
6179 
6180 //*************************************************************************************************
6190 template< typename MT // Type of the dense matrix
6191  , typename... CCAs > // Compile time column arguments
6192 inline typename Columns<MT,false,true,true,CCAs...>::Pointer
6194 {
6195  return matrix_.data( idx(0UL) );
6196 }
6198 //*************************************************************************************************
6199 
6200 
6201 //*************************************************************************************************
6211 template< typename MT // Type of the dense matrix
6212  , typename... CCAs > // Compile time column arguments
6213 inline typename Columns<MT,false,true,true,CCAs...>::ConstPointer
6215 {
6216  return matrix_.data( idx(0UL) );
6217 }
6219 //*************************************************************************************************
6220 
6221 
6222 //*************************************************************************************************
6231 template< typename MT // Type of the dense matrix
6232  , typename... CCAs > // Compile time column arguments
6233 inline typename Columns<MT,false,true,true,CCAs...>::Pointer
6234  Columns<MT,false,true,true,CCAs...>::data( size_t j ) noexcept
6235 {
6236  return matrix_.data( idx(j) );
6237 }
6239 //*************************************************************************************************
6240 
6241 
6242 //*************************************************************************************************
6251 template< typename MT // Type of the dense matrix
6252  , typename... CCAs > // Compile time column arguments
6253 inline typename Columns<MT,false,true,true,CCAs...>::ConstPointer
6254  Columns<MT,false,true,true,CCAs...>::data( size_t j ) const noexcept
6255 {
6256  return matrix_.data( idx(j) );
6257 }
6259 //*************************************************************************************************
6260 
6261 
6262 //*************************************************************************************************
6271 template< typename MT // Type of the dense matrix
6272  , typename... CCAs > // Compile time column arguments
6273 inline typename Columns<MT,false,true,true,CCAs...>::Iterator
6275 {
6276  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6277  return matrix_.begin( idx(j) );
6278 }
6280 //*************************************************************************************************
6281 
6282 
6283 //*************************************************************************************************
6292 template< typename MT // Type of the dense matrix
6293  , typename... CCAs > // Compile time column arguments
6294 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6296 {
6297  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6298  return matrix_.cbegin( idx(j) );
6299 }
6301 //*************************************************************************************************
6302 
6303 
6304 //*************************************************************************************************
6313 template< typename MT // Type of the dense matrix
6314  , typename... CCAs > // Compile time column arguments
6315 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6317 {
6318  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6319  return matrix_.cbegin( idx(j) );
6320 }
6322 //*************************************************************************************************
6323 
6324 
6325 //*************************************************************************************************
6334 template< typename MT // Type of the dense matrix
6335  , typename... CCAs > // Compile time column arguments
6336 inline typename Columns<MT,false,true,true,CCAs...>::Iterator
6338 {
6339  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6340  return matrix_.end( idx(j) );
6341 }
6343 //*************************************************************************************************
6344 
6345 
6346 //*************************************************************************************************
6355 template< typename MT // Type of the dense matrix
6356  , typename... CCAs > // Compile time column arguments
6357 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6359 {
6360  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6361  return matrix_.cend( idx(j) );
6362 }
6364 //*************************************************************************************************
6365 
6366 
6367 //*************************************************************************************************
6376 template< typename MT // Type of the dense matrix
6377  , typename... CCAs > // Compile time column arguments
6378 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6380 {
6381  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6382  return matrix_.cend( idx(j) );
6383 }
6385 //*************************************************************************************************
6386 
6387 
6388 
6389 
6390 //=================================================================================================
6391 //
6392 // ASSIGNMENT OPERATORS
6393 //
6394 //=================================================================================================
6395 
6396 //*************************************************************************************************
6407 template< typename MT // Type of the dense matrix
6408  , typename... CCAs > // Compile time column arguments
6409 inline Columns<MT,false,true,true,CCAs...>&
6410  Columns<MT,false,true,true,CCAs...>::operator=( const ElementType& rhs )
6411 {
6412  for( size_t j=0UL; j<columns(); ++j ) {
6413  row( matrix_, idx(j), unchecked ) = rhs;
6414  }
6415 
6416  return *this;
6417 }
6419 //*************************************************************************************************
6420 
6421 
6422 
6423 
6424 //=================================================================================================
6425 //
6426 // UTILITY FUNCTIONS
6427 //
6428 //=================================================================================================
6429 
6430 //*************************************************************************************************
6436 template< typename MT // Type of the dense matrix
6437  , typename... CCAs > // Compile time column arguments
6438 inline MT& Columns<MT,false,true,true,CCAs...>::operand() noexcept
6439 {
6440  return matrix_;
6441 }
6443 //*************************************************************************************************
6444 
6445 
6446 //*************************************************************************************************
6452 template< typename MT // Type of the dense matrix
6453  , typename... CCAs > // Compile time column arguments
6454 inline const MT& Columns<MT,false,true,true,CCAs...>::operand() const noexcept
6455 {
6456  return matrix_;
6457 }
6459 //*************************************************************************************************
6460 
6461 
6462 //*************************************************************************************************
6468 template< typename MT // Type of the dense matrix
6469  , typename... CCAs > // Compile time column arguments
6470 inline size_t Columns<MT,false,true,true,CCAs...>::rows() const noexcept
6471 {
6472  return matrix_.rows();
6473 }
6475 //*************************************************************************************************
6476 
6477 
6478 //*************************************************************************************************
6487 template< typename MT // Type of the dense matrix
6488  , typename... CCAs > // Compile time column arguments
6489 inline size_t Columns<MT,false,true,true,CCAs...>::spacing() const noexcept
6490 {
6491  return matrix_.spacing();
6492 }
6494 //*************************************************************************************************
6495 
6496 
6497 //*************************************************************************************************
6503 template< typename MT // Type of the dense matrix
6504  , typename... CCAs > // Compile time column arguments
6505 inline size_t Columns<MT,false,true,true,CCAs...>::capacity() const noexcept
6506 {
6507  return rows() * columns();
6508 }
6510 //*************************************************************************************************
6511 
6512 
6513 //*************************************************************************************************
6522 template< typename MT // Type of the dense matrix
6523  , typename... CCAs > // Compile time column arguments
6524 inline size_t Columns<MT,false,true,true,CCAs...>::capacity( size_t j ) const noexcept
6525 {
6526  UNUSED_PARAMETER( j );
6527 
6528  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6529 
6530  return rows();
6531 }
6533 //*************************************************************************************************
6534 
6535 
6536 //*************************************************************************************************
6542 template< typename MT // Type of the dense matrix
6543  , typename... CCAs > // Compile time column arguments
6545 {
6546  size_t nonzeros( 0UL );
6547 
6548  for( size_t j=0UL; j<columns(); ++j ) {
6549  nonzeros += matrix_.nonZeros( idx(j) );
6550  }
6551 
6552  return nonzeros;
6553 }
6555 //*************************************************************************************************
6556 
6557 
6558 //*************************************************************************************************
6567 template< typename MT // Type of the dense matrix
6568  , typename... CCAs > // Compile time column arguments
6569 inline size_t Columns<MT,false,true,true,CCAs...>::nonZeros( size_t j ) const
6570 {
6571  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6572 
6573  return matrix_.nonZeros( idx(j) );
6574 }
6576 //*************************************************************************************************
6577 
6578 
6579 //*************************************************************************************************
6585 template< typename MT // Type of the dense matrix
6586  , typename... CCAs > // Compile time column arguments
6588 {
6589  for( size_t j=0UL; j<columns(); ++j ) {
6590  matrix_.reset( idx(j) );
6591  }
6592 }
6594 //*************************************************************************************************
6595 
6596 
6597 //*************************************************************************************************
6606 template< typename MT // Type of the dense matrix
6607  , typename... CCAs > // Compile time column arguments
6608 inline void Columns<MT,false,true,true,CCAs...>::reset( size_t j )
6609 {
6610  matrix_.reset( idx(j) );
6611 }
6613 //*************************************************************************************************
6614 
6615 
6616 //=================================================================================================
6617 //
6618 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6619 //
6620 //=================================================================================================
6621 
6622 //*************************************************************************************************
6633 template< typename MT // Type of the dense matrix
6634  , typename... CCAs > // Compile time column arguments
6635 template< typename Other > // Data type of the foreign expression
6636 inline bool Columns<MT,false,true,true,CCAs...>::canAlias( const Other* alias ) const noexcept
6637 {
6638  return matrix_.isAliased( alias );
6639 }
6641 //*************************************************************************************************
6642 
6643 
6644 //*************************************************************************************************
6656 template< typename MT // Type of the dense matrix
6657  , typename... CCAs > // Compile time column arguments
6658 template< typename MT2 // Data type of the foreign dense column selection
6659  , bool SO2 // Storage order of the foreign dense column selection
6660  , bool SF2 // Symmetry flag of the foreign dense column selection
6661  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
6662 inline bool
6663  Columns<MT,false,true,true,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
6664 {
6665  return matrix_.isAliased( &alias->matrix_ );
6666 }
6668 //*************************************************************************************************
6669 
6670 
6671 //*************************************************************************************************
6682 template< typename MT // Type of the dense matrix
6683  , typename... CCAs > // Compile time column arguments
6684 template< typename Other > // Data type of the foreign expression
6685 inline bool Columns<MT,false,true,true,CCAs...>::isAliased( const Other* alias ) const noexcept
6686 {
6687  return matrix_.isAliased( alias );
6688 }
6690 //*************************************************************************************************
6691 
6692 
6693 //*************************************************************************************************
6705 template< typename MT // Type of the dense matrix
6706  , typename... CCAs > // Compile time column arguments
6707 template< typename MT2 // Data type of the foreign dense column selection
6708  , bool SO2 // Storage order of the foreign dense column selection
6709  , bool SF2 // Symmetry flag of the foreign dense column selection
6710  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
6711 inline bool
6712  Columns<MT,false,true,true,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
6713 {
6714  return matrix_.isAliased( &alias->matrix_ );
6715 }
6717 //*************************************************************************************************
6718 
6719 
6720 //*************************************************************************************************
6730 template< typename MT // Type of the dense matrix
6731  , typename... CCAs > // Compile time column arguments
6732 inline bool Columns<MT,false,true,true,CCAs...>::isAligned() const noexcept
6733 {
6734  return matrix_.isAligned();
6735 }
6737 //*************************************************************************************************
6738 
6739 
6740 //*************************************************************************************************
6751 template< typename MT // Type of the dense matrix
6752  , typename... CCAs > // Compile time column arguments
6753 inline bool Columns<MT,false,true,true,CCAs...>::canSMPAssign() const noexcept
6754 {
6755  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
6756 }
6758 //*************************************************************************************************
6759 
6760 
6761 //*************************************************************************************************
6776 template< typename MT // Type of the dense matrix
6777  , typename... CCAs > // Compile time column arguments
6778 BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6779  Columns<MT,false,true,true,CCAs...>::load( size_t i, size_t j ) const noexcept
6780 {
6781  return matrix_.load( idx(j), i );
6782 }
6784 //*************************************************************************************************
6785 
6786 
6787 //*************************************************************************************************
6802 template< typename MT // Type of the dense matrix
6803  , typename... CCAs > // Compile time column arguments
6804 BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6805  Columns<MT,false,true,true,CCAs...>::loada( size_t i, size_t j ) const noexcept
6806 {
6807  return matrix_.loada( idx(j), i );
6808 }
6810 //*************************************************************************************************
6811 
6812 
6813 //*************************************************************************************************
6828 template< typename MT // Type of the dense matrix
6829  , typename... CCAs > // Compile time column arguments
6830 BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6831  Columns<MT,false,true,true,CCAs...>::loadu( size_t i, size_t j ) const noexcept
6832 {
6833  return matrix_.loadu( idx(j), i );
6834 }
6836 //*************************************************************************************************
6837 
6838 } // namespace blaze
6839 
6840 #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.
Header file for the implementation of the Columns base template.
Header file for kernel specific block sizes.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3078
Header file for the Schur product trait.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the UNUSED_PARAMETER function template.
Header file for the subtraction 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:169
Header file for the View base class.
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:188
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:61
BLAZE_ALWAYS_INLINE 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
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3077
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
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:591
static constexpr bool smpAssignable
Compilation flag for SMP assignments.
Definition: CompressedMatrix.h:3113
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3079
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:81
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:851
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3084
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.
Header file for the decltype(auto) workaround.
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3085
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
Header file for the RequiresEvaluation type trait.
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
constexpr void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
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
Constraint on the data type.
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:252
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
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
Header file for the DisableIf class template.
Header file for the IsStrictlyUpper type trait.
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3083
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
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1364
Header file for the If class template.
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a column-major dense or sparse matri...
Definition: ColumnMajorMatrix.h:61
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:189
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3076
#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
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3080
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
Header file for the DenseMatrix base class.
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
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3086
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:139
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.
#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
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
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COLUMNS_TYPE(T)
Constraint on the data type.In case the given data type T is a column selection type (i...
Definition: Columns.h:81
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:8908
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.
Constraint on the data type.
Header file for the IsSIMDCombinable type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the addition 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
Header file for the columns trait.
Constraint on the data type.
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:133
Header file for the cache size of the target architecture.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
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.
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.
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.The IsDiagonal_v variable template provides...
Definition: IsDiagonal.h:148
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
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3081
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:765
Header file for the implementation of the ColumnsData class template.
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
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3082
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:188
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:263
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:631
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type, a compilation error is created.
Definition: Hermitian.h:79
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
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 IsRestricted type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the IsExpression type trait class.
Constraint on the data type.
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:825