Blaze  3.6
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>
93 #include <blaze/util/DisableIf.h>
94 #include <blaze/util/EnableIf.h>
95 #include <blaze/util/MaybeUnused.h>
96 #include <blaze/util/mpl/If.h>
97 #include <blaze/util/TypeList.h>
98 #include <blaze/util/Types.h>
101 
102 
103 namespace blaze {
104 
105 //=================================================================================================
106 //
107 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR DENSE MATRICES
108 //
109 //=================================================================================================
110 
111 //*************************************************************************************************
119 template< typename MT // Type of the dense matrix
120  , bool SF // Symmetry flag
121  , typename... CCAs > // Compile time column arguments
122 class Columns<MT,true,true,SF,CCAs...>
123  : public View< DenseMatrix< Columns<MT,true,true,SF,CCAs...>, true > >
124  , private ColumnsData<CCAs...>
125 {
126  private:
127  //**Type definitions****************************************************************************
128  using DataType = ColumnsData<CCAs...>;
129  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
130  //**********************************************************************************************
131 
132  //**Compile time flags**************************************************************************
133  static constexpr size_t N = sizeof...( CCAs );
134  //**********************************************************************************************
135 
136  //**********************************************************************************************
138  template< typename MT1, typename MT2 >
139  static constexpr bool EnforceEvaluation_v =
140  ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
141  //**********************************************************************************************
142 
143  public:
144  //**Type definitions****************************************************************************
146  using This = Columns<MT,true,true,SF,CCAs...>;
147 
148  using BaseType = DenseMatrix<This,true>;
149  using ViewedType = MT;
150  using ResultType = ColumnsTrait_t<MT,N>;
151  using OppositeType = OppositeType_t<ResultType>;
152  using TransposeType = TransposeType_t<ResultType>;
153  using ElementType = ElementType_t<MT>;
154  using SIMDType = SIMDTrait_t<ElementType>;
155  using ReturnType = ReturnType_t<MT>;
156  using CompositeType = const Columns&;
157 
159  using ConstReference = ConstReference_t<MT>;
160 
162  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
163 
165  using ConstPointer = ConstPointer_t<MT>;
166 
168  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
169 
171  using ConstIterator = ConstIterator_t<MT>;
172 
174  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
175  //**********************************************************************************************
176 
177  //**Compilation flags***************************************************************************
179  static constexpr bool simdEnabled = MT::simdEnabled;
180 
182  static constexpr bool smpAssignable = MT::smpAssignable;
183 
185  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
186  //**********************************************************************************************
187 
188  //**Constructors********************************************************************************
191  template< typename... RCAs >
192  explicit inline Columns( MT& matrix, RCAs... args );
193 
194  Columns( const Columns& ) = default;
195  Columns( Columns&& ) = default;
197  //**********************************************************************************************
198 
199  //**Destructor**********************************************************************************
202  ~Columns() = default;
204  //**********************************************************************************************
205 
206  //**Data access functions***********************************************************************
209  inline Reference operator()( size_t i, size_t j );
210  inline ConstReference operator()( size_t i, size_t j ) const;
211  inline Reference at( size_t i, size_t j );
212  inline ConstReference at( size_t i, size_t j ) const;
213  inline Pointer data () noexcept;
214  inline ConstPointer data () const noexcept;
215  inline Pointer data ( size_t j ) noexcept;
216  inline ConstPointer data ( size_t j ) const noexcept;
217  inline Iterator begin ( size_t j );
218  inline ConstIterator begin ( size_t j ) const;
219  inline ConstIterator cbegin( size_t j ) const;
220  inline Iterator end ( size_t j );
221  inline ConstIterator end ( size_t j ) const;
222  inline ConstIterator cend ( size_t j ) const;
224  //**********************************************************************************************
225 
226  //**Assignment operators************************************************************************
229  inline Columns& operator=( const ElementType& rhs );
230  inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
231  inline Columns& operator=( const Columns& rhs );
232 
233  template< typename MT2, bool SO2 >
234  inline Columns& operator=( const Matrix<MT2,SO2>& rhs );
235 
236  template< typename MT2, bool SO2 >
237  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
238  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
239 
240  template< typename MT2, bool SO2 >
241  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
242  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
243 
244  template< typename MT2, bool SO2 >
245  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
246  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
247 
248  template< typename MT2, bool SO2 >
249  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
250  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
251 
252  template< typename MT2, bool SO2 >
253  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
254  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
255 
256  template< typename MT2, bool SO2 >
257  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
258  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
260  //**********************************************************************************************
261 
262  //**Utility functions***************************************************************************
265  using DataType::idx;
266  using DataType::idces;
267  using DataType::columns;
268 
269  inline MT& operand() noexcept;
270  inline const MT& operand() const noexcept;
271 
272  inline size_t rows() const noexcept;
273  inline size_t spacing() const noexcept;
274  inline size_t capacity() const noexcept;
275  inline size_t capacity( size_t j ) const noexcept;
276  inline size_t nonZeros() const;
277  inline size_t nonZeros( size_t j ) const;
278  inline void reset();
279  inline void reset( size_t j );
281  //**********************************************************************************************
282 
283  //**Numeric functions***************************************************************************
286  inline Columns& transpose();
287  inline Columns& ctranspose();
288 
289  template< typename Other > inline Columns& scale( const Other& scalar );
291  //**********************************************************************************************
292 
293  private:
294  //**********************************************************************************************
296  template< typename MT2 >
297  static constexpr bool VectorizedAssign_v =
298  ( useOptimizedKernels &&
299  simdEnabled && MT2::simdEnabled &&
300  IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > );
301  //**********************************************************************************************
302 
303  //**********************************************************************************************
305  template< typename MT2 >
306  static constexpr bool VectorizedAddAssign_v =
307  ( useOptimizedKernels &&
308  simdEnabled && MT2::simdEnabled &&
309  IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > &&
310  HasSIMDAdd_v< ElementType, ElementType_t<MT2> > &&
311  !IsDiagonal_v<MT2> );
312  //**********************************************************************************************
313 
314  //**********************************************************************************************
316  template< typename MT2 >
317  static constexpr bool VectorizedSubAssign_v =
318  ( useOptimizedKernels &&
319  simdEnabled && MT2::simdEnabled &&
320  IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > &&
321  HasSIMDSub_v< ElementType, ElementType_t<MT2> > &&
322  !IsDiagonal_v<MT2> );
323  //**********************************************************************************************
324 
325  //**********************************************************************************************
327  template< typename MT2 >
328  static constexpr bool VectorizedSchurAssign_v =
329  ( useOptimizedKernels &&
330  simdEnabled && MT2::simdEnabled &&
331  IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > &&
332  HasSIMDMult_v< ElementType, ElementType_t<MT2> > );
333  //**********************************************************************************************
334 
335  //**SIMD properties*****************************************************************************
337  static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
338  //**********************************************************************************************
339 
340  public:
341  //**Expression template evaluation functions****************************************************
344  template< typename Other >
345  inline bool canAlias( const Other* alias ) const noexcept;
346 
347  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
348  inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
349 
350  template< typename Other >
351  inline bool isAliased( const Other* alias ) const noexcept;
352 
353  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
354  inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
355 
356  inline bool isAligned () const noexcept;
357  inline bool canSMPAssign() const noexcept;
358 
359  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
360  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
361  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
362 
363  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
364  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
365  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
366  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
367 
368  template< typename MT2 >
369  inline auto assign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT2> >;
370 
371  template< typename MT2 >
372  inline auto assign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT2> >;
373 
374  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
375 
376  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
377  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
378 
379  template< typename MT2 >
380  inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT2> >;
381 
382  template< typename MT2 >
383  inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT2> >;
384 
385  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
386  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
387  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
388 
389  template< typename MT2 >
390  inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT2> >;
391 
392  template< typename MT2 >
393  inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT2> >;
394 
395  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
396  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
397  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
398 
399  template< typename MT2 >
400  inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT2> >;
401 
402  template< typename MT2 >
403  inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT2> >;
404 
405  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
406  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
407  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
409  //**********************************************************************************************
410 
411  private:
412  //**Member variables****************************************************************************
415  Operand matrix_;
416 
417  //**********************************************************************************************
418 
419  //**Friend declarations*************************************************************************
420  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
421  //**********************************************************************************************
422 
423  //**Compile time checks*************************************************************************
432  //**********************************************************************************************
433 };
435 //*************************************************************************************************
436 
437 
438 
439 
440 //=================================================================================================
441 //
442 // CONSTRUCTORS
443 //
444 //=================================================================================================
445 
446 //*************************************************************************************************
459 template< typename MT // Type of the dense matrix
460  , bool SF // Symmetry flag
461  , typename... CCAs > // Compile time column arguments
462 template< typename... RCAs > // Runtime column arguments
463 inline Columns<MT,true,true,SF,CCAs...>::Columns( MT& matrix, RCAs... args )
464  : DataType( args... ) // Base class initialization
465  , matrix_ ( matrix ) // The matrix containing the columns
466 {
467  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
468  for( size_t j=0UL; j<columns(); ++j ) {
469  if( matrix_.columns() <= idx(j) ) {
470  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
471  }
472  }
473  }
474 }
476 //*************************************************************************************************
477 
478 
479 
480 
481 //=================================================================================================
482 //
483 // DATA ACCESS FUNCTIONS
484 //
485 //=================================================================================================
486 
487 //*************************************************************************************************
498 template< typename MT // Type of the dense matrix
499  , bool SF // Symmetry flag
500  , typename... CCAs > // Compile time column arguments
501 inline typename Columns<MT,true,true,SF,CCAs...>::Reference
502  Columns<MT,true,true,SF,CCAs...>::operator()( size_t i, size_t j )
503 {
504  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
505  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
506 
507  return matrix_(i,idx(j));
508 }
510 //*************************************************************************************************
511 
512 
513 //*************************************************************************************************
524 template< typename MT // Type of the dense matrix
525  , bool SF // Symmetry flag
526  , typename... CCAs > // Compile time column arguments
527 inline typename Columns<MT,true,true,SF,CCAs...>::ConstReference
528  Columns<MT,true,true,SF,CCAs...>::operator()( size_t i, size_t j ) const
529 {
530  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
531  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
532 
533  return const_cast<const MT&>( matrix_ )(i,idx(j));
534 }
536 //*************************************************************************************************
537 
538 
539 //*************************************************************************************************
551 template< typename MT // Type of the dense matrix
552  , bool SF // Symmetry flag
553  , typename... CCAs > // Compile time column arguments
554 inline typename Columns<MT,true,true,SF,CCAs...>::Reference
555  Columns<MT,true,true,SF,CCAs...>::at( size_t i, size_t j )
556 {
557  if( i >= rows() ) {
558  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
559  }
560  if( j >= columns() ) {
561  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
562  }
563  return (*this)(i,j);
564 }
566 //*************************************************************************************************
567 
568 
569 //*************************************************************************************************
581 template< typename MT // Type of the dense matrix
582  , bool SF // Symmetry flag
583  , typename... CCAs > // Compile time column arguments
584 inline typename Columns<MT,true,true,SF,CCAs...>::ConstReference
585  Columns<MT,true,true,SF,CCAs...>::at( size_t i, size_t j ) const
586 {
587  if( i >= rows() ) {
588  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
589  }
590  if( j >= columns() ) {
591  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
592  }
593  return (*this)(i,j);
594 }
596 //*************************************************************************************************
597 
598 
599 //*************************************************************************************************
609 template< typename MT // Type of the dense matrix
610  , bool SF // Symmetry flag
611  , typename... CCAs > // Compile time column arguments
612 inline typename Columns<MT,true,true,SF,CCAs...>::Pointer
614 {
615  return matrix_.data( idx(0UL) );
616 }
618 //*************************************************************************************************
619 
620 
621 //*************************************************************************************************
631 template< typename MT // Type of the dense matrix
632  , bool SF // Symmetry flag
633  , typename... CCAs > // Compile time column arguments
634 inline typename Columns<MT,true,true,SF,CCAs...>::ConstPointer
636 {
637  return matrix_.data( idx(0UL) );
638 }
640 //*************************************************************************************************
641 
642 
643 //*************************************************************************************************
652 template< typename MT // Type of the dense matrix
653  , bool SF // Symmetry flag
654  , typename... CCAs > // Compile time column arguments
655 inline typename Columns<MT,true,true,SF,CCAs...>::Pointer
656  Columns<MT,true,true,SF,CCAs...>::data( size_t j ) noexcept
657 {
658  return matrix_.data( idx(j) );
659 }
661 //*************************************************************************************************
662 
663 
664 //*************************************************************************************************
673 template< typename MT // Type of the dense matrix
674  , bool SF // Symmetry flag
675  , typename... CCAs > // Compile time column arguments
676 inline typename Columns<MT,true,true,SF,CCAs...>::ConstPointer
677  Columns<MT,true,true,SF,CCAs...>::data( size_t j ) const noexcept
678 {
679  return matrix_.data( idx(j) );
680 }
682 //*************************************************************************************************
683 
684 
685 //*************************************************************************************************
694 template< typename MT // Type of the dense matrix
695  , bool SF // Symmetry flag
696  , typename... CCAs > // Compile time column arguments
697 inline typename Columns<MT,true,true,SF,CCAs...>::Iterator
699 {
700  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
701  return matrix_.begin( idx(j) );
702 }
704 //*************************************************************************************************
705 
706 
707 //*************************************************************************************************
716 template< typename MT // Type of the dense matrix
717  , bool SF // Symmetry flag
718  , typename... CCAs > // Compile time column arguments
719 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
721 {
722  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
723  return matrix_.cbegin( idx(j) );
724 }
726 //*************************************************************************************************
727 
728 
729 //*************************************************************************************************
738 template< typename MT // Type of the dense matrix
739  , bool SF // Symmetry flag
740  , typename... CCAs > // Compile time column arguments
741 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
743 {
744  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
745  return matrix_.cbegin( idx(j) );
746 }
748 //*************************************************************************************************
749 
750 
751 //*************************************************************************************************
760 template< typename MT // Type of the dense matrix
761  , bool SF // Symmetry flag
762  , typename... CCAs > // Compile time column arguments
763 inline typename Columns<MT,true,true,SF,CCAs...>::Iterator
765 {
766  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
767  return matrix_.end( idx(j) );
768 }
770 //*************************************************************************************************
771 
772 
773 //*************************************************************************************************
782 template< typename MT // Type of the dense matrix
783  , bool SF // Symmetry flag
784  , typename... CCAs > // Compile time column arguments
785 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
786  Columns<MT,true,true,SF,CCAs...>::end( size_t j ) const
787 {
788  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
789  return matrix_.cend( idx(j) );
790 }
792 //*************************************************************************************************
793 
794 
795 //*************************************************************************************************
804 template< typename MT // Type of the dense matrix
805  , bool SF // Symmetry flag
806  , typename... CCAs > // Compile time column arguments
807 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
809 {
810  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
811  return matrix_.cend( idx(j) );
812 }
814 //*************************************************************************************************
815 
816 
817 
818 
819 //=================================================================================================
820 //
821 // ASSIGNMENT OPERATORS
822 //
823 //=================================================================================================
824 
825 //*************************************************************************************************
836 template< typename MT // Type of the dense matrix
837  , bool SF // Symmetry flag
838  , typename... CCAs > // Compile time column arguments
839 inline Columns<MT,true,true,SF,CCAs...>&
840  Columns<MT,true,true,SF,CCAs...>::operator=( const ElementType& rhs )
841 {
842  for( size_t j=0UL; j<columns(); ++j ) {
843  column( matrix_, idx(j), unchecked ) = rhs;
844  }
845 
846  return *this;
847 }
849 //*************************************************************************************************
850 
851 
852 //*************************************************************************************************
868 template< typename MT // Type of the dense matrix
869  , bool SF // Symmetry flag
870  , typename... CCAs > // Compile time column arguments
871 inline Columns<MT,true,true,SF,CCAs...>&
872  Columns<MT,true,true,SF,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
873 {
876 
877  if( list.size() != rows() ) {
878  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
879  }
880 
881  if( IsRestricted_v<MT> ) {
882  const InitializerMatrix<ElementType> tmp( list, columns() );
883  for( size_t j=0UL; j<columns(); ++j ) {
884  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
885  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
886  }
887  }
888  }
889 
890  decltype(auto) left( derestrict( *this ) );
891  size_t i( 0UL );
892 
893  for( const auto& rowList : list ) {
894  size_t j( 0UL );
895  for( const auto& element : rowList ) {
896  matrix_(i,idx(j)) = element;
897  ++j;
898  }
899  for( ; j<columns(); ++j ) {
900  matrix_(i,idx(j)) = ElementType();
901  }
902  ++i;
903  }
904 
905  return *this;
906 }
908 //*************************************************************************************************
909 
910 
911 //*************************************************************************************************
926 template< typename MT // Type of the dense matrix
927  , bool SF // Symmetry flag
928  , typename... CCAs > // Compile time column arguments
929 inline Columns<MT,true,true,SF,CCAs...>&
930  Columns<MT,true,true,SF,CCAs...>::operator=( const Columns& rhs )
931 {
934 
937 
938  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
939  return *this;
940 
941  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
942  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
943  }
944 
945  if( IsRestricted_v<MT> ) {
946  for( size_t j=0UL; j<columns(); ++j ) {
947  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( rhs, j, unchecked ), 0UL ) ) {
948  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
949  }
950  }
951  }
952 
953  decltype(auto) left( derestrict( *this ) );
954 
955  if( rhs.canAlias( &matrix_ ) ) {
956  const ResultType tmp( rhs );
957  smpAssign( left, tmp );
958  }
959  else {
960  smpAssign( left, rhs );
961  }
962 
963  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
964 
965  return *this;
966 }
968 //*************************************************************************************************
969 
970 
971 //*************************************************************************************************
986 template< typename MT // Type of the dense matrix
987  , bool SF // Symmetry flag
988  , typename... CCAs > // Compile time column arguments
989 template< typename MT2 // Type of the right-hand side matrix
990  , bool SO2 > // Storage order of the right-hand side matrix
991 inline Columns<MT,true,true,SF,CCAs...>&
992  Columns<MT,true,true,SF,CCAs...>::operator=( const Matrix<MT2,SO2>& rhs )
993 {
996 
998 
999  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1000  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1001  }
1002 
1003  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
1004  Right right( ~rhs );
1005 
1006  if( IsRestricted_v<MT> ) {
1007  for( size_t j=0UL; j<columns(); ++j ) {
1008  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( right, j, unchecked ), 0UL ) ) {
1009  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1010  }
1011  }
1012  }
1013 
1014  decltype(auto) left( derestrict( *this ) );
1015 
1016  if( IsSparseMatrix_v<MT2> ) {
1017  reset();
1018  }
1019 
1020  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
1021  const ResultType_t<MT2> tmp( right );
1022  smpAssign( left, tmp );
1023  }
1024  else {
1025  smpAssign( left, right );
1026  }
1027 
1028  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1029 
1030  return *this;
1031 }
1033 //*************************************************************************************************
1034 
1035 
1036 //*************************************************************************************************
1050 template< typename MT // Type of the dense matrix
1051  , bool SF // Symmetry flag
1052  , typename... CCAs > // Compile time column arguments
1053 template< typename MT2 // Type of the right-hand side matrix
1054  , bool SO2 > // Storage order of the right-hand side matrix
1055 inline auto Columns<MT,true,true,SF,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1056  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1057 {
1060 
1063  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1064 
1065  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1066 
1069 
1070  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1071  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1072  }
1073 
1074  if( IsRestricted_v<MT> ) {
1075  for( size_t j=0UL; j<columns(); ++j ) {
1076  if( !tryAddAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
1077  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1078  }
1079  }
1080  }
1081 
1082  decltype(auto) left( derestrict( *this ) );
1083 
1084  if( (~rhs).canAlias( &matrix_ ) ) {
1085  const AddType tmp( *this + (~rhs) );
1086  smpAssign( left, tmp );
1087  }
1088  else {
1089  smpAddAssign( left, ~rhs );
1090  }
1091 
1092  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1093 
1094  return *this;
1095 }
1097 //*************************************************************************************************
1098 
1099 
1100 //*************************************************************************************************
1114 template< typename MT // Type of the dense matrix
1115  , bool SF // Symmetry flag
1116  , typename... CCAs > // Compile time column arguments
1117 template< typename MT2 // Type of the right-hand side matrix
1118  , bool SO2 > // Storage order of the right-hand side matrix
1119 inline auto Columns<MT,true,true,SF,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1120  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1121 {
1124 
1127  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1128 
1129  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1130 
1133 
1134  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1135  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1136  }
1137 
1138  const AddType tmp( *this + (~rhs) );
1139 
1140  if( IsRestricted_v<MT> ) {
1141  for( size_t j=0UL; j<columns(); ++j ) {
1142  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1143  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1144  }
1145  }
1146  }
1147 
1148  decltype(auto) left( derestrict( *this ) );
1149 
1150  smpAssign( left, tmp );
1151 
1152  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1153 
1154  return *this;
1155 }
1157 //*************************************************************************************************
1158 
1159 
1160 //*************************************************************************************************
1174 template< typename MT // Type of the dense matrix
1175  , bool SF // Symmetry flag
1176  , typename... CCAs > // Compile time column arguments
1177 template< typename MT2 // Type of the right-hand side matrix
1178  , bool SO2 > // Storage order of the right-hand side matrix
1179 inline auto Columns<MT,true,true,SF,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1180  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1181 {
1184 
1187  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1188 
1189  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1190 
1193 
1194  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1195  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1196  }
1197 
1198  if( IsRestricted_v<MT> ) {
1199  for( size_t j=0UL; j<columns(); ++j ) {
1200  if( !trySubAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
1201  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1202  }
1203  }
1204  }
1205 
1206  decltype(auto) left( derestrict( *this ) );
1207 
1208  if( (~rhs).canAlias( &matrix_ ) ) {
1209  const SubType tmp( *this - (~rhs ) );
1210  smpAssign( left, tmp );
1211  }
1212  else {
1213  smpSubAssign( left, ~rhs );
1214  }
1215 
1216  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1217 
1218  return *this;
1219 }
1221 //*************************************************************************************************
1222 
1223 
1224 //*************************************************************************************************
1238 template< typename MT // Type of the dense matrix
1239  , bool SF // Symmetry flag
1240  , typename... CCAs > // Compile time column arguments
1241 template< typename MT2 // Type of the right-hand side matrix
1242  , bool SO2 > // Storage order of the right-hand side matrix
1243 inline auto Columns<MT,true,true,SF,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1244  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1245 {
1248 
1251  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1252 
1253  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1254 
1257 
1258  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1259  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1260  }
1261 
1262  const SubType tmp( *this - (~rhs) );
1263 
1264  if( IsRestricted_v<MT> ) {
1265  for( size_t j=0UL; j<columns(); ++j ) {
1266  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1267  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1268  }
1269  }
1270  }
1271 
1272  decltype(auto) left( derestrict( *this ) );
1273 
1274  smpAssign( left, tmp );
1275 
1276  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1277 
1278  return *this;
1279 }
1281 //*************************************************************************************************
1282 
1283 
1284 //*************************************************************************************************
1298 template< typename MT // Type of the dense matrix
1299  , bool SF // Symmetry flag
1300  , typename... CCAs > // Compile time column arguments
1301 template< typename MT2 // Type of the right-hand side matrix
1302  , bool SO2 > // Storage order of the right-hand side matrix
1303 inline auto Columns<MT,true,true,SF,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1304  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1305 {
1308 
1311  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1312 
1313  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1314 
1316 
1317  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1318  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1319  }
1320 
1321  if( IsRestricted_v<MT> ) {
1322  for( size_t j=0UL; j<columns(); ++j ) {
1323  if( !tryMultAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
1324  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1325  }
1326  }
1327  }
1328 
1329  decltype(auto) left( derestrict( *this ) );
1330 
1331  if( (~rhs).canAlias( &matrix_ ) ) {
1332  const SchurType tmp( *this % (~rhs) );
1333  if( IsSparseMatrix_v<SchurType> )
1334  reset();
1335  smpAssign( left, tmp );
1336  }
1337  else {
1338  smpSchurAssign( left, ~rhs );
1339  }
1340 
1341  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1342 
1343  return *this;
1344 }
1346 //*************************************************************************************************
1347 
1348 
1349 //*************************************************************************************************
1363 template< typename MT // Type of the dense matrix
1364  , bool SF // Symmetry flag
1365  , typename... CCAs > // Compile time column arguments
1366 template< typename MT2 // Type of the right-hand side matrix
1367  , bool SO2 > // Storage order of the right-hand side matrix
1368 inline auto Columns<MT,true,true,SF,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1369  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1370 {
1373 
1376  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
1377 
1378  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1379 
1381 
1382  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1383  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1384  }
1385 
1386  const SchurType tmp( *this % (~rhs) );
1387 
1388  if( IsRestricted_v<MT> ) {
1389  for( size_t j=0UL; j<columns(); ++j ) {
1390  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1391  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1392  }
1393  }
1394  }
1395 
1396  decltype(auto) left( derestrict( *this ) );
1397 
1398  if( IsSparseMatrix_v<SchurType> ) {
1399  reset();
1400  }
1401 
1402  smpAssign( left, tmp );
1403 
1404  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1405 
1406  return *this;
1407 }
1409 //*************************************************************************************************
1410 
1411 
1412 
1413 
1414 //=================================================================================================
1415 //
1416 // UTILITY FUNCTIONS
1417 //
1418 //=================================================================================================
1419 
1420 //*************************************************************************************************
1426 template< typename MT // Type of the dense matrix
1427  , bool SF // Symmetry flag
1428  , typename... CCAs > // Compile time column arguments
1429 inline MT& Columns<MT,true,true,SF,CCAs...>::operand() noexcept
1430 {
1431  return matrix_;
1432 }
1434 //*************************************************************************************************
1435 
1436 
1437 //*************************************************************************************************
1443 template< typename MT // Type of the dense matrix
1444  , bool SF // Symmetry flag
1445  , typename... CCAs > // Compile time column arguments
1446 inline const MT& Columns<MT,true,true,SF,CCAs...>::operand() const noexcept
1447 {
1448  return matrix_;
1449 }
1451 //*************************************************************************************************
1452 
1453 
1454 //*************************************************************************************************
1460 template< typename MT // Type of the dense matrix
1461  , bool SF // Symmetry flag
1462  , typename... CCAs > // Compile time column arguments
1463 inline size_t Columns<MT,true,true,SF,CCAs...>::rows() const noexcept
1464 {
1465  return matrix_.rows();
1466 }
1468 //*************************************************************************************************
1469 
1470 
1471 //*************************************************************************************************
1480 template< typename MT // Type of the dense matrix
1481  , bool SF // Symmetry flag
1482  , typename... CCAs > // Compile time column arguments
1483 inline size_t Columns<MT,true,true,SF,CCAs...>::spacing() const noexcept
1484 {
1485  return matrix_.spacing();
1486 }
1488 //*************************************************************************************************
1489 
1490 
1491 //*************************************************************************************************
1497 template< typename MT // Type of the dense matrix
1498  , bool SF // Symmetry flag
1499  , typename... CCAs > // Compile time column arguments
1500 inline size_t Columns<MT,true,true,SF,CCAs...>::capacity() const noexcept
1501 {
1502  return rows() * columns();
1503 }
1505 //*************************************************************************************************
1506 
1507 
1508 //*************************************************************************************************
1517 template< typename MT // Type of the dense matrix
1518  , bool SF // Symmetry flag
1519  , typename... CCAs > // Compile time column arguments
1520 inline size_t Columns<MT,true,true,SF,CCAs...>::capacity( size_t j ) const noexcept
1521 {
1522  MAYBE_UNUSED( j );
1523 
1524  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1525 
1526  return rows();
1527 }
1529 //*************************************************************************************************
1530 
1531 
1532 //*************************************************************************************************
1538 template< typename MT // Type of the dense matrix
1539  , bool SF // Symmetry flag
1540  , typename... CCAs > // Compile time column arguments
1541 inline size_t Columns<MT,true,true,SF,CCAs...>::nonZeros() const
1542 {
1543  size_t nonzeros( 0UL );
1544 
1545  for( size_t j=0UL; j<columns(); ++j ) {
1546  nonzeros += matrix_.nonZeros( idx(j) );
1547  }
1548 
1549  return nonzeros;
1550 }
1552 //*************************************************************************************************
1553 
1554 
1555 //*************************************************************************************************
1564 template< typename MT // Type of the dense matrix
1565  , bool SF // Symmetry flag
1566  , typename... CCAs > // Compile time column arguments
1567 inline size_t Columns<MT,true,true,SF,CCAs...>::nonZeros( size_t j ) const
1568 {
1569  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1570 
1571  return matrix_.nonZeros( idx(j) );
1572 }
1574 //*************************************************************************************************
1575 
1576 
1577 //*************************************************************************************************
1583 template< typename MT // Type of the dense matrix
1584  , bool SF // Symmetry flag
1585  , typename... CCAs > // Compile time column arguments
1587 {
1588  for( size_t j=0UL; j<columns(); ++j ) {
1589  matrix_.reset( idx(j) );
1590  }
1591 }
1593 //*************************************************************************************************
1594 
1595 
1596 //*************************************************************************************************
1605 template< typename MT // Type of the dense matrix
1606  , bool SF // Symmetry flag
1607  , typename... CCAs > // Compile time column arguments
1608 inline void Columns<MT,true,true,SF,CCAs...>::reset( size_t j )
1609 {
1610  matrix_.reset( idx(j) );
1611 }
1613 //*************************************************************************************************
1614 
1615 
1616 
1617 
1618 //=================================================================================================
1619 //
1620 // NUMERIC FUNCTIONS
1621 //
1622 //=================================================================================================
1623 
1624 //*************************************************************************************************
1637 template< typename MT // Type of the dense matrix
1638  , bool SF // Symmetry flag
1639  , typename... CCAs > // Compile time column arguments
1640 inline Columns<MT,true,true,SF,CCAs...>&
1642 {
1645 
1646  if( rows() != columns() ) {
1647  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1648  }
1649 
1650  const ResultType tmp( trans( *this ) );
1651 
1652  if( IsRestricted_v<MT> ) {
1653  for( size_t j=0UL; j<columns(); ++j ) {
1654  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
1655  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1656  }
1657  }
1658  }
1659 
1660  decltype(auto) left( derestrict( *this ) );
1661 
1662  smpAssign( left, tmp );
1663 
1664  return *this;
1665 }
1667 //*************************************************************************************************
1668 
1669 
1670 //*************************************************************************************************
1683 template< typename MT // Type of the dense matrix
1684  , bool SF // Symmetry flag
1685  , typename... CCAs > // Compile time column arguments
1686 inline Columns<MT,true,true,SF,CCAs...>&
1687  Columns<MT,true,true,SF,CCAs...>::ctranspose()
1688 {
1691 
1692  if( rows() != columns() ) {
1693  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1694  }
1695 
1696  const ResultType tmp( ctrans( *this ) );
1697 
1698  if( IsRestricted_v<MT> ) {
1699  for( size_t j=0UL; j<columns(); ++j ) {
1700  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
1701  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1702  }
1703  }
1704  }
1705 
1706  decltype(auto) left( derestrict( *this ) );
1707 
1708  smpAssign( left, tmp );
1709 
1710  return *this;
1711 }
1713 //*************************************************************************************************
1714 
1715 
1716 //*************************************************************************************************
1729 template< typename MT // Type of the dense matrix
1730  , bool SF // Symmetry flag
1731  , typename... CCAs > // Compile time column arguments
1732 template< typename Other > // Data type of the scalar value
1733 inline Columns<MT,true,true,SF,CCAs...>&
1734  Columns<MT,true,true,SF,CCAs...>::scale( const Other& scalar )
1735 {
1739 
1740  for( size_t j=0UL; j<columns(); ++j )
1741  {
1742  const size_t index ( idx(j) );
1743  const size_t ibegin( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index+1UL : index ) : 0UL );
1744  const size_t iend ( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index : index+1UL ) : rows() );
1745 
1746  for( size_t i=ibegin; i<iend; ++i ) {
1747  matrix_(i,index) *= scalar;
1748  }
1749  }
1750 
1751  return *this;
1752 }
1754 //*************************************************************************************************
1755 
1756 
1757 
1758 
1759 //=================================================================================================
1760 //
1761 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1762 //
1763 //=================================================================================================
1764 
1765 //*************************************************************************************************
1776 template< typename MT // Type of the dense matrix
1777  , bool SF // Symmetry flag
1778  , typename... CCAs > // Compile time column arguments
1779 template< typename Other > // Data type of the foreign expression
1780 inline bool Columns<MT,true,true,SF,CCAs...>::canAlias( const Other* alias ) const noexcept
1781 {
1782  return matrix_.isAliased( alias );
1783 }
1785 //*************************************************************************************************
1786 
1787 
1788 //*************************************************************************************************
1800 template< typename MT // Type of the dense matrix
1801  , bool SF // Symmetry flag
1802  , typename... CCAs > // Compile time column arguments
1803 template< typename MT2 // Data type of the foreign dense column selection
1804  , bool SO2 // Storage order of the foreign dense column selection
1805  , bool SF2 // Symmetry flag of the foreign dense column selection
1806  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
1807 inline bool
1808  Columns<MT,true,true,SF,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1809 {
1810  return matrix_.isAliased( &alias->matrix_ );
1811 }
1813 //*************************************************************************************************
1814 
1815 
1816 //*************************************************************************************************
1827 template< typename MT // Type of the dense matrix
1828  , bool SF // Symmetry flag
1829  , typename... CCAs > // Compile time column arguments
1830 template< typename Other > // Data type of the foreign expression
1831 inline bool Columns<MT,true,true,SF,CCAs...>::isAliased( const Other* alias ) const noexcept
1832 {
1833  return matrix_.isAliased( alias );
1834 }
1836 //*************************************************************************************************
1837 
1838 
1839 //*************************************************************************************************
1851 template< typename MT // Type of the dense matrix
1852  , bool SF // Symmetry flag
1853  , typename... CCAs > // Compile time column arguments
1854 template< typename MT2 // Data type of the foreign dense column selection
1855  , bool SO2 // Storage order of the foreign dense column selection
1856  , bool SF2 // Symmetry flag of the foreign dense column selection
1857  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
1858 inline bool
1859  Columns<MT,true,true,SF,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1860 {
1861  return matrix_.isAliased( &alias->matrix_ );
1862 }
1864 //*************************************************************************************************
1865 
1866 
1867 //*************************************************************************************************
1877 template< typename MT // Type of the dense matrix
1878  , bool SF // Symmetry flag
1879  , typename... CCAs > // Compile time column arguments
1880 inline bool Columns<MT,true,true,SF,CCAs...>::isAligned() const noexcept
1881 {
1882  return matrix_.isAligned();
1883 }
1885 //*************************************************************************************************
1886 
1887 
1888 //*************************************************************************************************
1899 template< typename MT // Type of the dense matrix
1900  , bool SF // Symmetry flag
1901  , typename... CCAs > // Compile time column arguments
1902 inline bool Columns<MT,true,true,SF,CCAs...>::canSMPAssign() const noexcept
1903 {
1904  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
1905 }
1907 //*************************************************************************************************
1908 
1909 
1910 //*************************************************************************************************
1925 template< typename MT // Type of the dense matrix
1926  , bool SF // Symmetry flag
1927  , typename... CCAs > // Compile time column arguments
1928 BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1929  Columns<MT,true,true,SF,CCAs...>::load( size_t i, size_t j ) const noexcept
1930 {
1931  return matrix_.load( i, idx(j) );
1932 }
1934 //*************************************************************************************************
1935 
1936 
1937 //*************************************************************************************************
1952 template< typename MT // Type of the dense matrix
1953  , bool SF // Symmetry flag
1954  , typename... CCAs > // Compile time column arguments
1955 BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1956  Columns<MT,true,true,SF,CCAs...>::loada( size_t i, size_t j ) const noexcept
1957 {
1958  return matrix_.loada( i, idx(j) );
1959 }
1961 //*************************************************************************************************
1962 
1963 
1964 //*************************************************************************************************
1979 template< typename MT // Type of the dense matrix
1980  , bool SF // Symmetry flag
1981  , typename... CCAs > // Compile time column arguments
1982 BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1983  Columns<MT,true,true,SF,CCAs...>::loadu( size_t i, size_t j ) const noexcept
1984 {
1985  return matrix_.loadu( i, idx(j) );
1986 }
1988 //*************************************************************************************************
1989 
1990 
1991 //*************************************************************************************************
2007 template< typename MT // Type of the dense matrix
2008  , bool SF // Symmetry flag
2009  , typename... CCAs > // Compile time column arguments
2011  Columns<MT,true,true,SF,CCAs...>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2012 {
2013  matrix_.store( i, idx(j), value );
2014 }
2016 //*************************************************************************************************
2017 
2018 
2019 //*************************************************************************************************
2035 template< typename MT // Type of the dense matrix
2036  , bool SF // Symmetry flag
2037  , typename... CCAs > // Compile time column arguments
2039  Columns<MT,true,true,SF,CCAs...>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2040 {
2041  matrix_.storea( i, idx(j), value );
2042 }
2044 //*************************************************************************************************
2045 
2046 
2047 //*************************************************************************************************
2063 template< typename MT // Type of the dense matrix
2064  , bool SF // Symmetry flag
2065  , typename... CCAs > // Compile time column arguments
2067  Columns<MT,true,true,SF,CCAs...>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2068 {
2069  matrix_.storeu( i, idx(j), value );
2070 }
2072 //*************************************************************************************************
2073 
2074 
2075 //*************************************************************************************************
2091 template< typename MT // Type of the dense matrix
2092  , bool SF // Symmetry flag
2093  , typename... CCAs > // Compile time column arguments
2095  Columns<MT,true,true,SF,CCAs...>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2096 {
2097  matrix_.stream( i, idx(j), value );
2098 }
2100 //*************************************************************************************************
2101 
2102 
2103 //*************************************************************************************************
2115 template< typename MT // Type of the dense matrix
2116  , bool SF // Symmetry flag
2117  , typename... CCAs > // Compile time column arguments
2118 template< typename MT2 > // Type of the right-hand side dense matrix
2119 inline auto Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2120  -> DisableIf_t< VectorizedAssign_v<MT2> >
2121 {
2124 
2125  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2126  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2127 
2128  const size_t ipos( rows() & size_t(-2) );
2129  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2130 
2131  for( size_t j=0UL; j<columns(); ++j ) {
2132  const size_t index( idx(j) );
2133  for( size_t i=0UL; i<ipos; i+=2UL ) {
2134  matrix_(i ,index) = (~rhs)(i ,j);
2135  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
2136  }
2137  if( ipos < rows() ) {
2138  matrix_(ipos,index) = (~rhs)(ipos,j);
2139  }
2140  }
2141 }
2143 //*************************************************************************************************
2144 
2145 
2146 //*************************************************************************************************
2158 template< typename MT // Type of the dense matrix
2159  , bool SF // Symmetry flag
2160  , typename... CCAs > // Compile time column arguments
2161 template< typename MT2 > // Type of the right-hand side dense matrix
2162 inline auto Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2163  -> EnableIf_t< VectorizedAssign_v<MT2> >
2164 {
2167 
2169 
2170  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2171  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2172 
2173  const size_t ipos( rows() & size_t(-SIMDSIZE) );
2174  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2175 
2176  if( useStreaming &&
2177  rows()*columns() > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2178  !(~rhs).isAliased( &matrix_ ) )
2179  {
2180  for( size_t j=0UL; j<columns(); ++j )
2181  {
2182  size_t i( 0UL );
2183  Iterator left( begin(j) );
2184  ConstIterator_t<MT2> right( (~rhs).begin(j) );
2185 
2186  for( ; i<ipos; i+=SIMDSIZE ) {
2187  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2188  }
2189  for( ; i<rows(); ++i ) {
2190  *left = *right;
2191  }
2192  }
2193  }
2194  else
2195  {
2196  for( size_t j=0UL; j<columns(); ++j )
2197  {
2198  size_t i( 0UL );
2199  Iterator left( begin(j) );
2200  ConstIterator_t<MT2> right( (~rhs).begin(j) );
2201 
2202  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2203  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2204  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2205  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2206  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2207  }
2208  for( ; i<ipos; i+=SIMDSIZE ) {
2209  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2210  }
2211  for( ; i<rows(); ++i ) {
2212  *left = *right; ++left; ++right;
2213  }
2214  }
2215  }
2216 }
2218 //*************************************************************************************************
2219 
2220 
2221 //*************************************************************************************************
2233 template< typename MT // Type of the dense matrix
2234  , bool SF // Symmetry flag
2235  , typename... CCAs > // Compile time column arguments
2236 template< typename MT2 > // Type of the right-hand side dense matrix
2237 inline void Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2238 {
2241 
2243 
2244  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2245  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2246 
2247  constexpr size_t block( BLOCK_SIZE );
2248 
2249  if( rows() < block && columns() < block )
2250  {
2251  const size_t ipos( (~rhs).rows() & size_t(-2) );
2252  for( size_t j=0UL; j<columns(); ++j ) {
2253  const size_t index( idx(j) );
2254  for( size_t i=0UL; i<ipos; i+=2UL ) {
2255  matrix_(i ,index) = (~rhs)(i ,j);
2256  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
2257  }
2258  if( ipos < (~rhs).rows() ) {
2259  matrix_(ipos,index) = (~rhs)(ipos,j);
2260  }
2261  }
2262  }
2263  else
2264  {
2265  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2266  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2267  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2268  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2269  for( size_t j=jj; j<jend; ++j ) {
2270  const size_t index( idx(j) );
2271  for( size_t i=ii; i<iend; ++i ) {
2272  matrix_(i,index) = (~rhs)(i,j);
2273  }
2274  }
2275  }
2276  }
2277  }
2278 }
2280 //*************************************************************************************************
2281 
2282 
2283 //*************************************************************************************************
2295 template< typename MT // Type of the dense matrix
2296  , bool SF // Symmetry flag
2297  , typename... CCAs > // Compile time column arguments
2298 template< typename MT2 > // Type of the right-hand side sparse matrix
2299 inline void Columns<MT,true,true,SF,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2300 {
2303 
2304  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2305  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2306 
2307  for( size_t j=0UL; j<columns(); ++j ) {
2308  const size_t index( idx(j) );
2309  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2310  matrix_(element->index(),index) = element->value();
2311  }
2312 }
2314 //*************************************************************************************************
2315 
2316 
2317 //*************************************************************************************************
2329 template< typename MT // Type of the dense matrix
2330  , bool SF // Symmetry flag
2331  , typename... CCAs > // Compile time column arguments
2332 template< typename MT2 > // Type of the right-hand side sparse matrix
2333 inline void Columns<MT,true,true,SF,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2334 {
2337 
2339 
2340  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2341  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2342 
2343  for( size_t i=0UL; i<rows(); ++i ) {
2344  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2345  matrix_(i,idx(element->index())) = element->value();
2346  }
2347 }
2349 //*************************************************************************************************
2350 
2351 
2352 //*************************************************************************************************
2364 template< typename MT // Type of the dense matrix
2365  , bool SF // Symmetry flag
2366  , typename... CCAs > // Compile time column arguments
2367 template< typename MT2 > // Type of the right-hand side dense matrix
2368 inline auto Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2369  -> DisableIf_t< VectorizedAddAssign_v<MT2> >
2370 {
2373 
2374  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2375  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2376 
2377  const size_t ipos( rows() & size_t(-2) );
2378  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2379 
2380  for( size_t j=0UL; j<columns(); ++j )
2381  {
2382  const size_t index( idx(j) );
2383  if( IsDiagonal_v<MT2> ) {
2384  matrix_(j,index) += (~rhs)(j,j);
2385  }
2386  else {
2387  for( size_t i=0UL; i<ipos; i+=2UL ) {
2388  matrix_(i ,index) += (~rhs)(i ,j);
2389  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
2390  }
2391  if( ipos < rows() ) {
2392  matrix_(ipos,index) += (~rhs)(ipos,j);
2393  }
2394  }
2395  }
2396 }
2398 //*************************************************************************************************
2399 
2400 
2401 //*************************************************************************************************
2413 template< typename MT // Type of the dense matrix
2414  , bool SF // Symmetry flag
2415  , typename... CCAs > // Compile time column arguments
2416 template< typename MT2 > // Type of the right-hand side dense matrix
2417 inline auto Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2418  -> EnableIf_t< VectorizedAddAssign_v<MT2> >
2419 {
2422 
2424 
2425  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2426  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2427 
2428  for( size_t j=0UL; j<columns(); ++j )
2429  {
2430  const size_t ibegin( ( IsLower_v<MT2> )
2431  ?( ( IsStrictlyLower_v<MT2> ? j+1UL : j ) & size_t(-SIMDSIZE) )
2432  :( 0UL ) );
2433  const size_t iend ( ( IsUpper_v<MT2> )
2434  ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
2435  :( rows() ) );
2436  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
2437 
2438  const size_t ipos( iend & size_t(-SIMDSIZE) );
2439  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2440 
2441  size_t i( ibegin );
2442  Iterator left( begin(j) + ibegin );
2443  ConstIterator_t<MT2> right( (~rhs).begin(j) + ibegin );
2444 
2445  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2446  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2447  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2448  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2449  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2450  }
2451  for( ; i<ipos; i+=SIMDSIZE ) {
2452  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2453  }
2454  for( ; i<iend; ++i ) {
2455  *left += *right; ++left; ++right;
2456  }
2457  }
2458 }
2460 //*************************************************************************************************
2461 
2462 
2463 //*************************************************************************************************
2475 template< typename MT // Type of the dense matrix
2476  , bool SF // Symmetry flag
2477  , typename... CCAs > // Compile time column arguments
2478 template< typename MT2 > // Type of the right-hand side dense matrix
2479 inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2480 {
2483 
2485 
2486  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2487  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2488 
2489  constexpr size_t block( BLOCK_SIZE );
2490 
2491  if( rows() < block && columns() < block )
2492  {
2493  const size_t ipos( (~rhs).rows() & size_t(-2) );
2494  for( size_t j=0UL; j<columns(); ++j ) {
2495  const size_t index( idx(j) );
2496  for( size_t i=0UL; i<ipos; i+=2UL ) {
2497  matrix_(i ,index) += (~rhs)(i ,j);
2498  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
2499  }
2500  if( ipos < (~rhs).rows() )
2501  matrix_(ipos,index) += (~rhs)(ipos,j);
2502  }
2503  }
2504  else
2505  {
2506  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2507  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2508  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2509  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2510  for( size_t j=jj; j<jend; ++j ) {
2511  const size_t index( idx(j) );
2512  for( size_t i=ii; i<iend; ++i ) {
2513  matrix_(i,index) += (~rhs)(i,j);
2514  }
2515  }
2516  }
2517  }
2518  }
2519 }
2521 //*************************************************************************************************
2522 
2523 
2524 //*************************************************************************************************
2536 template< typename MT // Type of the dense matrix
2537  , bool SF // Symmetry flag
2538  , typename... CCAs > // Compile time column arguments
2539 template< typename MT2 > // Type of the right-hand side sparse matrix
2540 inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
2541 {
2544 
2545  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2546  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2547 
2548  for( size_t j=0UL; j<columns(); ++j ) {
2549  const size_t index( idx(j) );
2550  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2551  matrix_(element->index(),index) += element->value();
2552  }
2553 }
2555 //*************************************************************************************************
2556 
2557 
2558 //*************************************************************************************************
2570 template< typename MT // Type of the dense matrix
2571  , bool SF // Symmetry flag
2572  , typename... CCAs > // Compile time column arguments
2573 template< typename MT2 > // Type of the right-hand side sparse matrix
2574 inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
2575 {
2578 
2580 
2581  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2582  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2583 
2584  for( size_t i=0UL; i<rows(); ++i ) {
2585  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2586  matrix_(i,idx(element->index())) += element->value();
2587  }
2588 }
2590 //*************************************************************************************************
2591 
2592 
2593 //*************************************************************************************************
2605 template< typename MT // Type of the dense matrix
2606  , bool SF // Symmetry flag
2607  , typename... CCAs > // Compile time column arguments
2608 template< typename MT2 > // Type of the right-hand side dense matrix
2609 inline auto Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2610  -> DisableIf_t< VectorizedSubAssign_v<MT2> >
2611 {
2614 
2615  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2616  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2617 
2618  const size_t ipos( rows() & size_t(-2) );
2619  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2620 
2621  for( size_t j=0UL; j<columns(); ++j )
2622  {
2623  const size_t index( idx(j) );
2624 
2625  if( IsDiagonal_v<MT2> ) {
2626  matrix_(j,index) -= (~rhs)(j,j);
2627  }
2628  else {
2629  for( size_t i=0UL; i<ipos; i+=2UL ) {
2630  matrix_(i ,index) -= (~rhs)(i ,j);
2631  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
2632  }
2633  if( ipos < rows() ) {
2634  matrix_(ipos,index) -= (~rhs)(ipos,j);
2635  }
2636  }
2637  }
2638 }
2640 //*************************************************************************************************
2641 
2642 
2643 //*************************************************************************************************
2655 template< typename MT // Type of the dense matrix
2656  , bool SF // Symmetry flag
2657  , typename... CCAs > // Compile time column arguments
2658 template< typename MT2 > // Type of the right-hand side dense matrix
2659 inline auto Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2660  -> EnableIf_t< VectorizedSubAssign_v<MT2> >
2661 {
2664 
2666 
2667  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2668  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2669 
2670  for( size_t j=0UL; j<columns(); ++j )
2671  {
2672  const size_t ibegin( ( IsLower_v<MT2> )
2673  ?( ( IsStrictlyLower_v<MT2> ? j+1UL : j ) & size_t(-SIMDSIZE) )
2674  :( 0UL ) );
2675  const size_t iend ( ( IsUpper_v<MT2> )
2676  ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
2677  :( rows() ) );
2678  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
2679 
2680  const size_t ipos( iend & size_t(-SIMDSIZE) );
2681  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2682 
2683  size_t i( ibegin );
2684  Iterator left( begin(j) + ibegin );
2685  ConstIterator_t<MT2> right( (~rhs).begin(j) + ibegin );
2686 
2687  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2688  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2689  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2690  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2691  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2692  }
2693  for( ; i<ipos; i+=SIMDSIZE ) {
2694  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2695  }
2696  for( ; i<iend; ++i ) {
2697  *left -= *right; ++left; ++right;
2698  }
2699  }
2700 }
2702 //*************************************************************************************************
2703 
2704 
2705 //*************************************************************************************************
2717 template< typename MT // Type of the dense matrix
2718  , bool SF // Symmetry flag
2719  , typename... CCAs > // Compile time column arguments
2720 template< typename MT2 > // Type of the right-hand side dense matrix
2721 inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2722 {
2725 
2727 
2728  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2729  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2730 
2731  constexpr size_t block( BLOCK_SIZE );
2732 
2733  if( rows() < block && columns() < block )
2734  {
2735  const size_t ipos( (~rhs).rows() & size_t(-2) );
2736  for( size_t j=0UL; j<columns(); ++j ) {
2737  const size_t index( idx(j) );
2738  for( size_t i=0UL; i<ipos; i+=2UL ) {
2739  matrix_(i ,index) -= (~rhs)(i ,j);
2740  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
2741  }
2742  if( ipos < (~rhs).rows() )
2743  matrix_(ipos,index) -= (~rhs)(ipos,j);
2744  }
2745  }
2746  else
2747  {
2748  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2749  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2750  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2751  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2752  for( size_t j=jj; j<jend; ++j ) {
2753  const size_t index( idx(j) );
2754  for( size_t i=ii; i<iend; ++i ) {
2755  matrix_(i,index) -= (~rhs)(i,j);
2756  }
2757  }
2758  }
2759  }
2760  }
2761 }
2763 //*************************************************************************************************
2764 
2765 
2766 //*************************************************************************************************
2778 template< typename MT // Type of the dense matrix
2779  , bool SF // Symmetry flag
2780  , typename... CCAs > // Compile time column arguments
2781 template< typename MT2 > // Type of the right-hand side sparse matrix
2782 inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
2783 {
2786 
2787  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2788  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2789 
2790  for( size_t j=0UL; j<columns(); ++j ) {
2791  const size_t index( idx(j) );
2792  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2793  matrix_(element->index(),index) -= element->value();
2794  }
2795 }
2797 //*************************************************************************************************
2798 
2799 
2800 //*************************************************************************************************
2812 template< typename MT // Type of the dense matrix
2813  , bool SF // Symmetry flag
2814  , typename... CCAs > // Compile time column arguments
2815 template< typename MT2 > // Type of the right-hand side sparse matrix
2816 inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
2817 {
2820 
2822 
2823  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2824  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2825 
2826  for( size_t i=0UL; i<rows(); ++i ) {
2827  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2828  matrix_(i,idx(element->index())) -= element->value();
2829  }
2830 }
2832 //*************************************************************************************************
2833 
2834 
2835 //*************************************************************************************************
2847 template< typename MT // Type of the dense matrix
2848  , bool SF // Symmetry flag
2849  , typename... CCAs > // Compile time column arguments
2850 template< typename MT2 > // Type of the right-hand side dense matrix
2851 inline auto Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2852  -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
2853 {
2856 
2857  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2858  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2859 
2860  const size_t ipos( rows() & size_t(-2) );
2861  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2862 
2863  for( size_t j=0UL; j<columns(); ++j ) {
2864  const size_t index( idx(j) );
2865  for( size_t i=0UL; i<ipos; i+=2UL ) {
2866  matrix_(i ,index) *= (~rhs)(i ,j);
2867  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
2868  }
2869  if( ipos < rows() ) {
2870  matrix_(ipos,index) *= (~rhs)(ipos,j);
2871  }
2872  }
2873 }
2875 //*************************************************************************************************
2876 
2877 
2878 //*************************************************************************************************
2891 template< typename MT // Type of the dense matrix
2892  , bool SF // Symmetry flag
2893  , typename... CCAs > // Compile time column arguments
2894 template< typename MT2 > // Type of the right-hand side dense matrix
2895 inline auto Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2896  -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
2897 {
2900 
2902 
2903  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2904  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2905 
2906  for( size_t j=0UL; j<columns(); ++j )
2907  {
2908  const size_t ipos( rows() & size_t(-SIMDSIZE) );
2909  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2910 
2911  size_t i( 0UL );
2912  Iterator left( begin(j) );
2913  ConstIterator_t<MT2> right( (~rhs).begin(j) );
2914 
2915  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2916  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2917  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2918  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2919  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2920  }
2921  for( ; i<ipos; i+=SIMDSIZE ) {
2922  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2923  }
2924  for( ; i<rows(); ++i ) {
2925  *left *= *right; ++left; ++right;
2926  }
2927  }
2928 }
2930 //*************************************************************************************************
2931 
2932 
2933 //*************************************************************************************************
2945 template< typename MT // Type of the dense matrix
2946  , bool SF // Symmetry flag
2947  , typename... CCAs > // Compile time column arguments
2948 template< typename MT2 > // Type of the right-hand side dense matrix
2949 inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2950 {
2953 
2955 
2956  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2957  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2958 
2959  constexpr size_t block( BLOCK_SIZE );
2960 
2961  if( rows() < block && columns() < block )
2962  {
2963  const size_t ipos( (~rhs).rows() & size_t(-2) );
2964  for( size_t j=0UL; j<columns(); ++j ) {
2965  const size_t index( idx(j) );
2966  for( size_t i=0UL; i<ipos; i+=2UL ) {
2967  matrix_(i ,index) *= (~rhs)(i ,j);
2968  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
2969  }
2970  if( ipos < (~rhs).rows() )
2971  matrix_(ipos,index) *= (~rhs)(ipos,j);
2972  }
2973  }
2974  else
2975  {
2976  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2977  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2978  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2979  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2980  for( size_t j=jj; j<jend; ++j ) {
2981  const size_t index( idx(j) );
2982  for( size_t i=ii; i<iend; ++i ) {
2983  matrix_(i,index) *= (~rhs)(i,j);
2984  }
2985  }
2986  }
2987  }
2988  }
2989 }
2991 //*************************************************************************************************
2992 
2993 
2994 //*************************************************************************************************
3006 template< typename MT // Type of the dense matrix
3007  , bool SF // Symmetry flag
3008  , typename... CCAs > // Compile time column arguments
3009 template< typename MT2 > // Type of the right-hand side sparse matrix
3010 inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
3011 {
3014 
3015  using blaze::reset;
3016 
3017  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3018  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3019 
3020  for( size_t j=0UL; j<columns(); ++j )
3021  {
3022  const size_t index( idx(j) );
3023  size_t i( 0UL );
3024 
3025  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
3026  for( ; i<element->index(); ++i )
3027  reset( matrix_(i,index) );
3028  matrix_(i,index) *= element->value();
3029  ++i;
3030  }
3031 
3032  for( ; i<rows(); ++i ) {
3033  reset( matrix_(i,index) );
3034  }
3035  }
3036 }
3038 //*************************************************************************************************
3039 
3040 
3041 //*************************************************************************************************
3053 template< typename MT // Type of the dense matrix
3054  , bool SF // Symmetry flag
3055  , typename... CCAs > // Compile time column arguments
3056 template< typename MT2 > // Type of the right-hand side sparse matrix
3057 inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
3058 {
3061 
3062  using blaze::reset;
3063 
3065 
3066  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3067  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3068 
3069  for( size_t i=0UL; i<rows(); ++i )
3070  {
3071  size_t j( 0UL );
3072 
3073  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
3074  for( ; j<element->index(); ++j )
3075  reset( matrix_(i,idx(j)) );
3076  matrix_(i,idx(j)) *= element->value();
3077  ++j;
3078  }
3079 
3080  for( ; j<columns(); ++j ) {
3081  reset( matrix_(i,idx(j)) );
3082  }
3083  }
3084 }
3086 //*************************************************************************************************
3087 
3088 
3089 
3090 
3091 
3092 
3093 
3094 
3095 //=================================================================================================
3096 //
3097 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
3098 //
3099 //=================================================================================================
3100 
3101 //*************************************************************************************************
3109 template< typename MT // Type of the dense matrix
3110  , typename... CCAs > // Compile time column arguments
3111 class Columns<MT,false,true,false,CCAs...>
3112  : public View< DenseMatrix< Columns<MT,false,true,false,CCAs...>, true > >
3113  , private ColumnsData<CCAs...>
3114 {
3115  private:
3116  //**Type definitions****************************************************************************
3117  using DataType = ColumnsData<CCAs...>;
3118  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
3119  //**********************************************************************************************
3120 
3121  //**Compile time flags**************************************************************************
3122  static constexpr size_t N = sizeof...( CCAs );
3123  //**********************************************************************************************
3124 
3125  //**********************************************************************************************
3127  template< typename MT1, typename MT2 >
3128  static constexpr bool EnforceEvaluation_v =
3129  ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
3130  //**********************************************************************************************
3131 
3132  public:
3133  //**Type definitions****************************************************************************
3135  using This = Columns<MT,false,true,false,CCAs...>;
3136 
3137  using BaseType = DenseMatrix<This,true>;
3138  using ViewedType = MT;
3139  using ResultType = ColumnsTrait_t<MT,N>;
3140  using OppositeType = OppositeType_t<ResultType>;
3141  using TransposeType = TransposeType_t<ResultType>;
3142  using ElementType = ElementType_t<MT>;
3143  using ReturnType = ReturnType_t<MT>;
3144  using CompositeType = const Columns&;
3145 
3147  using ConstReference = ConstReference_t<MT>;
3148 
3150  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
3151 
3153  using ConstPointer = ConstPointer_t<MT>;
3154 
3156  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
3157  //**********************************************************************************************
3158 
3159  //**ColumnsIterator class definition************************************************************
3162  template< typename MatrixType // Type of the dense matrix
3163  , typename IteratorType > // Type of the dense matrix iterator
3164  class ColumnsIterator
3165  {
3166  public:
3167  //**Type definitions*************************************************************************
3169  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
3170 
3172  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
3173 
3175  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
3176 
3178  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
3179 
3181  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
3182 
3183  // STL iterator requirements
3184  using iterator_category = IteratorCategory;
3185  using value_type = ValueType;
3186  using pointer = PointerType;
3187  using reference = ReferenceType;
3188  using difference_type = DifferenceType;
3189  //*******************************************************************************************
3190 
3191  //**Constructor******************************************************************************
3194  inline ColumnsIterator() noexcept
3195  : matrix_( nullptr ) // The dense matrix containing the column
3196  , row_ ( 0UL ) // The current row index
3197  , column_( 0UL ) // The current column index
3198  , pos_ ( ) // Iterator to the current dense element
3199  {}
3200  //*******************************************************************************************
3201 
3202  //**Constructor******************************************************************************
3209  inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
3210  : matrix_( &matrix ) // The dense matrix containing the selected column
3211  , row_ ( row ) // The current row index
3212  , column_( column ) // The current column index
3213  , pos_ ( ) // Iterator to the current dense element
3214  {
3215  if( row_ != matrix_->rows() )
3216  pos_ = matrix_->begin( row_ ) + column_;
3217  }
3218  //*******************************************************************************************
3219 
3220  //**Constructor******************************************************************************
3225  template< typename MatrixType2, typename IteratorType2 >
3226  inline ColumnsIterator( const ColumnsIterator<MatrixType2,IteratorType2>& it ) noexcept
3227  : matrix_( it.matrix_ ) // The dense matrix containing the seleted column
3228  , row_ ( it.row_ ) // The current row index
3229  , column_( it.column_ ) // The current column index
3230  , pos_ ( it.pos_ ) // Iterator to the current dense element
3231  {}
3232  //*******************************************************************************************
3233 
3234  //**Addition assignment operator*************************************************************
3240  inline ColumnsIterator& operator+=( size_t inc ) noexcept {
3241  using blaze::reset;
3242  row_ += inc;
3243  if( row_ != matrix_->rows() )
3244  pos_ = matrix_->begin( row_ ) + column_;
3245  else reset( pos_ );
3246  return *this;
3247  }
3248  //*******************************************************************************************
3249 
3250  //**Subtraction assignment operator**********************************************************
3256  inline ColumnsIterator& operator-=( size_t dec ) noexcept {
3257  using blaze::reset;
3258  row_ -= dec;
3259  if( row_ != matrix_->rows() )
3260  pos_ = matrix_->begin( row_ ) + column_;
3261  else reset( pos_ );
3262  return *this;
3263  }
3264  //*******************************************************************************************
3265 
3266  //**Prefix increment operator****************************************************************
3271  inline ColumnsIterator& operator++() noexcept {
3272  using blaze::reset;
3273  ++row_;
3274  if( row_ != matrix_->rows() )
3275  pos_ = matrix_->begin( row_ ) + column_;
3276  else reset( pos_ );
3277  return *this;
3278  }
3279  //*******************************************************************************************
3280 
3281  //**Postfix increment operator***************************************************************
3286  inline const ColumnsIterator operator++( int ) noexcept {
3287  const ColumnsIterator tmp( *this );
3288  ++(*this);
3289  return tmp;
3290  }
3291  //*******************************************************************************************
3292 
3293  //**Prefix decrement operator****************************************************************
3298  inline ColumnsIterator& operator--() noexcept {
3299  using blaze::reset;
3300  --row_;
3301  if( row_ != matrix_->rows() )
3302  pos_ = matrix_->begin( row_ ) + column_;
3303  else reset( pos_ );
3304  return *this;
3305  }
3306  //*******************************************************************************************
3307 
3308  //**Postfix decrement operator***************************************************************
3313  inline const ColumnsIterator operator--( int ) noexcept {
3314  const ColumnsIterator tmp( *this );
3315  --(*this);
3316  return tmp;
3317  }
3318  //*******************************************************************************************
3319 
3320  //**Subscript operator***********************************************************************
3326  inline ReferenceType operator[]( size_t index ) const {
3327  BLAZE_USER_ASSERT( row_+index < matrix_->rows(), "Invalid access index detected" );
3328  const IteratorType pos( matrix_->begin( row_+index ) + column_ );
3329  return *pos;
3330  }
3331  //*******************************************************************************************
3332 
3333  //**Element access operator******************************************************************
3338  inline ReferenceType operator*() const {
3339  return *pos_;
3340  }
3341  //*******************************************************************************************
3342 
3343  //**Element access operator******************************************************************
3348  inline PointerType operator->() const {
3349  return pos_;
3350  }
3351  //*******************************************************************************************
3352 
3353  //**Equality operator************************************************************************
3359  template< typename MatrixType2, typename IteratorType2 >
3360  inline bool operator==( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3361  return row_ == rhs.row_;
3362  }
3363  //*******************************************************************************************
3364 
3365  //**Inequality operator**********************************************************************
3371  template< typename MatrixType2, typename IteratorType2 >
3372  inline bool operator!=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3373  return !( *this == rhs );
3374  }
3375  //*******************************************************************************************
3376 
3377  //**Less-than operator***********************************************************************
3383  template< typename MatrixType2, typename IteratorType2 >
3384  inline bool operator<( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3385  return row_ < rhs.row_;
3386  }
3387  //*******************************************************************************************
3388 
3389  //**Greater-than operator********************************************************************
3395  template< typename MatrixType2, typename IteratorType2 >
3396  inline bool operator>( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3397  return row_ > rhs.row_;
3398  }
3399  //*******************************************************************************************
3400 
3401  //**Less-or-equal-than operator**************************************************************
3407  template< typename MatrixType2, typename IteratorType2 >
3408  inline bool operator<=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3409  return row_ <= rhs.row_;
3410  }
3411  //*******************************************************************************************
3412 
3413  //**Greater-or-equal-than operator***********************************************************
3419  template< typename MatrixType2, typename IteratorType2 >
3420  inline bool operator>=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3421  return row_ >= rhs.row_;
3422  }
3423  //*******************************************************************************************
3424 
3425  //**Subtraction operator*********************************************************************
3431  inline DifferenceType operator-( const ColumnsIterator& rhs ) const noexcept {
3432  return row_ - rhs.row_;
3433  }
3434  //*******************************************************************************************
3435 
3436  //**Addition operator************************************************************************
3443  friend inline const ColumnsIterator operator+( const ColumnsIterator& it, size_t inc ) noexcept {
3444  return ColumnsIterator( *it.matrix_, it.row_+inc, it.column_ );
3445  }
3446  //*******************************************************************************************
3447 
3448  //**Addition operator************************************************************************
3455  friend inline const ColumnsIterator operator+( size_t inc, const ColumnsIterator& it ) noexcept {
3456  return ColumnsIterator( *it.matrix_, it.row_+inc, it.column_ );
3457  }
3458  //*******************************************************************************************
3459 
3460  //**Subtraction operator*********************************************************************
3467  friend inline const ColumnsIterator operator-( const ColumnsIterator& it, size_t dec ) noexcept {
3468  return ColumnsIterator( *it.matrix_, it.row_-dec, it.column_ );
3469  }
3470  //*******************************************************************************************
3471 
3472  private:
3473  //**Member variables*************************************************************************
3474  MatrixType* matrix_;
3475  size_t row_;
3476  size_t column_;
3477  IteratorType pos_;
3478  //*******************************************************************************************
3479 
3480  //**Friend declarations**********************************************************************
3481  template< typename MatrixType2, typename IteratorType2 > friend class ColumnsIterator;
3482  //*******************************************************************************************
3483  };
3484  //**********************************************************************************************
3485 
3486  //**Type definitions****************************************************************************
3488  using ConstIterator = ColumnsIterator< const MT, ConstIterator_t<MT> >;
3489 
3491  using Iterator = If_t< IsConst_v<MT>, ConstIterator, ColumnsIterator< MT, Iterator_t<MT> > >;
3492  //**********************************************************************************************
3493 
3494  //**Compilation flags***************************************************************************
3496  static constexpr bool simdEnabled = false;
3497 
3499  static constexpr bool smpAssignable = MT::smpAssignable;
3500 
3502  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
3503  //**********************************************************************************************
3504 
3505  //**Constructors********************************************************************************
3508  template< typename... RCAs >
3509  explicit inline Columns( MT& matrix, RCAs... args );
3510 
3511  Columns( const Columns& ) = default;
3512  Columns( Columns&& ) = default;
3514  //**********************************************************************************************
3515 
3516  //**Destructor**********************************************************************************
3519  ~Columns() = default;
3521  //**********************************************************************************************
3522 
3523  //**Data access functions***********************************************************************
3526  inline Reference operator()( size_t i, size_t j );
3527  inline ConstReference operator()( size_t i, size_t j ) const;
3528  inline Reference at( size_t i, size_t j );
3529  inline ConstReference at( size_t i, size_t j ) const;
3530  inline Pointer data () noexcept;
3531  inline ConstPointer data () const noexcept;
3532  inline Pointer data ( size_t j ) noexcept;
3533  inline ConstPointer data ( size_t j ) const noexcept;
3534  inline Iterator begin ( size_t j );
3535  inline ConstIterator begin ( size_t j ) const;
3536  inline ConstIterator cbegin( size_t j ) const;
3537  inline Iterator end ( size_t j );
3538  inline ConstIterator end ( size_t j ) const;
3539  inline ConstIterator cend ( size_t j ) const;
3541  //**********************************************************************************************
3542 
3543  //**Assignment operators************************************************************************
3546  inline Columns& operator=( const ElementType& rhs );
3547  inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
3548  inline Columns& operator=( const Columns& rhs );
3549 
3550  template< typename MT2, bool SO2 >
3551  inline Columns& operator=( const Matrix<MT2,SO2>& rhs );
3552 
3553  template< typename MT2, bool SO2 >
3554  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3555  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3556 
3557  template< typename MT2, bool SO2 >
3558  inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3559  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3560 
3561  template< typename MT2, bool SO2 >
3562  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3563  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3564 
3565  template< typename MT2, bool SO2 >
3566  inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3567  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3568 
3569  template< typename MT2, bool SO2 >
3570  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3571  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3572 
3573  template< typename MT2, bool SO2 >
3574  inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3575  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3577  //**********************************************************************************************
3578 
3579  //**Utility functions***************************************************************************
3582  using DataType::idx;
3583  using DataType::idces;
3584  using DataType::columns;
3585 
3586  inline MT& operand() noexcept;
3587  inline const MT& operand() const noexcept;
3588 
3589  inline size_t rows() const noexcept;
3590  inline size_t spacing() const noexcept;
3591  inline size_t capacity() const noexcept;
3592  inline size_t capacity( size_t j ) const noexcept;
3593  inline size_t nonZeros() const;
3594  inline size_t nonZeros( size_t j ) const;
3595  inline void reset();
3596  inline void reset( size_t j );
3598  //**********************************************************************************************
3599 
3600  //**Numeric functions***************************************************************************
3603  inline Columns& transpose();
3604  inline Columns& ctranspose();
3605 
3606  template< typename Other > inline Columns& scale( const Other& scalar );
3608  //**********************************************************************************************
3609 
3610  //**Expression template evaluation functions****************************************************
3613  template< typename Other >
3614  inline bool canAlias( const Other* alias ) const noexcept;
3615 
3616  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
3617  inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
3618 
3619  template< typename Other >
3620  inline bool isAliased( const Other* alias ) const noexcept;
3621 
3622  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
3623  inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
3624 
3625  inline bool isAligned () const noexcept;
3626  inline bool canSMPAssign() const noexcept;
3627 
3628  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
3629  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3630  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3631  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3632 
3633  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
3634  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3635  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3636  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3637 
3638  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
3639  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3640  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3641  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3642 
3643  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
3644  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
3645  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
3646  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
3648  //**********************************************************************************************
3649 
3650  private:
3651  //**Member variables****************************************************************************
3654  Operand matrix_;
3655 
3656  //**********************************************************************************************
3657 
3658  //**Friend declarations*************************************************************************
3659  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
3660  //**********************************************************************************************
3661 
3662  //**Compile time checks*************************************************************************
3672  //**********************************************************************************************
3673 };
3675 //*************************************************************************************************
3676 
3677 
3678 
3679 
3680 //=================================================================================================
3681 //
3682 // CONSTRUCTORS
3683 //
3684 //=================================================================================================
3685 
3686 //*************************************************************************************************
3699 template< typename MT // Type of the dense matrix
3700  , typename... CCAs > // Compile time column arguments
3701 template< typename... RCAs > // Runtime column arguments
3702 inline Columns<MT,false,true,false,CCAs...>::Columns( MT& matrix, RCAs... args )
3703  : DataType( args... ) // Base class initialization
3704  , matrix_ ( matrix ) // The matrix containing the columns
3705 {
3706  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
3707  for( size_t j=0UL; j<columns(); ++j ) {
3708  if( matrix_.columns() <= idx(j) ) {
3709  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3710  }
3711  }
3712  }
3713 }
3715 //*************************************************************************************************
3716 
3717 
3718 
3719 
3720 //=================================================================================================
3721 //
3722 // DATA ACCESS FUNCTIONS
3723 //
3724 //=================================================================================================
3725 
3726 //*************************************************************************************************
3737 template< typename MT // Type of the dense matrix
3738  , typename... CCAs > // Compile time column arguments
3739 inline typename Columns<MT,false,true,false,CCAs...>::Reference
3740  Columns<MT,false,true,false,CCAs...>::operator()( size_t i, size_t j )
3741 {
3742  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3743  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3744 
3745  return matrix_(i,idx(j));
3746 }
3748 //*************************************************************************************************
3749 
3750 
3751 //*************************************************************************************************
3762 template< typename MT // Type of the dense matrix
3763  , typename... CCAs > // Compile time column arguments
3764 inline typename Columns<MT,false,true,false,CCAs...>::ConstReference
3765  Columns<MT,false,true,false,CCAs...>::operator()( size_t i, size_t j ) const
3766 {
3767  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3768  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3769 
3770  return const_cast<const MT&>( matrix_ )(i,idx(j));
3771 }
3773 //*************************************************************************************************
3774 
3775 
3776 //*************************************************************************************************
3788 template< typename MT // Type of the dense matrix
3789  , typename... CCAs > // Compile time column arguments
3790 inline typename Columns<MT,false,true,false,CCAs...>::Reference
3791  Columns<MT,false,true,false,CCAs...>::at( size_t i, size_t j )
3792 {
3793  if( i >= rows() ) {
3794  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3795  }
3796  if( j >= columns() ) {
3797  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3798  }
3799  return (*this)(i,j);
3800 }
3802 //*************************************************************************************************
3803 
3804 
3805 //*************************************************************************************************
3817 template< typename MT // Type of the dense matrix
3818  , typename... CCAs > // Compile time column arguments
3819 inline typename Columns<MT,false,true,false,CCAs...>::ConstReference
3820  Columns<MT,false,true,false,CCAs...>::at( size_t i, size_t j ) const
3821 {
3822  if( i >= rows() ) {
3823  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3824  }
3825  if( j >= columns() ) {
3826  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3827  }
3828  return (*this)(i,j);
3829 }
3831 //*************************************************************************************************
3832 
3833 
3834 //*************************************************************************************************
3844 template< typename MT // Type of the dense matrix
3845  , typename... CCAs > // Compile time column arguments
3846 inline typename Columns<MT,false,true,false,CCAs...>::Pointer
3848 {
3849  return matrix_.data() + idx(0UL);
3850 }
3852 //*************************************************************************************************
3853 
3854 
3855 //*************************************************************************************************
3865 template< typename MT // Type of the dense matrix
3866  , typename... CCAs > // Compile time column arguments
3867 inline typename Columns<MT,false,true,false,CCAs...>::ConstPointer
3869 {
3870  return matrix_.data() + idx(0UL);
3871 }
3873 //*************************************************************************************************
3874 
3875 
3876 //*************************************************************************************************
3885 template< typename MT // Type of the dense matrix
3886  , typename... CCAs > // Compile time column arguments
3887 inline typename Columns<MT,false,true,false,CCAs...>::Pointer
3888  Columns<MT,false,true,false,CCAs...>::data( size_t j ) noexcept
3889 {
3890  return matrix_.data() + idx(j);
3891 }
3893 //*************************************************************************************************
3894 
3895 
3896 //*************************************************************************************************
3905 template< typename MT // Type of the dense matrix
3906  , typename... CCAs > // Compile time column arguments
3907 inline typename Columns<MT,false,true,false,CCAs...>::ConstPointer
3908  Columns<MT,false,true,false,CCAs...>::data( size_t j ) const noexcept
3909 {
3910  return matrix_.data() + idx(j);
3911 }
3913 //*************************************************************************************************
3914 
3915 
3916 //*************************************************************************************************
3925 template< typename MT // Type of the dense matrix
3926  , typename... CCAs > // Compile time column arguments
3927 inline typename Columns<MT,false,true,false,CCAs...>::Iterator
3929 {
3930  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3931  return Iterator( matrix_, 0UL, idx(j) );
3932 }
3934 //*************************************************************************************************
3935 
3936 
3937 //*************************************************************************************************
3946 template< typename MT // Type of the dense matrix
3947  , typename... CCAs > // Compile time column arguments
3948 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
3950 {
3951  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3952  return ConstIterator( matrix_, 0UL, idx(j) );
3953 }
3955 //*************************************************************************************************
3956 
3957 
3958 //*************************************************************************************************
3967 template< typename MT // Type of the dense matrix
3968  , typename... CCAs > // Compile time column arguments
3969 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
3971 {
3972  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3973  return ConstIterator( matrix_, 0UL, idx(j) );
3974 }
3976 //*************************************************************************************************
3977 
3978 
3979 //*************************************************************************************************
3988 template< typename MT // Type of the dense matrix
3989  , typename... CCAs > // Compile time column arguments
3990 inline typename Columns<MT,false,true,false,CCAs...>::Iterator
3992 {
3993  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3994  return Iterator( matrix_, rows(), idx(j) );
3995 }
3997 //*************************************************************************************************
3998 
3999 
4000 //*************************************************************************************************
4009 template< typename MT // Type of the dense matrix
4010  , typename... CCAs > // Compile time column arguments
4011 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
4013 {
4014  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4015  return ConstIterator( matrix_, rows(), idx(j) );
4016 }
4018 //*************************************************************************************************
4019 
4020 
4021 //*************************************************************************************************
4030 template< typename MT // Type of the dense matrix
4031  , typename... CCAs > // Compile time column arguments
4032 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
4034 {
4035  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4036  return ConstIterator( matrix_, rows(), idx(j) );
4037 }
4039 //*************************************************************************************************
4040 
4041 
4042 
4043 
4044 //=================================================================================================
4045 //
4046 // ASSIGNMENT OPERATORS
4047 //
4048 //=================================================================================================
4049 
4050 //*************************************************************************************************
4061 template< typename MT // Type of the dense matrix
4062  , typename... CCAs > // Compile time column arguments
4063 inline Columns<MT,false,true,false,CCAs...>&
4064  Columns<MT,false,true,false,CCAs...>::operator=( const ElementType& rhs )
4065 {
4066  for( size_t j=0UL; j<columns(); ++j ) {
4067  column( matrix_, idx(j), unchecked ) = rhs;
4068  }
4069 
4070  return *this;
4071 }
4073 //*************************************************************************************************
4074 
4075 
4076 //*************************************************************************************************
4092 template< typename MT // Type of the dense matrix
4093  , typename... CCAs > // Compile time column arguments
4094 inline Columns<MT,false,true,false,CCAs...>&
4095  Columns<MT,false,true,false,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
4096 {
4099 
4100  if( list.size() != rows() ) {
4101  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
4102  }
4103 
4104  if( IsRestricted_v<MT> ) {
4105  const InitializerMatrix<ElementType> tmp( list, columns() );
4106  for( size_t j=0UL; j<columns(); ++j ) {
4107  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4108  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4109  }
4110  }
4111  }
4112 
4113  decltype(auto) left( derestrict( *this ) );
4114  size_t i( 0UL );
4115 
4116  for( const auto& rowList : list ) {
4117  size_t j( 0UL );
4118  for( const auto& element : rowList ) {
4119  matrix_(i,idx(j)) = element;
4120  ++j;
4121  }
4122  for( ; j<columns(); ++j ) {
4123  matrix_(i,idx(j)) = ElementType();
4124  }
4125  ++i;
4126  }
4127 
4128  return *this;
4129 }
4131 //*************************************************************************************************
4132 
4133 
4134 //*************************************************************************************************
4149 template< typename MT // Type of the dense matrix
4150  , typename... CCAs > // Compile time column arguments
4151 inline Columns<MT,false,true,false,CCAs...>&
4152  Columns<MT,false,true,false,CCAs...>::operator=( const Columns& rhs )
4153 {
4156 
4159 
4160  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
4161  return *this;
4162 
4163  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
4164  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4165  }
4166 
4167  if( IsRestricted_v<MT> ) {
4168  for( size_t j=0UL; j<columns(); ++j ) {
4169  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( rhs, j, unchecked ), 0UL ) ) {
4170  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4171  }
4172  }
4173  }
4174 
4175  decltype(auto) left( derestrict( *this ) );
4176 
4177  if( rhs.canAlias( &matrix_ ) ) {
4178  const ResultType tmp( rhs );
4179  smpAssign( left, tmp );
4180  }
4181  else {
4182  smpAssign( left, rhs );
4183  }
4184 
4185  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4186 
4187  return *this;
4188 }
4190 //*************************************************************************************************
4191 
4192 
4193 //*************************************************************************************************
4208 template< typename MT // Type of the dense matrix
4209  , typename... CCAs > // Compile time column arguments
4210 template< typename MT2 // Type of the right-hand side matrix
4211  , bool SO2 > // Storage order of the right-hand side matrix
4212 inline Columns<MT,false,true,false,CCAs...>&
4213  Columns<MT,false,true,false,CCAs...>::operator=( const Matrix<MT2,SO2>& rhs )
4214 {
4217 
4218  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4219 
4220  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4221  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4222  }
4223 
4224  using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
4225  Right right( ~rhs );
4226 
4227  if( IsRestricted_v<MT> ) {
4228  for( size_t j=0UL; j<columns(); ++j ) {
4229  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( right, j, unchecked ), 0UL ) ) {
4230  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4231  }
4232  }
4233  }
4234 
4235  decltype(auto) left( derestrict( *this ) );
4236 
4237  if( IsSparseMatrix_v<MT2> ) {
4238  reset();
4239  }
4240 
4241  if( IsReference_v<Right> && right.canAlias( &matrix_ ) ) {
4242  const ResultType_t<MT2> tmp( right );
4243  smpAssign( left, tmp );
4244  }
4245  else {
4246  smpAssign( left, right );
4247  }
4248 
4249  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4250 
4251  return *this;
4252 }
4254 //*************************************************************************************************
4255 
4256 
4257 //*************************************************************************************************
4271 template< typename MT // Type of the dense matrix
4272  , typename... CCAs > // Compile time column arguments
4273 template< typename MT2 // Type of the right-hand side matrix
4274  , bool SO2 > // Storage order of the right-hand side matrix
4275 inline auto Columns<MT,false,true,false,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4276  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4277 {
4280 
4283  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4284 
4285  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4286 
4289 
4290  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4291  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4292  }
4293 
4294  if( IsRestricted_v<MT> ) {
4295  for( size_t j=0UL; j<columns(); ++j ) {
4296  if( !tryAddAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
4297  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4298  }
4299  }
4300  }
4301 
4302  decltype(auto) left( derestrict( *this ) );
4303 
4304  if( (~rhs).canAlias( &matrix_ ) ) {
4305  const AddType tmp( *this + (~rhs) );
4306  smpAssign( left, tmp );
4307  }
4308  else {
4309  smpAddAssign( left, ~rhs );
4310  }
4311 
4312  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4313 
4314  return *this;
4315 }
4317 //*************************************************************************************************
4318 
4319 
4320 //*************************************************************************************************
4334 template< typename MT // Type of the dense matrix
4335  , typename... CCAs > // Compile time column arguments
4336 template< typename MT2 // Type of the right-hand side matrix
4337  , bool SO2 > // Storage order of the right-hand side matrix
4338 inline auto Columns<MT,false,true,false,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4339  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4340 {
4343 
4346  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4347 
4348  using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4349 
4352 
4353  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4354  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4355  }
4356 
4357  const AddType tmp( *this + (~rhs) );
4358 
4359  if( IsRestricted_v<MT> ) {
4360  for( size_t j=0UL; j<columns(); ++j ) {
4361  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4362  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4363  }
4364  }
4365  }
4366 
4367  decltype(auto) left( derestrict( *this ) );
4368 
4369  smpAssign( left, tmp );
4370 
4371  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4372 
4373  return *this;
4374 }
4376 //*************************************************************************************************
4377 
4378 
4379 //*************************************************************************************************
4393 template< typename MT // Type of the dense matrix
4394  , typename... CCAs > // Compile time column arguments
4395 template< typename MT2 // Type of the right-hand side matrix
4396  , bool SO2 > // Storage order of the right-hand side matrix
4397 inline auto Columns<MT,false,true,false,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4398  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4399 {
4402 
4405  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4406 
4407  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4408 
4411 
4412  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4413  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4414  }
4415 
4416  if( IsRestricted_v<MT> ) {
4417  for( size_t j=0UL; j<columns(); ++j ) {
4418  if( !trySubAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
4419  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4420  }
4421  }
4422  }
4423 
4424  decltype(auto) left( derestrict( *this ) );
4425 
4426  if( (~rhs).canAlias( &matrix_ ) ) {
4427  const SubType tmp( *this - (~rhs ) );
4428  smpAssign( left, tmp );
4429  }
4430  else {
4431  smpSubAssign( left, ~rhs );
4432  }
4433 
4434  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4435 
4436  return *this;
4437 }
4439 //*************************************************************************************************
4440 
4441 
4442 //*************************************************************************************************
4456 template< typename MT // Type of the dense matrix
4457  , typename... CCAs > // Compile time column arguments
4458 template< typename MT2 // Type of the right-hand side matrix
4459  , bool SO2 > // Storage order of the right-hand side matrix
4460 inline auto Columns<MT,false,true,false,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4461  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4462 {
4465 
4468  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4469 
4470  using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4471 
4474 
4475  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4476  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4477  }
4478 
4479  const SubType tmp( *this - (~rhs) );
4480 
4481  if( IsRestricted_v<MT> ) {
4482  for( size_t j=0UL; j<columns(); ++j ) {
4483  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4484  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4485  }
4486  }
4487  }
4488 
4489  decltype(auto) left( derestrict( *this ) );
4490 
4491  smpAssign( left, tmp );
4492 
4493  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4494 
4495  return *this;
4496 }
4498 //*************************************************************************************************
4499 
4500 
4501 //*************************************************************************************************
4515 template< typename MT // Type of the dense matrix
4516  , typename... CCAs > // Compile time column arguments
4517 template< typename MT2 // Type of the right-hand side matrix
4518  , bool SO2 > // Storage order of the right-hand side matrix
4519 inline auto Columns<MT,false,true,false,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4520  -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4521 {
4524 
4527  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4528 
4529  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4530 
4532 
4533  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4534  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4535  }
4536 
4537  if( IsRestricted_v<MT> ) {
4538  for( size_t j=0UL; j<columns(); ++j ) {
4539  if( !tryMultAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
4540  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4541  }
4542  }
4543  }
4544 
4545  decltype(auto) left( derestrict( *this ) );
4546 
4547  if( (~rhs).canAlias( &matrix_ ) ) {
4548  const SchurType tmp( *this % (~rhs) );
4549  if( IsSparseMatrix_v<SchurType> )
4550  reset();
4551  smpAssign( left, tmp );
4552  }
4553  else {
4554  smpSchurAssign( left, ~rhs );
4555  }
4556 
4557  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4558 
4559  return *this;
4560 }
4562 //*************************************************************************************************
4563 
4564 
4565 //*************************************************************************************************
4579 template< typename MT // Type of the dense matrix
4580  , typename... CCAs > // Compile time column arguments
4581 template< typename MT2 // Type of the right-hand side matrix
4582  , bool SO2 > // Storage order of the right-hand side matrix
4583 inline auto Columns<MT,false,true,false,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4584  -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4585 {
4588 
4591  BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ResultType_t<MT2> );
4592 
4593  using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4594 
4596 
4597  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4598  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4599  }
4600 
4601  const SchurType tmp( *this % (~rhs) );
4602 
4603  if( IsRestricted_v<MT> ) {
4604  for( size_t j=0UL; j<columns(); ++j ) {
4605  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4606  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4607  }
4608  }
4609  }
4610 
4611  decltype(auto) left( derestrict( *this ) );
4612 
4613  if( IsSparseMatrix_v<SchurType> ) {
4614  reset();
4615  }
4616 
4617  smpAssign( left, tmp );
4618 
4619  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4620 
4621  return *this;
4622 }
4624 //*************************************************************************************************
4625 
4626 
4627 
4628 
4629 //=================================================================================================
4630 //
4631 // UTILITY FUNCTIONS
4632 //
4633 //=================================================================================================
4634 
4635 //*************************************************************************************************
4641 template< typename MT // Type of the dense matrix
4642  , typename... CCAs > // Compile time column arguments
4643 inline MT& Columns<MT,false,true,false,CCAs...>::operand() noexcept
4644 {
4645  return matrix_;
4646 }
4648 //*************************************************************************************************
4649 
4650 
4651 //*************************************************************************************************
4657 template< typename MT // Type of the dense matrix
4658  , typename... CCAs > // Compile time column arguments
4659 inline const MT& Columns<MT,false,true,false,CCAs...>::operand() const noexcept
4660 {
4661  return matrix_;
4662 }
4664 //*************************************************************************************************
4665 
4666 
4667 //*************************************************************************************************
4673 template< typename MT // Type of the dense matrix
4674  , typename... CCAs > // Compile time column arguments
4675 inline size_t Columns<MT,false,true,false,CCAs...>::rows() const noexcept
4676 {
4677  return matrix_.rows();
4678 }
4680 //*************************************************************************************************
4681 
4682 
4683 //*************************************************************************************************
4692 template< typename MT // Type of the dense matrix
4693  , typename... CCAs > // Compile time column arguments
4694 inline size_t Columns<MT,false,true,false,CCAs...>::spacing() const noexcept
4695 {
4696  return matrix_.rows();
4697 }
4699 //*************************************************************************************************
4700 
4701 
4702 //*************************************************************************************************
4708 template< typename MT // Type of the dense matrix
4709  , typename... CCAs > // Compile time column arguments
4710 inline size_t Columns<MT,false,true,false,CCAs...>::capacity() const noexcept
4711 {
4712  return rows() * columns();
4713 }
4715 //*************************************************************************************************
4716 
4717 
4718 //*************************************************************************************************
4727 template< typename MT // Type of the dense matrix
4728  , typename... CCAs > // Compile time column arguments
4729 inline size_t Columns<MT,false,true,false,CCAs...>::capacity( size_t j ) const noexcept
4730 {
4731  MAYBE_UNUSED( j );
4732 
4733  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4734 
4735  return rows();
4736 }
4738 //*************************************************************************************************
4739 
4740 
4741 //*************************************************************************************************
4747 template< typename MT // Type of the dense matrix
4748  , typename... CCAs > // Compile time column arguments
4750 {
4751  size_t nonzeros( 0UL );
4752 
4753  for( size_t j=0UL; j<columns(); ++j ) {
4754  nonzeros += nonZeros( j );
4755  }
4756 
4757  return nonzeros;
4758 }
4760 //*************************************************************************************************
4761 
4762 
4763 //*************************************************************************************************
4772 template< typename MT // Type of the dense matrix
4773  , typename... CCAs > // Compile time column arguments
4774 inline size_t Columns<MT,false,true,false,CCAs...>::nonZeros( size_t j ) const
4775 {
4776  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4777 
4778  size_t nonzeros( 0UL );
4779 
4780  const size_t index( idx(j) );
4781  for( size_t i=0UL; i<rows(); ++i ) {
4782  if( !isDefault( matrix_( i, index ) ) )
4783  ++nonzeros;
4784  }
4785 
4786  return nonzeros;
4787 }
4789 //*************************************************************************************************
4790 
4791 
4792 //*************************************************************************************************
4798 template< typename MT // Type of the dense matrix
4799  , typename... CCAs > // Compile time column arguments
4801 {
4802  for( size_t j=0UL; j<columns(); ++j ) {
4803  reset( j );
4804  }
4805 }
4807 //*************************************************************************************************
4808 
4809 
4810 //*************************************************************************************************
4819 template< typename MT // Type of the dense matrix
4820  , typename... CCAs > // Compile time column arguments
4821 inline void Columns<MT,false,true,false,CCAs...>::reset( size_t j )
4822 {
4823  using blaze::reset;
4824 
4825  const size_t index( idx(j) );
4826  for( size_t i=0UL; i<rows(); ++i ) {
4827  reset( matrix_( i, index ) );
4828  }
4829 }
4831 //*************************************************************************************************
4832 
4833 
4834 
4835 
4836 //=================================================================================================
4837 //
4838 // NUMERIC FUNCTIONS
4839 //
4840 //=================================================================================================
4841 
4842 //*************************************************************************************************
4855 template< typename MT // Type of the dense matrix
4856  , typename... CCAs > // Compile time column arguments
4857 inline Columns<MT,false,true,false,CCAs...>&
4859 {
4862 
4863  if( rows() != columns() ) {
4864  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4865  }
4866 
4867  const ResultType tmp( trans( *this ) );
4868 
4869  if( IsRestricted_v<MT> ) {
4870  for( size_t j=0UL; j<columns(); ++j ) {
4871  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4872  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4873  }
4874  }
4875  }
4876 
4877  decltype(auto) left( derestrict( *this ) );
4878 
4879  smpAssign( left, tmp );
4880 
4881  return *this;
4882 }
4884 //*************************************************************************************************
4885 
4886 
4887 //*************************************************************************************************
4900 template< typename MT // Type of the dense matrix
4901  , typename... CCAs > // Compile time column arguments
4902 inline Columns<MT,false,true,false,CCAs...>&
4903  Columns<MT,false,true,false,CCAs...>::ctranspose()
4904 {
4907 
4908  if( rows() != columns() ) {
4909  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4910  }
4911 
4912  const ResultType tmp( ctrans( *this ) );
4913 
4914  if( IsRestricted_v<MT> ) {
4915  for( size_t j=0UL; j<columns(); ++j ) {
4916  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4917  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4918  }
4919  }
4920  }
4921 
4922  decltype(auto) left( derestrict( *this ) );
4923 
4924  smpAssign( left, tmp );
4925 
4926  return *this;
4927 }
4929 //*************************************************************************************************
4930 
4931 
4932 //*************************************************************************************************
4945 template< typename MT // Type of the dense matrix
4946  , typename... CCAs > // Compile time column arguments
4947 template< typename Other > // Data type of the scalar value
4948 inline Columns<MT,false,true,false,CCAs...>&
4949  Columns<MT,false,true,false,CCAs...>::scale( const Other& scalar )
4950 {
4954 
4955  for( size_t j=0UL; j<columns(); ++j )
4956  {
4957  const size_t index ( idx(j) );
4958  const size_t ibegin( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index+1UL : index ) : 0UL );
4959  const size_t iend ( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index : index+1UL ) : rows() );
4960 
4961  for( size_t i=ibegin; i<iend; ++i ) {
4962  matrix_(i,index) *= scalar;
4963  }
4964  }
4965 
4966  return *this;
4967 }
4969 //*************************************************************************************************
4970 
4971 
4972 
4973 
4974 //=================================================================================================
4975 //
4976 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4977 //
4978 //=================================================================================================
4979 
4980 //*************************************************************************************************
4991 template< typename MT // Type of the dense matrix
4992  , typename... CCAs > // Compile time column arguments
4993 template< typename Other > // Data type of the foreign expression
4994 inline bool Columns<MT,false,true,false,CCAs...>::canAlias( const Other* alias ) const noexcept
4995 {
4996  return matrix_.isAliased( alias );
4997 }
4999 //*************************************************************************************************
5000 
5001 
5002 //*************************************************************************************************
5014 template< typename MT // Type of the dense matrix
5015  , typename... CCAs > // Compile time column arguments
5016 template< typename MT2 // Data type of the foreign dense column selection
5017  , bool SO2 // Storage order of the foreign dense column selection
5018  , bool SF2 // Symmetry flag of the foreign dense column selection
5019  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
5020 inline bool
5021  Columns<MT,false,true,false,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5022 {
5023  return matrix_.isAliased( &alias->matrix_ );
5024 }
5026 //*************************************************************************************************
5027 
5028 
5029 //*************************************************************************************************
5040 template< typename MT // Type of the dense matrix
5041  , typename... CCAs > // Compile time column arguments
5042 template< typename Other > // Data type of the foreign expression
5043 inline bool Columns<MT,false,true,false,CCAs...>::isAliased( const Other* alias ) const noexcept
5044 {
5045  return matrix_.isAliased( alias );
5046 }
5048 //*************************************************************************************************
5049 
5050 
5051 //*************************************************************************************************
5063 template< typename MT // Type of the dense matrix
5064  , typename... CCAs > // Compile time column arguments
5065 template< typename MT2 // Data type of the foreign dense column selection
5066  , bool SO2 // Storage order of the foreign dense column selection
5067  , bool SF2 // Symmetry flag of the foreign dense column selection
5068  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
5069 inline bool
5070  Columns<MT,false,true,false,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5071 {
5072  return matrix_.isAliased( &alias->matrix_ );
5073 }
5075 //*************************************************************************************************
5076 
5077 
5078 //*************************************************************************************************
5088 template< typename MT // Type of the dense matrix
5089  , typename... CCAs > // Compile time column arguments
5090 inline bool Columns<MT,false,true,false,CCAs...>::isAligned() const noexcept
5091 {
5092  return false;
5093 }
5095 //*************************************************************************************************
5096 
5097 
5098 //*************************************************************************************************
5109 template< typename MT // Type of the dense matrix
5110  , typename... CCAs > // Compile time column arguments
5111 inline bool Columns<MT,false,true,false,CCAs...>::canSMPAssign() const noexcept
5112 {
5113  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
5114 }
5116 //*************************************************************************************************
5117 
5118 
5119 //*************************************************************************************************
5131 template< typename MT // Type of the dense matrix
5132  , typename... CCAs > // Compile time column arguments
5133 template< typename MT2 > // Type of the right-hand side dense matrix
5134 inline void Columns<MT,false,true,false,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
5135 {
5138 
5139  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5140  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5141 
5142  const size_t ipos( rows() & size_t(-2) );
5143  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5144 
5145  for( size_t j=0UL; j<columns(); ++j ) {
5146  const size_t index( idx(j) );
5147  for( size_t i=0UL; i<ipos; i+=2UL ) {
5148  matrix_(i ,index) = (~rhs)(i ,j);
5149  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
5150  }
5151  if( ipos < rows() ) {
5152  matrix_(ipos,index) = (~rhs)(ipos,j);
5153  }
5154  }
5155 }
5157 //*************************************************************************************************
5158 
5159 
5160 //*************************************************************************************************
5172 template< typename MT // Type of the dense matrix
5173  , typename... CCAs > // Compile time column arguments
5174 template< typename MT2 > // Type of the right-hand side dense matrix
5175 inline void Columns<MT,false,true,false,CCAs...>::assign( const DenseMatrix<MT2,false>& rhs )
5176 {
5179 
5181 
5182  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5183  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5184 
5185  constexpr size_t block( BLOCK_SIZE );
5186 
5187  if( rows() < block && columns() < block )
5188  {
5189  const size_t ipos( (~rhs).rows() & size_t(-2) );
5190  for( size_t j=0UL; j<columns(); ++j ) {
5191  const size_t index( idx(j) );
5192  for( size_t i=0UL; i<ipos; i+=2UL ) {
5193  matrix_(i ,index) = (~rhs)(i ,j);
5194  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
5195  }
5196  if( ipos < (~rhs).rows() ) {
5197  matrix_(ipos,index) = (~rhs)(ipos,j);
5198  }
5199  }
5200  }
5201  else
5202  {
5203  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5204  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5205  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5206  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5207  for( size_t j=jj; j<jend; ++j ) {
5208  const size_t index( idx(j) );
5209  for( size_t i=ii; i<iend; ++i ) {
5210  matrix_(i,index) = (~rhs)(i,j);
5211  }
5212  }
5213  }
5214  }
5215  }
5216 }
5218 //*************************************************************************************************
5219 
5220 
5221 //*************************************************************************************************
5233 template< typename MT // Type of the dense matrix
5234  , typename... CCAs > // Compile time column arguments
5235 template< typename MT2 > // Type of the right-hand side sparse matrix
5236 inline void Columns<MT,false,true,false,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
5237 {
5240 
5241  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5242  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5243 
5244  for( size_t j=0UL; j<columns(); ++j ) {
5245  const size_t index( idx(j) );
5246  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5247  matrix_(element->index(),index) = element->value();
5248  }
5249 }
5251 //*************************************************************************************************
5252 
5253 
5254 //*************************************************************************************************
5266 template< typename MT // Type of the dense matrix
5267  , typename... CCAs > // Compile time column arguments
5268 template< typename MT2 > // Type of the right-hand side sparse matrix
5269 inline void Columns<MT,false,true,false,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
5270 {
5273 
5275 
5276  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5277  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5278 
5279  for( size_t i=0UL; i<rows(); ++i ) {
5280  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5281  matrix_(i,idx(element->index())) = element->value();
5282  }
5283 }
5285 //*************************************************************************************************
5286 
5287 
5288 //*************************************************************************************************
5300 template< typename MT // Type of the dense matrix
5301  , typename... CCAs > // Compile time column arguments
5302 template< typename MT2 > // Type of the right-hand side dense matrix
5303 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
5304 {
5307 
5308  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5309  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5310 
5311  const size_t ipos( rows() & size_t(-2) );
5312  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5313 
5314  for( size_t j=0UL; j<columns(); ++j )
5315  {
5316  const size_t index( idx(j) );
5317  if( IsDiagonal_v<MT2> ) {
5318  matrix_(j,index) += (~rhs)(j,j);
5319  }
5320  else {
5321  for( size_t i=0UL; i<ipos; i+=2UL ) {
5322  matrix_(i ,index) += (~rhs)(i ,j);
5323  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
5324  }
5325  if( ipos < rows() ) {
5326  matrix_(ipos,index) += (~rhs)(ipos,j);
5327  }
5328  }
5329  }
5330 }
5332 //*************************************************************************************************
5333 
5334 
5335 //*************************************************************************************************
5347 template< typename MT // Type of the dense matrix
5348  , typename... CCAs > // Compile time column arguments
5349 template< typename MT2 > // Type of the right-hand side dense matrix
5350 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
5351 {
5354 
5356 
5357  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5358  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5359 
5360  constexpr size_t block( BLOCK_SIZE );
5361 
5362  if( rows() < block && columns() < block )
5363  {
5364  const size_t ipos( (~rhs).rows() & size_t(-2) );
5365  for( size_t j=0UL; j<columns(); ++j ) {
5366  const size_t index( idx(j) );
5367  for( size_t i=0UL; i<ipos; i+=2UL ) {
5368  matrix_(i ,index) += (~rhs)(i ,j);
5369  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
5370  }
5371  if( ipos < (~rhs).rows() )
5372  matrix_(ipos,index) += (~rhs)(ipos,j);
5373  }
5374  }
5375  else
5376  {
5377  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5378  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5379  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5380  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5381  for( size_t j=jj; j<jend; ++j ) {
5382  const size_t index( idx(j) );
5383  for( size_t i=ii; i<iend; ++i ) {
5384  matrix_(i,index) += (~rhs)(i,j);
5385  }
5386  }
5387  }
5388  }
5389  }
5390 }
5392 //*************************************************************************************************
5393 
5394 
5395 //*************************************************************************************************
5407 template< typename MT // Type of the dense matrix
5408  , typename... CCAs > // Compile time column arguments
5409 template< typename MT2 > // Type of the right-hand side sparse matrix
5410 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
5411 {
5414 
5415  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5416  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5417 
5418  for( size_t j=0UL; j<columns(); ++j ) {
5419  const size_t index( idx(j) );
5420  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5421  matrix_(element->index(),index) += element->value();
5422  }
5423 }
5425 //*************************************************************************************************
5426 
5427 
5428 //*************************************************************************************************
5440 template< typename MT // Type of the dense matrix
5441  , typename... CCAs > // Compile time column arguments
5442 template< typename MT2 > // Type of the right-hand side sparse matrix
5443 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
5444 {
5447 
5449 
5450  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5451  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5452 
5453  for( size_t i=0UL; i<rows(); ++i ) {
5454  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5455  matrix_(i,idx(element->index())) += element->value();
5456  }
5457 }
5459 //*************************************************************************************************
5460 
5461 
5462 //*************************************************************************************************
5474 template< typename MT // Type of the dense matrix
5475  , typename... CCAs > // Compile time column arguments
5476 template< typename MT2 > // Type of the right-hand side dense matrix
5477 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
5478 {
5481 
5482  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5483  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5484 
5485  const size_t ipos( rows() & size_t(-2) );
5486  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5487 
5488  for( size_t j=0UL; j<columns(); ++j )
5489  {
5490  const size_t index( idx(j) );
5491 
5492  if( IsDiagonal_v<MT2> ) {
5493  matrix_(j,index) -= (~rhs)(j,j);
5494  }
5495  else {
5496  for( size_t i=0UL; i<ipos; i+=2UL ) {
5497  matrix_(i ,index) -= (~rhs)(i ,j);
5498  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
5499  }
5500  if( ipos < rows() ) {
5501  matrix_(ipos,index) -= (~rhs)(ipos,j);
5502  }
5503  }
5504  }
5505 }
5507 //*************************************************************************************************
5508 
5509 
5510 //*************************************************************************************************
5522 template< typename MT // Type of the dense matrix
5523  , typename... CCAs > // Compile time column arguments
5524 template< typename MT2 > // Type of the right-hand side dense matrix
5525 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
5526 {
5529 
5531 
5532  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5533  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5534 
5535  constexpr size_t block( BLOCK_SIZE );
5536 
5537  if( rows() < block && columns() < block )
5538  {
5539  const size_t ipos( (~rhs).rows() & size_t(-2) );
5540  for( size_t j=0UL; j<columns(); ++j ) {
5541  const size_t index( idx(j) );
5542  for( size_t i=0UL; i<ipos; i+=2UL ) {
5543  matrix_(i ,index) -= (~rhs)(i ,j);
5544  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
5545  }
5546  if( ipos < (~rhs).rows() )
5547  matrix_(ipos,index) -= (~rhs)(ipos,j);
5548  }
5549  }
5550  else
5551  {
5552  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5553  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5554  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5555  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5556  for( size_t j=jj; j<jend; ++j ) {
5557  const size_t index( idx(j) );
5558  for( size_t i=ii; i<iend; ++i ) {
5559  matrix_(i,index) -= (~rhs)(i,j);
5560  }
5561  }
5562  }
5563  }
5564  }
5565 }
5567 //*************************************************************************************************
5568 
5569 
5570 //*************************************************************************************************
5582 template< typename MT // Type of the dense matrix
5583  , typename... CCAs > // Compile time column arguments
5584 template< typename MT2 > // Type of the right-hand side sparse matrix
5585 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
5586 {
5589 
5590  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5591  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5592 
5593  for( size_t j=0UL; j<columns(); ++j ) {
5594  const size_t index( idx(j) );
5595  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5596  matrix_(element->index(),index) -= element->value();
5597  }
5598 }
5600 //*************************************************************************************************
5601 
5602 
5603 //*************************************************************************************************
5615 template< typename MT // Type of the dense matrix
5616  , typename... CCAs > // Compile time column arguments
5617 template< typename MT2 > // Type of the right-hand side sparse matrix
5618 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
5619 {
5622 
5624 
5625  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5626  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5627 
5628  for( size_t i=0UL; i<rows(); ++i ) {
5629  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5630  matrix_(i,idx(element->index())) -= element->value();
5631  }
5632 }
5634 //*************************************************************************************************
5635 
5636 
5637 //*************************************************************************************************
5649 template< typename MT // Type of the dense matrix
5650  , typename... CCAs > // Compile time column arguments
5651 template< typename MT2 > // Type of the right-hand side dense matrix
5652 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
5653 {
5656 
5657  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5658  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5659 
5660  const size_t ipos( rows() & size_t(-2) );
5661  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5662 
5663  for( size_t j=0UL; j<columns(); ++j ) {
5664  const size_t index( idx(j) );
5665  for( size_t i=0UL; i<ipos; i+=2UL ) {
5666  matrix_(i ,index) *= (~rhs)(i ,j);
5667  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
5668  }
5669  if( ipos < rows() ) {
5670  matrix_(ipos,index) *= (~rhs)(ipos,j);
5671  }
5672  }
5673 }
5675 //*************************************************************************************************
5676 
5677 
5678 //*************************************************************************************************
5690 template< typename MT // Type of the dense matrix
5691  , typename... CCAs > // Compile time column arguments
5692 template< typename MT2 > // Type of the right-hand side dense matrix
5693 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
5694 {
5697 
5699 
5700  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5701  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5702 
5703  constexpr size_t block( BLOCK_SIZE );
5704 
5705  if( rows() < block && columns() < block )
5706  {
5707  const size_t ipos( (~rhs).rows() & size_t(-2) );
5708  for( size_t j=0UL; j<columns(); ++j ) {
5709  const size_t index( idx(j) );
5710  for( size_t i=0UL; i<ipos; i+=2UL ) {
5711  matrix_(i ,index) *= (~rhs)(i ,j);
5712  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
5713  }
5714  if( ipos < (~rhs).rows() )
5715  matrix_(ipos,index) *= (~rhs)(ipos,j);
5716  }
5717  }
5718  else
5719  {
5720  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5721  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5722  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5723  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5724  for( size_t j=jj; j<jend; ++j ) {
5725  const size_t index( idx(j) );
5726  for( size_t i=ii; i<iend; ++i ) {
5727  matrix_(i,index) *= (~rhs)(i,j);
5728  }
5729  }
5730  }
5731  }
5732  }
5733 }
5735 //*************************************************************************************************
5736 
5737 
5738 //*************************************************************************************************
5750 template< typename MT // Type of the dense matrix
5751  , typename... CCAs > // Compile time column arguments
5752 template< typename MT2 > // Type of the right-hand side sparse matrix
5753 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
5754 {
5755  using blaze::reset;
5756 
5759 
5760  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5761  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5762 
5763  for( size_t j=0UL; j<columns(); ++j )
5764  {
5765  const size_t index( idx(j) );
5766  size_t i( 0UL );
5767 
5768  for( ConstIterator_t<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
5769  for( ; i<element->index(); ++i )
5770  reset( matrix_(i,index) );
5771  matrix_(i,index) *= element->value();
5772  ++i;
5773  }
5774 
5775  for( ; i<rows(); ++i ) {
5776  reset( matrix_(i,index) );
5777  }
5778  }
5779 }
5781 //*************************************************************************************************
5782 
5783 
5784 //*************************************************************************************************
5796 template< typename MT // Type of the dense matrix
5797  , typename... CCAs > // Compile time column arguments
5798 template< typename MT2 > // Type of the right-hand side sparse matrix
5799 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
5800 {
5801  using blaze::reset;
5802 
5805 
5807 
5808  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5809  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5810 
5811  for( size_t i=0UL; i<rows(); ++i )
5812  {
5813  size_t j( 0UL );
5814 
5815  for( ConstIterator_t<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
5816  for( ; j<element->index(); ++j )
5817  reset( matrix_(i,idx(j)) );
5818  matrix_(i,idx(j)) *= element->value();
5819  ++j;
5820  }
5821 
5822  for( ; j<columns(); ++j ) {
5823  reset( matrix_(i,idx(j)) );
5824  }
5825  }
5826 }
5828 //*************************************************************************************************
5829 
5830 
5831 
5832 
5833 
5834 
5835 
5836 
5837 //=================================================================================================
5838 //
5839 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
5840 //
5841 //=================================================================================================
5842 
5843 //*************************************************************************************************
5851 template< typename MT // Type of the dense matrix
5852  , typename... CCAs > // Compile time column arguments
5853 class Columns<MT,false,true,true,CCAs...>
5854  : public View< DenseMatrix< Columns<MT,false,true,true,CCAs...>, true > >
5855  , private ColumnsData<CCAs...>
5856 {
5857  private:
5858  //**Type definitions****************************************************************************
5859  using DataType = ColumnsData<CCAs...>;
5860  using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
5861  //**********************************************************************************************
5862 
5863  //**Compile time flags**************************************************************************
5864  static constexpr size_t N = sizeof...( CCAs );
5865  //**********************************************************************************************
5866 
5867  public:
5868  //**Type definitions****************************************************************************
5870  using This = Columns<MT,false,true,true,CCAs...>;
5871 
5872  using BaseType = DenseMatrix<This,true>;
5873  using ViewedType = MT;
5874  using ResultType = ColumnsTrait_t<MT,N>;
5875  using OppositeType = OppositeType_t<ResultType>;
5876  using TransposeType = TransposeType_t<ResultType>;
5877  using ElementType = ElementType_t<MT>;
5878  using SIMDType = SIMDTrait_t<ElementType>;
5879  using ReturnType = ReturnType_t<MT>;
5880  using CompositeType = const Columns&;
5881 
5883  using ConstReference = ConstReference_t<MT>;
5884 
5886  using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
5887 
5889  using ConstPointer = ConstPointer_t<MT>;
5890 
5892  using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
5893 
5895  using ConstIterator = ConstIterator_t<MT>;
5896 
5898  using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
5899  //**********************************************************************************************
5900 
5901  //**Compilation flags***************************************************************************
5903  static constexpr bool simdEnabled = MT::simdEnabled;
5904 
5906  static constexpr bool smpAssignable = MT::smpAssignable;
5907 
5909  static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
5910  //**********************************************************************************************
5911 
5912  //**Constructors********************************************************************************
5915  template< typename... RCAs >
5916  explicit inline Columns( MT& matrix, RCAs... args );
5917 
5918  Columns( const Columns& ) = default;
5919  Columns( Columns&& ) = default;
5921  //**********************************************************************************************
5922 
5923  //**Destructor**********************************************************************************
5926  ~Columns() = default;
5928  //**********************************************************************************************
5929 
5930  //**Data access functions***********************************************************************
5933  inline Reference operator()( size_t i, size_t j );
5934  inline ConstReference operator()( size_t i, size_t j ) const;
5935  inline Reference at( size_t i, size_t j );
5936  inline ConstReference at( size_t i, size_t j ) const;
5937  inline Pointer data () noexcept;
5938  inline ConstPointer data () const noexcept;
5939  inline Pointer data ( size_t j ) noexcept;
5940  inline ConstPointer data ( size_t j ) const noexcept;
5941  inline Iterator begin ( size_t j );
5942  inline ConstIterator begin ( size_t j ) const;
5943  inline ConstIterator cbegin( size_t j ) const;
5944  inline Iterator end ( size_t j );
5945  inline ConstIterator end ( size_t j ) const;
5946  inline ConstIterator cend ( size_t j ) const;
5948  //**********************************************************************************************
5949 
5950  //**Assignment operators************************************************************************
5953  inline Columns& operator=( const ElementType& rhs );
5954 
5955  Columns& operator=( const Columns& ) = delete;
5957  //**********************************************************************************************
5958 
5959  //**Utility functions***************************************************************************
5962  using DataType::idx;
5963  using DataType::idces;
5964  using DataType::columns;
5965 
5966  inline MT& operand() noexcept;
5967  inline const MT& operand() const noexcept;
5968 
5969  inline size_t rows() const noexcept;
5970  inline size_t spacing() const noexcept;
5971  inline size_t capacity() const noexcept;
5972  inline size_t capacity( size_t j ) const noexcept;
5973  inline size_t nonZeros() const;
5974  inline size_t nonZeros( size_t j ) const;
5975  inline void reset();
5976  inline void reset( size_t j );
5978  //**********************************************************************************************
5979 
5980  //**Expression template evaluation functions****************************************************
5983  template< typename Other >
5984  inline bool canAlias( const Other* alias ) const noexcept;
5985 
5986  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
5987  inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
5988 
5989  template< typename Other >
5990  inline bool isAliased( const Other* alias ) const noexcept;
5991 
5992  template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
5993  inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
5994 
5995  inline bool isAligned () const noexcept;
5996  inline bool canSMPAssign() const noexcept;
5997 
5998  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
5999  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
6000  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
6002  //**********************************************************************************************
6003 
6004  private:
6005  //**Member variables****************************************************************************
6008  Operand matrix_;
6009 
6010  //**********************************************************************************************
6011 
6012  //**Friend declarations*************************************************************************
6013  template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
6014  //**********************************************************************************************
6015 
6016  //**Compile time checks*************************************************************************
6026  //**********************************************************************************************
6027 };
6029 //*************************************************************************************************
6030 
6031 
6032 
6033 
6034 //=================================================================================================
6035 //
6036 // CONSTRUCTORS
6037 //
6038 //=================================================================================================
6039 
6040 //*************************************************************************************************
6053 template< typename MT // Type of the dense matrix
6054  , typename... CCAs > // Compile time column arguments
6055 template< typename... RCAs > // Runtime column arguments
6056 inline Columns<MT,false,true,true,CCAs...>::Columns( MT& matrix, RCAs... args )
6057  : DataType( args... ) // Base class initialization
6058  , matrix_ ( matrix ) // The matrix containing the columns
6059 {
6060  if( !Contains_v< TypeList<RCAs...>, Unchecked > ) {
6061  for( size_t j=0UL; j<columns(); ++j ) {
6062  if( matrix_.columns() <= idx(j) ) {
6063  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
6064  }
6065  }
6066  }
6067 }
6069 //*************************************************************************************************
6070 
6071 
6072 
6073 
6074 //=================================================================================================
6075 //
6076 // DATA ACCESS FUNCTIONS
6077 //
6078 //=================================================================================================
6079 
6080 //*************************************************************************************************
6091 template< typename MT // Type of the dense matrix
6092  , typename... CCAs > // Compile time column arguments
6093 inline typename Columns<MT,false,true,true,CCAs...>::Reference
6094  Columns<MT,false,true,true,CCAs...>::operator()( size_t i, size_t j )
6095 {
6096  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6097  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6098 
6099  return matrix_(idx(j),i);
6100 }
6102 //*************************************************************************************************
6103 
6104 
6105 //*************************************************************************************************
6116 template< typename MT // Type of the dense matrix
6117  , typename... CCAs > // Compile time column arguments
6118 inline typename Columns<MT,false,true,true,CCAs...>::ConstReference
6119  Columns<MT,false,true,true,CCAs...>::operator()( size_t i, size_t j ) const
6120 {
6121  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6122  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6123 
6124  return const_cast<const MT&>( matrix_ )(idx(j),i);
6125 }
6127 //*************************************************************************************************
6128 
6129 
6130 //*************************************************************************************************
6142 template< typename MT // Type of the dense matrix
6143  , typename... CCAs > // Compile time column arguments
6144 inline typename Columns<MT,false,true,true,CCAs...>::Reference
6145  Columns<MT,false,true,true,CCAs...>::at( size_t i, size_t j )
6146 {
6147  if( i >= rows() ) {
6148  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6149  }
6150  if( j >= columns() ) {
6151  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6152  }
6153  return (*this)(i,j);
6154 }
6156 //*************************************************************************************************
6157 
6158 
6159 //*************************************************************************************************
6171 template< typename MT // Type of the dense matrix
6172  , typename... CCAs > // Compile time column arguments
6173 inline typename Columns<MT,false,true,true,CCAs...>::ConstReference
6174  Columns<MT,false,true,true,CCAs...>::at( size_t i, size_t j ) const
6175 {
6176  if( i >= rows() ) {
6177  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6178  }
6179  if( j >= columns() ) {
6180  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6181  }
6182  return (*this)(i,j);
6183 }
6185 //*************************************************************************************************
6186 
6187 
6188 //*************************************************************************************************
6198 template< typename MT // Type of the dense matrix
6199  , typename... CCAs > // Compile time column arguments
6200 inline typename Columns<MT,false,true,true,CCAs...>::Pointer
6202 {
6203  return matrix_.data( idx(0UL) );
6204 }
6206 //*************************************************************************************************
6207 
6208 
6209 //*************************************************************************************************
6219 template< typename MT // Type of the dense matrix
6220  , typename... CCAs > // Compile time column arguments
6221 inline typename Columns<MT,false,true,true,CCAs...>::ConstPointer
6223 {
6224  return matrix_.data( idx(0UL) );
6225 }
6227 //*************************************************************************************************
6228 
6229 
6230 //*************************************************************************************************
6239 template< typename MT // Type of the dense matrix
6240  , typename... CCAs > // Compile time column arguments
6241 inline typename Columns<MT,false,true,true,CCAs...>::Pointer
6242  Columns<MT,false,true,true,CCAs...>::data( size_t j ) noexcept
6243 {
6244  return matrix_.data( idx(j) );
6245 }
6247 //*************************************************************************************************
6248 
6249 
6250 //*************************************************************************************************
6259 template< typename MT // Type of the dense matrix
6260  , typename... CCAs > // Compile time column arguments
6261 inline typename Columns<MT,false,true,true,CCAs...>::ConstPointer
6262  Columns<MT,false,true,true,CCAs...>::data( size_t j ) const noexcept
6263 {
6264  return matrix_.data( idx(j) );
6265 }
6267 //*************************************************************************************************
6268 
6269 
6270 //*************************************************************************************************
6279 template< typename MT // Type of the dense matrix
6280  , typename... CCAs > // Compile time column arguments
6281 inline typename Columns<MT,false,true,true,CCAs...>::Iterator
6283 {
6284  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6285  return matrix_.begin( idx(j) );
6286 }
6288 //*************************************************************************************************
6289 
6290 
6291 //*************************************************************************************************
6300 template< typename MT // Type of the dense matrix
6301  , typename... CCAs > // Compile time column arguments
6302 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6304 {
6305  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6306  return matrix_.cbegin( idx(j) );
6307 }
6309 //*************************************************************************************************
6310 
6311 
6312 //*************************************************************************************************
6321 template< typename MT // Type of the dense matrix
6322  , typename... CCAs > // Compile time column arguments
6323 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6325 {
6326  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6327  return matrix_.cbegin( idx(j) );
6328 }
6330 //*************************************************************************************************
6331 
6332 
6333 //*************************************************************************************************
6342 template< typename MT // Type of the dense matrix
6343  , typename... CCAs > // Compile time column arguments
6344 inline typename Columns<MT,false,true,true,CCAs...>::Iterator
6346 {
6347  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6348  return matrix_.end( idx(j) );
6349 }
6351 //*************************************************************************************************
6352 
6353 
6354 //*************************************************************************************************
6363 template< typename MT // Type of the dense matrix
6364  , typename... CCAs > // Compile time column arguments
6365 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6367 {
6368  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6369  return matrix_.cend( idx(j) );
6370 }
6372 //*************************************************************************************************
6373 
6374 
6375 //*************************************************************************************************
6384 template< typename MT // Type of the dense matrix
6385  , typename... CCAs > // Compile time column arguments
6386 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6388 {
6389  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6390  return matrix_.cend( idx(j) );
6391 }
6393 //*************************************************************************************************
6394 
6395 
6396 
6397 
6398 //=================================================================================================
6399 //
6400 // ASSIGNMENT OPERATORS
6401 //
6402 //=================================================================================================
6403 
6404 //*************************************************************************************************
6415 template< typename MT // Type of the dense matrix
6416  , typename... CCAs > // Compile time column arguments
6417 inline Columns<MT,false,true,true,CCAs...>&
6418  Columns<MT,false,true,true,CCAs...>::operator=( const ElementType& rhs )
6419 {
6420  for( size_t j=0UL; j<columns(); ++j ) {
6421  row( matrix_, idx(j), unchecked ) = rhs;
6422  }
6423 
6424  return *this;
6425 }
6427 //*************************************************************************************************
6428 
6429 
6430 
6431 
6432 //=================================================================================================
6433 //
6434 // UTILITY FUNCTIONS
6435 //
6436 //=================================================================================================
6437 
6438 //*************************************************************************************************
6444 template< typename MT // Type of the dense matrix
6445  , typename... CCAs > // Compile time column arguments
6446 inline MT& Columns<MT,false,true,true,CCAs...>::operand() noexcept
6447 {
6448  return matrix_;
6449 }
6451 //*************************************************************************************************
6452 
6453 
6454 //*************************************************************************************************
6460 template< typename MT // Type of the dense matrix
6461  , typename... CCAs > // Compile time column arguments
6462 inline const MT& Columns<MT,false,true,true,CCAs...>::operand() const noexcept
6463 {
6464  return matrix_;
6465 }
6467 //*************************************************************************************************
6468 
6469 
6470 //*************************************************************************************************
6476 template< typename MT // Type of the dense matrix
6477  , typename... CCAs > // Compile time column arguments
6478 inline size_t Columns<MT,false,true,true,CCAs...>::rows() const noexcept
6479 {
6480  return matrix_.rows();
6481 }
6483 //*************************************************************************************************
6484 
6485 
6486 //*************************************************************************************************
6495 template< typename MT // Type of the dense matrix
6496  , typename... CCAs > // Compile time column arguments
6497 inline size_t Columns<MT,false,true,true,CCAs...>::spacing() const noexcept
6498 {
6499  return matrix_.spacing();
6500 }
6502 //*************************************************************************************************
6503 
6504 
6505 //*************************************************************************************************
6511 template< typename MT // Type of the dense matrix
6512  , typename... CCAs > // Compile time column arguments
6513 inline size_t Columns<MT,false,true,true,CCAs...>::capacity() const noexcept
6514 {
6515  return rows() * columns();
6516 }
6518 //*************************************************************************************************
6519 
6520 
6521 //*************************************************************************************************
6530 template< typename MT // Type of the dense matrix
6531  , typename... CCAs > // Compile time column arguments
6532 inline size_t Columns<MT,false,true,true,CCAs...>::capacity( size_t j ) const noexcept
6533 {
6534  MAYBE_UNUSED( j );
6535 
6536  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6537 
6538  return rows();
6539 }
6541 //*************************************************************************************************
6542 
6543 
6544 //*************************************************************************************************
6550 template< typename MT // Type of the dense matrix
6551  , typename... CCAs > // Compile time column arguments
6553 {
6554  size_t nonzeros( 0UL );
6555 
6556  for( size_t j=0UL; j<columns(); ++j ) {
6557  nonzeros += matrix_.nonZeros( idx(j) );
6558  }
6559 
6560  return nonzeros;
6561 }
6563 //*************************************************************************************************
6564 
6565 
6566 //*************************************************************************************************
6575 template< typename MT // Type of the dense matrix
6576  , typename... CCAs > // Compile time column arguments
6577 inline size_t Columns<MT,false,true,true,CCAs...>::nonZeros( size_t j ) const
6578 {
6579  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6580 
6581  return matrix_.nonZeros( idx(j) );
6582 }
6584 //*************************************************************************************************
6585 
6586 
6587 //*************************************************************************************************
6593 template< typename MT // Type of the dense matrix
6594  , typename... CCAs > // Compile time column arguments
6596 {
6597  for( size_t j=0UL; j<columns(); ++j ) {
6598  matrix_.reset( idx(j) );
6599  }
6600 }
6602 //*************************************************************************************************
6603 
6604 
6605 //*************************************************************************************************
6614 template< typename MT // Type of the dense matrix
6615  , typename... CCAs > // Compile time column arguments
6616 inline void Columns<MT,false,true,true,CCAs...>::reset( size_t j )
6617 {
6618  matrix_.reset( idx(j) );
6619 }
6621 //*************************************************************************************************
6622 
6623 
6624 //=================================================================================================
6625 //
6626 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6627 //
6628 //=================================================================================================
6629 
6630 //*************************************************************************************************
6641 template< typename MT // Type of the dense matrix
6642  , typename... CCAs > // Compile time column arguments
6643 template< typename Other > // Data type of the foreign expression
6644 inline bool Columns<MT,false,true,true,CCAs...>::canAlias( const Other* alias ) const noexcept
6645 {
6646  return matrix_.isAliased( alias );
6647 }
6649 //*************************************************************************************************
6650 
6651 
6652 //*************************************************************************************************
6664 template< typename MT // Type of the dense matrix
6665  , typename... CCAs > // Compile time column arguments
6666 template< typename MT2 // Data type of the foreign dense column selection
6667  , bool SO2 // Storage order of the foreign dense column selection
6668  , bool SF2 // Symmetry flag of the foreign dense column selection
6669  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
6670 inline bool
6671  Columns<MT,false,true,true,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
6672 {
6673  return matrix_.isAliased( &alias->matrix_ );
6674 }
6676 //*************************************************************************************************
6677 
6678 
6679 //*************************************************************************************************
6690 template< typename MT // Type of the dense matrix
6691  , typename... CCAs > // Compile time column arguments
6692 template< typename Other > // Data type of the foreign expression
6693 inline bool Columns<MT,false,true,true,CCAs...>::isAliased( const Other* alias ) const noexcept
6694 {
6695  return matrix_.isAliased( alias );
6696 }
6698 //*************************************************************************************************
6699 
6700 
6701 //*************************************************************************************************
6713 template< typename MT // Type of the dense matrix
6714  , typename... CCAs > // Compile time column arguments
6715 template< typename MT2 // Data type of the foreign dense column selection
6716  , bool SO2 // Storage order of the foreign dense column selection
6717  , bool SF2 // Symmetry flag of the foreign dense column selection
6718  , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
6719 inline bool
6720  Columns<MT,false,true,true,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
6721 {
6722  return matrix_.isAliased( &alias->matrix_ );
6723 }
6725 //*************************************************************************************************
6726 
6727 
6728 //*************************************************************************************************
6738 template< typename MT // Type of the dense matrix
6739  , typename... CCAs > // Compile time column arguments
6740 inline bool Columns<MT,false,true,true,CCAs...>::isAligned() const noexcept
6741 {
6742  return matrix_.isAligned();
6743 }
6745 //*************************************************************************************************
6746 
6747 
6748 //*************************************************************************************************
6759 template< typename MT // Type of the dense matrix
6760  , typename... CCAs > // Compile time column arguments
6761 inline bool Columns<MT,false,true,true,CCAs...>::canSMPAssign() const noexcept
6762 {
6763  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
6764 }
6766 //*************************************************************************************************
6767 
6768 
6769 //*************************************************************************************************
6784 template< typename MT // Type of the dense matrix
6785  , typename... CCAs > // Compile time column arguments
6786 BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6787  Columns<MT,false,true,true,CCAs...>::load( size_t i, size_t j ) const noexcept
6788 {
6789  return matrix_.load( idx(j), i );
6790 }
6792 //*************************************************************************************************
6793 
6794 
6795 //*************************************************************************************************
6810 template< typename MT // Type of the dense matrix
6811  , typename... CCAs > // Compile time column arguments
6812 BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6813  Columns<MT,false,true,true,CCAs...>::loada( size_t i, size_t j ) const noexcept
6814 {
6815  return matrix_.loada( idx(j), i );
6816 }
6818 //*************************************************************************************************
6819 
6820 
6821 //*************************************************************************************************
6836 template< typename MT // Type of the dense matrix
6837  , typename... CCAs > // Compile time column arguments
6838 BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6839  Columns<MT,false,true,true,CCAs...>::loadu( size_t i, size_t j ) const noexcept
6840 {
6841  return matrix_.loadu( idx(j), i );
6842 }
6844 //*************************************************************************************************
6845 
6846 } // namespace blaze
6847 
6848 #endif
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:133
Header file for the blaze::checked and blaze::unchecked instances.
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:432
Header file for the implementation of the Columns base template.
Header file for kernel specific block sizes.
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,...
Definition: Assert.h:117
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:170
Header file for the View base class.
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.The IsSIMDCombinable_v variable templ...
Definition: IsSIMDCombinable.h:137
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
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:332
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:372
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:595
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e....
Definition: Submatrix.h:81
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
Header file for the MAYBE_UNUSED function template.
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:584
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a symmetric matrix type,...
Definition: Symmetric.h:60
Header file for the reset shim.
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.The HasSIMDAdd_v variable template provides...
Definition: HasSIMDAdd.h:187
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i....
Definition: TransExpr.h:81
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
Header file for the RequiresEvaluation type trait.
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
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:253
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.
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:1361
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
decltype(auto) operator *(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:9091
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.The HasSIMDSub_v variable template provides...
Definition: HasSIMDSub.h:187
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
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
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsNumeric_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
Header file for all SIMD functionality.
constexpr bool Contains_v
Auxiliary variable template for the Contains type trait.The Contains_v variable template provides a c...
Definition: Contains.h:138
Header file for the IsLower type trait.
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
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
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,...
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
Header file for run time assertion macros.
Header file for the 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,...
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.
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:408
Header file for the HasMutableDataAccess type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
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 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
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
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.The HasSIMDMult_v variable template provid...
Definition: HasSIMDMult.h:188
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:264
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:635
#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,...
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
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
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.The IsDiagonal_v variable template provides...
Definition: IsDiagonal.h:148
Header file for the IsRestricted type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression,...
Definition: Assert.h:101
constexpr bool IsSparseMatrix_v
Auxiliary variable template for the IsSparseMatrix type trait.The IsSparseMatrix_v variable template ...
Definition: IsSparseMatrix.h:138
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