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>
83 #include <blaze/math/views/Check.h>
86 #include <blaze/system/Blocking.h>
87 #include <blaze/system/CacheSize.h>
88 #include <blaze/system/Inline.h>
91 #include <blaze/util/Assert.h>
96 #include <blaze/util/DisableIf.h>
97 #include <blaze/util/EnableIf.h>
98 #include <blaze/util/mpl/And.h>
99 #include <blaze/util/mpl/If.h>
100 #include <blaze/util/mpl/Not.h>
101 #include <blaze/util/mpl/Or.h>
102 #include <blaze/util/Template.h>
103 #include <blaze/util/TypeList.h>
104 #include <blaze/util/Types.h>
107 #include <blaze/util/Unused.h>
108 
109 
110 namespace blaze {
111 
112 //=================================================================================================
113 //
114 // CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR DENSE MATRICES
115 //
116 //=================================================================================================
117 
118 //*************************************************************************************************
126 template< typename MT // Type of the dense matrix
127  , bool SF // Symmetry flag
128  , size_t... CCAs > // Compile time column arguments
129 class Columns<MT,true,true,SF,CCAs...>
130  : public View< DenseMatrix< Columns<MT,true,true,SF,CCAs...>, true > >
131  , private ColumnsData<CCAs...>
132 {
133  private:
134  //**Type definitions****************************************************************************
135  using DataType = ColumnsData<CCAs...>;
136  using Operand = If_< IsExpression<MT>, MT, MT& >;
137  //**********************************************************************************************
138 
139  public:
140  //**Type definitions****************************************************************************
142  using This = Columns<MT,true,true,SF,CCAs...>;
143 
144  using BaseType = DenseMatrix<This,true>;
145  using ViewedType = MT;
146  using ResultType = ColumnsTrait_<MT,CCAs...>;
147  using OppositeType = OppositeType_<ResultType>;
148  using TransposeType = TransposeType_<ResultType>;
149  using ElementType = ElementType_<MT>;
150  using SIMDType = SIMDTrait_<ElementType>;
151  using ReturnType = ReturnType_<MT>;
152  using CompositeType = const Columns&;
153 
155  using ConstReference = ConstReference_<MT>;
156 
158  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
159 
161  using ConstPointer = ConstPointer_<MT>;
162 
164  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, Pointer_<MT> >;
165 
167  using ConstIterator = ConstIterator_<MT>;
168 
170  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
171  //**********************************************************************************************
172 
173  //**Compilation flags***************************************************************************
175  enum : bool { simdEnabled = MT::simdEnabled };
176 
178  enum : bool { smpAssignable = MT::smpAssignable };
179  //**********************************************************************************************
180 
181  //**Constructors********************************************************************************
184  template< typename... RCAs >
185  explicit inline Columns( MT& matrix, RCAs... args );
186 
187  inline Columns( const Columns& ) = default;
188  inline Columns( Columns&& ) = default;
190  //**********************************************************************************************
191 
192  //**Destructor**********************************************************************************
193  // No explicitly declared destructor.
194  //**********************************************************************************************
195 
196  //**Data access functions***********************************************************************
199  inline Reference operator()( size_t i, size_t j );
200  inline ConstReference operator()( size_t i, size_t j ) const;
201  inline Reference at( size_t i, size_t j );
202  inline ConstReference at( size_t i, size_t j ) const;
203  inline Pointer data () noexcept;
204  inline ConstPointer data () const noexcept;
205  inline Pointer data ( size_t j ) noexcept;
206  inline ConstPointer data ( size_t j ) const noexcept;
207  inline Iterator begin ( size_t j );
208  inline ConstIterator begin ( size_t j ) const;
209  inline ConstIterator cbegin( size_t j ) const;
210  inline Iterator end ( size_t j );
211  inline ConstIterator end ( size_t j ) const;
212  inline ConstIterator cend ( size_t j ) const;
214  //**********************************************************************************************
215 
216  //**Assignment operators************************************************************************
219  inline Columns& operator=( const ElementType& rhs );
220  inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
221  inline Columns& operator=( const Columns& rhs );
222 
223  template< typename MT2, bool SO2 >
224  inline Columns& operator=( const Matrix<MT2,SO2>& rhs );
225 
226  template< typename MT2, bool SO2 >
227  inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
228  operator+=( const Matrix<MT2,SO2>& rhs );
229 
230  template< typename MT2, bool SO2 >
231  inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
232  operator+=( const Matrix<MT2,SO2>& rhs );
233 
234  template< typename MT2, bool SO2 >
235  inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
236  operator-=( const Matrix<MT2,SO2>& rhs );
237 
238  template< typename MT2, bool SO2 >
239  inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
240  operator-=( const Matrix<MT2,SO2>& rhs );
241 
242  template< typename MT2, bool SO2 >
243  inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
244  operator%=( const Matrix<MT2,SO2>& rhs );
245 
246  template< typename MT2, bool SO2 >
247  inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
248  operator%=( const Matrix<MT2,SO2>& rhs );
250  //**********************************************************************************************
251 
252  //**Utility functions***************************************************************************
255  using DataType::idx;
256  using DataType::idces;
257  using DataType::columns;
258 
259  inline MT& operand() noexcept;
260  inline const MT& operand() const noexcept;
261 
262  inline size_t rows() const noexcept;
263  inline size_t spacing() const noexcept;
264  inline size_t capacity() const noexcept;
265  inline size_t capacity( size_t j ) const noexcept;
266  inline size_t nonZeros() const;
267  inline size_t nonZeros( size_t j ) const;
268  inline void reset();
269  inline void reset( size_t j );
271  //**********************************************************************************************
272 
273  //**Numeric functions***************************************************************************
276  inline Columns& transpose();
277  inline Columns& ctranspose();
278 
279  template< typename Other > inline Columns& scale( const Other& scalar );
281  //**********************************************************************************************
282 
283  private:
284  //**********************************************************************************************
286  template< typename MT2 >
287  struct VectorizedAssign {
288  enum : bool { value = useOptimizedKernels &&
289  simdEnabled && MT2::simdEnabled &&
290  IsSIMDCombinable< ElementType, ElementType_<MT2> >::value };
291  };
292  //**********************************************************************************************
293 
294  //**********************************************************************************************
296  template< typename MT2 >
297  struct VectorizedAddAssign {
298  enum : bool { value = useOptimizedKernels &&
299  simdEnabled && MT2::simdEnabled &&
300  IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
301  HasSIMDAdd< ElementType, ElementType_<MT2> >::value &&
302  !IsDiagonal<MT2>::value };
303  };
304  //**********************************************************************************************
305 
306  //**********************************************************************************************
308  template< typename MT2 >
309  struct VectorizedSubAssign {
310  enum : bool { value = useOptimizedKernels &&
311  simdEnabled && MT2::simdEnabled &&
312  IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
313  HasSIMDSub< ElementType, ElementType_<MT2> >::value &&
314  !IsDiagonal<MT2>::value };
315  };
316  //**********************************************************************************************
317 
318  //**********************************************************************************************
320  template< typename MT2 >
321  struct VectorizedSchurAssign {
322  enum : bool { value = useOptimizedKernels &&
323  simdEnabled && MT2::simdEnabled &&
324  IsSIMDCombinable< ElementType, ElementType_<MT2> >::value &&
325  HasSIMDMult< ElementType, ElementType_<MT2> >::value };
326  };
327  //**********************************************************************************************
328 
329  //**SIMD properties*****************************************************************************
331  enum : size_t { SIMDSIZE = SIMDTrait<ElementType>::size };
332  //**********************************************************************************************
333 
334  public:
335  //**Expression template evaluation functions****************************************************
338  template< typename Other >
339  inline bool canAlias( const Other* alias ) const noexcept;
340 
341  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
342  inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
343 
344  template< typename Other >
345  inline bool isAliased( const Other* alias ) const noexcept;
346 
347  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
348  inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
349 
350  inline bool isAligned () const noexcept;
351  inline bool canSMPAssign() const noexcept;
352 
353  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
354  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
355  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
356 
357  BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
358  BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
359  BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
360  BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
361 
362  template< typename MT2 >
363  inline DisableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,true>& rhs );
364 
365  template< typename MT2 >
366  inline EnableIf_< VectorizedAssign<MT2> > assign( const DenseMatrix<MT2,true>& rhs );
367 
368  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
369 
370  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
371  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
372 
373  template< typename MT2 >
374  inline DisableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,true>& rhs );
375 
376  template< typename MT2 >
377  inline EnableIf_< VectorizedAddAssign<MT2> > addAssign( const DenseMatrix<MT2,true>& rhs );
378 
379  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
380  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
381  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
382 
383  template< typename MT2 >
384  inline DisableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,true>& rhs );
385 
386  template< typename MT2 >
387  inline EnableIf_< VectorizedSubAssign<MT2> > subAssign( const DenseMatrix<MT2,true>& rhs );
388 
389  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
390  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
391  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
392 
393  template< typename MT2 >
394  inline DisableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,true>& rhs );
395 
396  template< typename MT2 >
397  inline EnableIf_< VectorizedSchurAssign<MT2> > schurAssign( const DenseMatrix<MT2,true>& rhs );
398 
399  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
400  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
401  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
403  //**********************************************************************************************
404 
405  private:
406  //**Member variables****************************************************************************
409  Operand matrix_;
410 
411  //**********************************************************************************************
412 
413  //**Friend declarations*************************************************************************
414  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Columns;
415  //**********************************************************************************************
416 
417  //**Compile time checks*************************************************************************
426  //**********************************************************************************************
427 };
429 //*************************************************************************************************
430 
431 
432 
433 
434 //=================================================================================================
435 //
436 // CONSTRUCTORS
437 //
438 //=================================================================================================
439 
440 //*************************************************************************************************
453 template< typename MT // Type of the dense matrix
454  , bool SF // Symmetry flag
455  , size_t... CCAs > // Compile time column arguments
456 template< typename... RCAs > // Runtime column arguments
457 inline Columns<MT,true,true,SF,CCAs...>::Columns( MT& matrix, RCAs... args )
458  : DataType( args... ) // Base class initialization
459  , matrix_ ( matrix ) // The matrix containing the columns
460 {
461  if( !Contains< TypeList<RCAs...>, Unchecked >::value ) {
462  for( size_t j=0UL; j<columns(); ++j ) {
463  if( matrix_.columns() <= idx(j) ) {
464  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
465  }
466  }
467  }
468 }
470 //*************************************************************************************************
471 
472 
473 
474 
475 //=================================================================================================
476 //
477 // DATA ACCESS FUNCTIONS
478 //
479 //=================================================================================================
480 
481 //*************************************************************************************************
492 template< typename MT // Type of the dense matrix
493  , bool SF // Symmetry flag
494  , size_t... CCAs > // Compile time column arguments
495 inline typename Columns<MT,true,true,SF,CCAs...>::Reference
496  Columns<MT,true,true,SF,CCAs...>::operator()( size_t i, size_t j )
497 {
498  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
499  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
500 
501  return matrix_(i,idx(j));
502 }
504 //*************************************************************************************************
505 
506 
507 //*************************************************************************************************
518 template< typename MT // Type of the dense matrix
519  , bool SF // Symmetry flag
520  , size_t... CCAs > // Compile time column arguments
521 inline typename Columns<MT,true,true,SF,CCAs...>::ConstReference
522  Columns<MT,true,true,SF,CCAs...>::operator()( size_t i, size_t j ) const
523 {
524  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
525  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
526 
527  return const_cast<const MT&>( matrix_ )(i,idx(j));
528 }
530 //*************************************************************************************************
531 
532 
533 //*************************************************************************************************
545 template< typename MT // Type of the dense matrix
546  , bool SF // Symmetry flag
547  , size_t... CCAs > // Compile time column arguments
548 inline typename Columns<MT,true,true,SF,CCAs...>::Reference
549  Columns<MT,true,true,SF,CCAs...>::at( size_t i, size_t j )
550 {
551  if( i >= rows() ) {
552  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
553  }
554  if( j >= columns() ) {
555  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
556  }
557  return (*this)(i,j);
558 }
560 //*************************************************************************************************
561 
562 
563 //*************************************************************************************************
575 template< typename MT // Type of the dense matrix
576  , bool SF // Symmetry flag
577  , size_t... CCAs > // Compile time column arguments
578 inline typename Columns<MT,true,true,SF,CCAs...>::ConstReference
579  Columns<MT,true,true,SF,CCAs...>::at( size_t i, size_t j ) const
580 {
581  if( i >= rows() ) {
582  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
583  }
584  if( j >= columns() ) {
585  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
586  }
587  return (*this)(i,j);
588 }
590 //*************************************************************************************************
591 
592 
593 //*************************************************************************************************
603 template< typename MT // Type of the dense matrix
604  , bool SF // Symmetry flag
605  , size_t... CCAs > // Compile time column arguments
606 inline typename Columns<MT,true,true,SF,CCAs...>::Pointer
608 {
609  return matrix_.data( idx(0UL) );
610 }
612 //*************************************************************************************************
613 
614 
615 //*************************************************************************************************
625 template< typename MT // Type of the dense matrix
626  , bool SF // Symmetry flag
627  , size_t... CCAs > // Compile time column arguments
628 inline typename Columns<MT,true,true,SF,CCAs...>::ConstPointer
630 {
631  return matrix_.data( idx(0UL) );
632 }
634 //*************************************************************************************************
635 
636 
637 //*************************************************************************************************
646 template< typename MT // Type of the dense matrix
647  , bool SF // Symmetry flag
648  , size_t... CCAs > // Compile time column arguments
649 inline typename Columns<MT,true,true,SF,CCAs...>::Pointer
650  Columns<MT,true,true,SF,CCAs...>::data( size_t j ) noexcept
651 {
652  return matrix_.data( idx(j) );
653 }
655 //*************************************************************************************************
656 
657 
658 //*************************************************************************************************
667 template< typename MT // Type of the dense matrix
668  , bool SF // Symmetry flag
669  , size_t... CCAs > // Compile time column arguments
670 inline typename Columns<MT,true,true,SF,CCAs...>::ConstPointer
671  Columns<MT,true,true,SF,CCAs...>::data( size_t j ) const noexcept
672 {
673  return matrix_.data( idx(j) );
674 }
676 //*************************************************************************************************
677 
678 
679 //*************************************************************************************************
688 template< typename MT // Type of the dense matrix
689  , bool SF // Symmetry flag
690  , size_t... CCAs > // Compile time column arguments
691 inline typename Columns<MT,true,true,SF,CCAs...>::Iterator
693 {
694  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
695  return matrix_.begin( idx(j) );
696 }
698 //*************************************************************************************************
699 
700 
701 //*************************************************************************************************
710 template< typename MT // Type of the dense matrix
711  , bool SF // Symmetry flag
712  , size_t... CCAs > // Compile time column arguments
713 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
715 {
716  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
717  return matrix_.cbegin( idx(j) );
718 }
720 //*************************************************************************************************
721 
722 
723 //*************************************************************************************************
732 template< typename MT // Type of the dense matrix
733  , bool SF // Symmetry flag
734  , size_t... CCAs > // Compile time column arguments
735 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
737 {
738  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
739  return matrix_.cbegin( idx(j) );
740 }
742 //*************************************************************************************************
743 
744 
745 //*************************************************************************************************
754 template< typename MT // Type of the dense matrix
755  , bool SF // Symmetry flag
756  , size_t... CCAs > // Compile time column arguments
757 inline typename Columns<MT,true,true,SF,CCAs...>::Iterator
759 {
760  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
761  return matrix_.end( idx(j) );
762 }
764 //*************************************************************************************************
765 
766 
767 //*************************************************************************************************
776 template< typename MT // Type of the dense matrix
777  , bool SF // Symmetry flag
778  , size_t... CCAs > // Compile time column arguments
779 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
780  Columns<MT,true,true,SF,CCAs...>::end( size_t j ) const
781 {
782  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
783  return matrix_.cend( idx(j) );
784 }
786 //*************************************************************************************************
787 
788 
789 //*************************************************************************************************
798 template< typename MT // Type of the dense matrix
799  , bool SF // Symmetry flag
800  , size_t... CCAs > // Compile time column arguments
801 inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
803 {
804  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
805  return matrix_.cend( idx(j) );
806 }
808 //*************************************************************************************************
809 
810 
811 
812 
813 //=================================================================================================
814 //
815 // ASSIGNMENT OPERATORS
816 //
817 //=================================================================================================
818 
819 //*************************************************************************************************
830 template< typename MT // Type of the dense matrix
831  , bool SF // Symmetry flag
832  , size_t... CCAs > // Compile time column arguments
833 inline Columns<MT,true,true,SF,CCAs...>&
834  Columns<MT,true,true,SF,CCAs...>::operator=( const ElementType& rhs )
835 {
836  for( size_t j=0UL; j<columns(); ++j ) {
837  column( matrix_, idx(j), unchecked ) = rhs;
838  }
839 
840  return *this;
841 }
843 //*************************************************************************************************
844 
845 
846 //*************************************************************************************************
862 template< typename MT // Type of the dense matrix
863  , bool SF // Symmetry flag
864  , size_t... CCAs > // Compile time column arguments
865 inline Columns<MT,true,true,SF,CCAs...>&
866  Columns<MT,true,true,SF,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
867 {
870 
871  if( list.size() != rows() ) {
872  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
873  }
874 
875  if( IsRestricted<MT>::value ) {
876  const InitializerMatrix<ElementType> tmp( list, columns() );
877  for( size_t j=0UL; j<columns(); ++j ) {
878  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
879  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
880  }
881  }
882  }
883 
884  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
885  size_t i( 0UL );
886 
887  for( const auto& rowList : list ) {
888  size_t j( 0UL );
889  for( const auto& element : rowList ) {
890  matrix_(i,idx(j)) = element;
891  ++j;
892  }
893  for( ; j<columns(); ++j ) {
894  matrix_(i,idx(j)) = ElementType();
895  }
896  ++i;
897  }
898 
899  return *this;
900 }
902 //*************************************************************************************************
903 
904 
905 //*************************************************************************************************
920 template< typename MT // Type of the dense matrix
921  , bool SF // Symmetry flag
922  , size_t... CCAs > // Compile time column arguments
923 inline Columns<MT,true,true,SF,CCAs...>&
924  Columns<MT,true,true,SF,CCAs...>::operator=( const Columns& rhs )
925 {
928 
931 
932  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && idces() == rhs.idces() ) )
933  return *this;
934 
935  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
936  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
937  }
938 
939  if( IsRestricted<MT>::value ) {
940  for( size_t j=0UL; j<columns(); ++j ) {
941  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( rhs, j, unchecked ), 0UL ) ) {
942  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
943  }
944  }
945  }
946 
947  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
948 
949  if( rhs.canAlias( &matrix_ ) ) {
950  const ResultType tmp( rhs );
951  smpAssign( left, tmp );
952  }
953  else {
954  smpAssign( left, rhs );
955  }
956 
957  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
958 
959  return *this;
960 }
962 //*************************************************************************************************
963 
964 
965 //*************************************************************************************************
980 template< typename MT // Type of the dense matrix
981  , bool SF // Symmetry flag
982  , size_t... CCAs > // Compile time column arguments
983 template< typename MT2 // Type of the right-hand side matrix
984  , bool SO2 > // Storage order of the right-hand side matrix
985 inline Columns<MT,true,true,SF,CCAs...>&
986  Columns<MT,true,true,SF,CCAs...>::operator=( const Matrix<MT2,SO2>& rhs )
987 {
990 
992 
993  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
994  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
995  }
996 
997  using Right = If_< IsRestricted<MT>, CompositeType_<MT2>, const MT2& >;
998  Right right( ~rhs );
999 
1000  if( IsRestricted<MT>::value ) {
1001  for( size_t j=0UL; j<columns(); ++j ) {
1002  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( right, j, unchecked ), 0UL ) ) {
1003  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1004  }
1005  }
1006  }
1007 
1008  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1009 
1010  if( IsSparseMatrix<MT2>::value ) {
1011  reset();
1012  }
1013 
1014  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
1015  const ResultType_<MT2> tmp( right );
1016  smpAssign( left, tmp );
1017  }
1018  else {
1019  smpAssign( left, right );
1020  }
1021 
1022  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1023 
1024  return *this;
1025 }
1027 //*************************************************************************************************
1028 
1029 
1030 //*************************************************************************************************
1044 template< typename MT // Type of the dense matrix
1045  , bool SF // Symmetry flag
1046  , size_t... CCAs > // Compile time column arguments
1047 template< typename MT2 // Type of the right-hand side matrix
1048  , bool SO2 > // Storage order of the right-hand side matrix
1049 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,true,true,SF,CCAs...>& >
1050  Columns<MT,true,true,SF,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1051 {
1054 
1058 
1059  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
1060 
1063 
1064  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1065  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1066  }
1067 
1068  if( IsRestricted<MT>::value ) {
1069  for( size_t j=0UL; j<columns(); ++j ) {
1070  if( !tryAddAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
1071  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1072  }
1073  }
1074  }
1075 
1076  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1077 
1078  if( (~rhs).canAlias( &matrix_ ) ) {
1079  const AddType tmp( *this + (~rhs) );
1080  smpAssign( left, tmp );
1081  }
1082  else {
1083  smpAddAssign( left, ~rhs );
1084  }
1085 
1086  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1087 
1088  return *this;
1089 }
1091 //*************************************************************************************************
1092 
1093 
1094 //*************************************************************************************************
1108 template< typename MT // Type of the dense matrix
1109  , bool SF // Symmetry flag
1110  , size_t... CCAs > // Compile time column arguments
1111 template< typename MT2 // Type of the right-hand side matrix
1112  , bool SO2 > // Storage order of the right-hand side matrix
1113 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,true,true,SF,CCAs...>& >
1114  Columns<MT,true,true,SF,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1115 {
1118 
1122 
1123  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
1124 
1127 
1128  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1129  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1130  }
1131 
1132  const AddType tmp( *this + (~rhs) );
1133 
1134  if( IsRestricted<MT>::value ) {
1135  for( size_t j=0UL; j<columns(); ++j ) {
1136  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1137  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1138  }
1139  }
1140  }
1141 
1142  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1143 
1144  smpAssign( left, tmp );
1145 
1146  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1147 
1148  return *this;
1149 }
1151 //*************************************************************************************************
1152 
1153 
1154 //*************************************************************************************************
1168 template< typename MT // Type of the dense matrix
1169  , bool SF // Symmetry flag
1170  , size_t... CCAs > // Compile time column arguments
1171 template< typename MT2 // Type of the right-hand side matrix
1172  , bool SO2 > // Storage order of the right-hand side matrix
1173 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,true,true,SF,CCAs...>& >
1174  Columns<MT,true,true,SF,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1175 {
1178 
1182 
1183  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
1184 
1187 
1188  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1189  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1190  }
1191 
1192  if( IsRestricted<MT>::value ) {
1193  for( size_t j=0UL; j<columns(); ++j ) {
1194  if( !trySubAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
1195  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1196  }
1197  }
1198  }
1199 
1200  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1201 
1202  if( (~rhs).canAlias( &matrix_ ) ) {
1203  const SubType tmp( *this - (~rhs ) );
1204  smpAssign( left, tmp );
1205  }
1206  else {
1207  smpSubAssign( left, ~rhs );
1208  }
1209 
1210  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1211 
1212  return *this;
1213 }
1215 //*************************************************************************************************
1216 
1217 
1218 //*************************************************************************************************
1232 template< typename MT // Type of the dense matrix
1233  , bool SF // Symmetry flag
1234  , size_t... CCAs > // Compile time column arguments
1235 template< typename MT2 // Type of the right-hand side matrix
1236  , bool SO2 > // Storage order of the right-hand side matrix
1237 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,true,true,SF,CCAs...>& >
1238  Columns<MT,true,true,SF,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1239 {
1242 
1246 
1247  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
1248 
1251 
1252  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1253  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1254  }
1255 
1256  const SubType tmp( *this - (~rhs) );
1257 
1258  if( IsRestricted<MT>::value ) {
1259  for( size_t j=0UL; j<columns(); ++j ) {
1260  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1261  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1262  }
1263  }
1264  }
1265 
1266  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1267 
1268  smpAssign( left, tmp );
1269 
1270  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1271 
1272  return *this;
1273 }
1275 //*************************************************************************************************
1276 
1277 
1278 //*************************************************************************************************
1292 template< typename MT // Type of the dense matrix
1293  , bool SF // Symmetry flag
1294  , size_t... CCAs > // Compile time column arguments
1295 template< typename MT2 // Type of the right-hand side matrix
1296  , bool SO2 > // Storage order of the right-hand side matrix
1297 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,true,true,SF,CCAs...>& >
1298  Columns<MT,true,true,SF,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1299 {
1302 
1306 
1307  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
1308 
1310 
1311  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1312  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1313  }
1314 
1315  if( IsRestricted<MT>::value ) {
1316  for( size_t j=0UL; j<columns(); ++j ) {
1317  if( !tryMultAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
1318  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1319  }
1320  }
1321  }
1322 
1323  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1324 
1325  if( (~rhs).canAlias( &matrix_ ) ) {
1326  const SchurType tmp( *this % (~rhs) );
1327  if( IsSparseMatrix<SchurType>::value )
1328  reset();
1329  smpAssign( left, tmp );
1330  }
1331  else {
1332  smpSchurAssign( left, ~rhs );
1333  }
1334 
1335  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1336 
1337  return *this;
1338 }
1340 //*************************************************************************************************
1341 
1342 
1343 //*************************************************************************************************
1357 template< typename MT // Type of the dense matrix
1358  , bool SF // Symmetry flag
1359  , size_t... CCAs > // Compile time column arguments
1360 template< typename MT2 // Type of the right-hand side matrix
1361  , bool SO2 > // Storage order of the right-hand side matrix
1362 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,true,true,SF,CCAs...>& >
1363  Columns<MT,true,true,SF,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1364 {
1367 
1371 
1372  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
1373 
1375 
1376  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
1377  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1378  }
1379 
1380  const SchurType tmp( *this % (~rhs) );
1381 
1382  if( IsRestricted<MT>::value ) {
1383  for( size_t j=0UL; j<columns(); ++j ) {
1384  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1385  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1386  }
1387  }
1388  }
1389 
1390  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1391 
1392  if( IsSparseMatrix<SchurType>::value ) {
1393  reset();
1394  }
1395 
1396  smpAssign( left, tmp );
1397 
1398  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1399 
1400  return *this;
1401 }
1403 //*************************************************************************************************
1404 
1405 
1406 
1407 
1408 //=================================================================================================
1409 //
1410 // UTILITY FUNCTIONS
1411 //
1412 //=================================================================================================
1413 
1414 //*************************************************************************************************
1420 template< typename MT // Type of the dense matrix
1421  , bool SF // Symmetry flag
1422  , size_t... CCAs > // Compile time column arguments
1423 inline MT& Columns<MT,true,true,SF,CCAs...>::operand() noexcept
1424 {
1425  return matrix_;
1426 }
1428 //*************************************************************************************************
1429 
1430 
1431 //*************************************************************************************************
1437 template< typename MT // Type of the dense matrix
1438  , bool SF // Symmetry flag
1439  , size_t... CCAs > // Compile time column arguments
1440 inline const MT& Columns<MT,true,true,SF,CCAs...>::operand() const noexcept
1441 {
1442  return matrix_;
1443 }
1445 //*************************************************************************************************
1446 
1447 
1448 //*************************************************************************************************
1454 template< typename MT // Type of the dense matrix
1455  , bool SF // Symmetry flag
1456  , size_t... CCAs > // Compile time column arguments
1457 inline size_t Columns<MT,true,true,SF,CCAs...>::rows() const noexcept
1458 {
1459  return matrix_.rows();
1460 }
1462 //*************************************************************************************************
1463 
1464 
1465 //*************************************************************************************************
1474 template< typename MT // Type of the dense matrix
1475  , bool SF // Symmetry flag
1476  , size_t... CCAs > // Compile time column arguments
1477 inline size_t Columns<MT,true,true,SF,CCAs...>::spacing() const noexcept
1478 {
1479  return matrix_.spacing();
1480 }
1482 //*************************************************************************************************
1483 
1484 
1485 //*************************************************************************************************
1491 template< typename MT // Type of the dense matrix
1492  , bool SF // Symmetry flag
1493  , size_t... CCAs > // Compile time column arguments
1494 inline size_t Columns<MT,true,true,SF,CCAs...>::capacity() const noexcept
1495 {
1496  return rows() * columns();
1497 }
1499 //*************************************************************************************************
1500 
1501 
1502 //*************************************************************************************************
1511 template< typename MT // Type of the dense matrix
1512  , bool SF // Symmetry flag
1513  , size_t... CCAs > // Compile time column arguments
1514 inline size_t Columns<MT,true,true,SF,CCAs...>::capacity( size_t j ) const noexcept
1515 {
1516  UNUSED_PARAMETER( j );
1517 
1518  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1519 
1520  return rows();
1521 }
1523 //*************************************************************************************************
1524 
1525 
1526 //*************************************************************************************************
1532 template< typename MT // Type of the dense matrix
1533  , bool SF // Symmetry flag
1534  , size_t... CCAs > // Compile time column arguments
1535 inline size_t Columns<MT,true,true,SF,CCAs...>::nonZeros() const
1536 {
1537  size_t nonzeros( 0UL );
1538 
1539  for( size_t j=0UL; j<columns(); ++j ) {
1540  nonzeros += matrix_.nonZeros( idx(j) );
1541  }
1542 
1543  return nonzeros;
1544 }
1546 //*************************************************************************************************
1547 
1548 
1549 //*************************************************************************************************
1558 template< typename MT // Type of the dense matrix
1559  , bool SF // Symmetry flag
1560  , size_t... CCAs > // Compile time column arguments
1561 inline size_t Columns<MT,true,true,SF,CCAs...>::nonZeros( size_t j ) const
1562 {
1563  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1564 
1565  return matrix_.nonZeros( idx(j) );
1566 }
1568 //*************************************************************************************************
1569 
1570 
1571 //*************************************************************************************************
1577 template< typename MT // Type of the dense matrix
1578  , bool SF // Symmetry flag
1579  , size_t... CCAs > // Compile time column arguments
1581 {
1582  for( size_t j=0UL; j<columns(); ++j ) {
1583  matrix_.reset( idx(j) );
1584  }
1585 }
1587 //*************************************************************************************************
1588 
1589 
1590 //*************************************************************************************************
1599 template< typename MT // Type of the dense matrix
1600  , bool SF // Symmetry flag
1601  , size_t... CCAs > // Compile time column arguments
1602 inline void Columns<MT,true,true,SF,CCAs...>::reset( size_t j )
1603 {
1604  matrix_.reset( idx(j) );
1605 }
1607 //*************************************************************************************************
1608 
1609 
1610 
1611 
1612 //=================================================================================================
1613 //
1614 // NUMERIC FUNCTIONS
1615 //
1616 //=================================================================================================
1617 
1618 //*************************************************************************************************
1631 template< typename MT // Type of the dense matrix
1632  , bool SF // Symmetry flag
1633  , size_t... CCAs > // Compile time column arguments
1634 inline Columns<MT,true,true,SF,CCAs...>&
1636 {
1639 
1640  if( rows() != columns() ) {
1641  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1642  }
1643 
1644  const ResultType tmp( trans( *this ) );
1645 
1646  if( IsRestricted<MT>::value ) {
1647  for( size_t j=0UL; j<columns(); ++j ) {
1648  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
1649  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1650  }
1651  }
1652  }
1653 
1654  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1655 
1656  smpAssign( left, tmp );
1657 
1658  return *this;
1659 }
1661 //*************************************************************************************************
1662 
1663 
1664 //*************************************************************************************************
1677 template< typename MT // Type of the dense matrix
1678  , bool SF // Symmetry flag
1679  , size_t... CCAs > // Compile time column arguments
1680 inline Columns<MT,true,true,SF,CCAs...>&
1682 {
1685 
1686  if( rows() != columns() ) {
1687  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1688  }
1689 
1690  const ResultType tmp( ctrans( *this ) );
1691 
1692  if( IsRestricted<MT>::value ) {
1693  for( size_t j=0UL; j<columns(); ++j ) {
1694  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
1695  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1696  }
1697  }
1698  }
1699 
1700  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
1701 
1702  smpAssign( left, tmp );
1703 
1704  return *this;
1705 }
1707 //*************************************************************************************************
1708 
1709 
1710 //*************************************************************************************************
1723 template< typename MT // Type of the dense matrix
1724  , bool SF // Symmetry flag
1725  , size_t... CCAs > // Compile time column arguments
1726 template< typename Other > // Data type of the scalar value
1727 inline Columns<MT,true,true,SF,CCAs...>&
1728  Columns<MT,true,true,SF,CCAs...>::scale( const Other& scalar )
1729 {
1733 
1734  for( size_t j=0UL; j<columns(); ++j )
1735  {
1736  const size_t index ( idx(j) );
1737  const size_t ibegin( IsLower<MT>::value ? ( IsStrictlyLower<MT>::value ? index+1UL : index ) : 0UL );
1738  const size_t iend ( IsUpper<MT>::value ? ( IsStrictlyUpper<MT>::value ? index : index+1UL ) : rows() );
1739 
1740  for( size_t i=ibegin; i<iend; ++i ) {
1741  matrix_(i,index) *= scalar;
1742  }
1743  }
1744 
1745  return *this;
1746 }
1748 //*************************************************************************************************
1749 
1750 
1751 
1752 
1753 //=================================================================================================
1754 //
1755 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1756 //
1757 //=================================================================================================
1758 
1759 //*************************************************************************************************
1770 template< typename MT // Type of the dense matrix
1771  , bool SF // Symmetry flag
1772  , size_t... CCAs > // Compile time column arguments
1773 template< typename Other > // Data type of the foreign expression
1774 inline bool Columns<MT,true,true,SF,CCAs...>::canAlias( const Other* alias ) const noexcept
1775 {
1776  return matrix_.isAliased( alias );
1777 }
1779 //*************************************************************************************************
1780 
1781 
1782 //*************************************************************************************************
1794 template< typename MT // Type of the dense matrix
1795  , bool SF // Symmetry flag
1796  , size_t... CCAs > // Compile time column arguments
1797 template< typename MT2 // Data type of the foreign dense column selection
1798  , bool SO2 // Storage order of the foreign dense column selection
1799  , bool SF2 // Symmetry flag of the foreign dense column selection
1800  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column selection
1801 inline bool
1802  Columns<MT,true,true,SF,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1803 {
1804  return matrix_.isAliased( &alias->matrix_ );
1805 }
1807 //*************************************************************************************************
1808 
1809 
1810 //*************************************************************************************************
1821 template< typename MT // Type of the dense matrix
1822  , bool SF // Symmetry flag
1823  , size_t... CCAs > // Compile time column arguments
1824 template< typename Other > // Data type of the foreign expression
1825 inline bool Columns<MT,true,true,SF,CCAs...>::isAliased( const Other* alias ) const noexcept
1826 {
1827  return matrix_.isAliased( alias );
1828 }
1830 //*************************************************************************************************
1831 
1832 
1833 //*************************************************************************************************
1845 template< typename MT // Type of the dense matrix
1846  , bool SF // Symmetry flag
1847  , size_t... CCAs > // Compile time column arguments
1848 template< typename MT2 // Data type of the foreign dense column selection
1849  , bool SO2 // Storage order of the foreign dense column selection
1850  , bool SF2 // Symmetry flag of the foreign dense column selection
1851  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column selection
1852 inline bool
1853  Columns<MT,true,true,SF,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1854 {
1855  return matrix_.isAliased( &alias->matrix_ );
1856 }
1858 //*************************************************************************************************
1859 
1860 
1861 //*************************************************************************************************
1871 template< typename MT // Type of the dense matrix
1872  , bool SF // Symmetry flag
1873  , size_t... CCAs > // Compile time column arguments
1874 inline bool Columns<MT,true,true,SF,CCAs...>::isAligned() const noexcept
1875 {
1876  return matrix_.isAligned();
1877 }
1879 //*************************************************************************************************
1880 
1881 
1882 //*************************************************************************************************
1893 template< typename MT // Type of the dense matrix
1894  , bool SF // Symmetry flag
1895  , size_t... CCAs > // Compile time column arguments
1896 inline bool Columns<MT,true,true,SF,CCAs...>::canSMPAssign() const noexcept
1897 {
1898  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
1899 }
1901 //*************************************************************************************************
1902 
1903 
1904 //*************************************************************************************************
1919 template< typename MT // Type of the dense matrix
1920  , bool SF // Symmetry flag
1921  , size_t... CCAs > // Compile time column arguments
1922 BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1923  Columns<MT,true,true,SF,CCAs...>::load( size_t i, size_t j ) const noexcept
1924 {
1925  return matrix_.load( i, idx(j) );
1926 }
1928 //*************************************************************************************************
1929 
1930 
1931 //*************************************************************************************************
1946 template< typename MT // Type of the dense matrix
1947  , bool SF // Symmetry flag
1948  , size_t... CCAs > // Compile time column arguments
1949 BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1950  Columns<MT,true,true,SF,CCAs...>::loada( size_t i, size_t j ) const noexcept
1951 {
1952  return matrix_.loada( i, idx(j) );
1953 }
1955 //*************************************************************************************************
1956 
1957 
1958 //*************************************************************************************************
1973 template< typename MT // Type of the dense matrix
1974  , bool SF // Symmetry flag
1975  , size_t... CCAs > // Compile time column arguments
1976 BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1977  Columns<MT,true,true,SF,CCAs...>::loadu( size_t i, size_t j ) const noexcept
1978 {
1979  return matrix_.loadu( i, idx(j) );
1980 }
1982 //*************************************************************************************************
1983 
1984 
1985 //*************************************************************************************************
2001 template< typename MT // Type of the dense matrix
2002  , bool SF // Symmetry flag
2003  , size_t... CCAs > // Compile time column arguments
2005  Columns<MT,true,true,SF,CCAs...>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2006 {
2007  matrix_.store( i, idx(j), value );
2008 }
2010 //*************************************************************************************************
2011 
2012 
2013 //*************************************************************************************************
2029 template< typename MT // Type of the dense matrix
2030  , bool SF // Symmetry flag
2031  , size_t... CCAs > // Compile time column arguments
2033  Columns<MT,true,true,SF,CCAs...>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2034 {
2035  matrix_.storea( i, idx(j), value );
2036 }
2038 //*************************************************************************************************
2039 
2040 
2041 //*************************************************************************************************
2057 template< typename MT // Type of the dense matrix
2058  , bool SF // Symmetry flag
2059  , size_t... CCAs > // Compile time column arguments
2061  Columns<MT,true,true,SF,CCAs...>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2062 {
2063  matrix_.storeu( i, idx(j), value );
2064 }
2066 //*************************************************************************************************
2067 
2068 
2069 //*************************************************************************************************
2085 template< typename MT // Type of the dense matrix
2086  , bool SF // Symmetry flag
2087  , size_t... CCAs > // Compile time column arguments
2089  Columns<MT,true,true,SF,CCAs...>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2090 {
2091  matrix_.stream( i, idx(j), value );
2092 }
2094 //*************************************************************************************************
2095 
2096 
2097 //*************************************************************************************************
2109 template< typename MT // Type of the dense matrix
2110  , bool SF // Symmetry flag
2111  , size_t... CCAs > // Compile time column arguments
2112 template< typename MT2 > // Type of the right-hand side dense matrix
2113 inline DisableIf_< typename Columns<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
2114  Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2115 {
2118 
2119  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2120  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2121 
2122  const size_t ipos( rows() & size_t(-2) );
2123  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2124 
2125  for( size_t j=0UL; j<columns(); ++j ) {
2126  const size_t index( idx(j) );
2127  for( size_t i=0UL; i<ipos; i+=2UL ) {
2128  matrix_(i ,index) = (~rhs)(i ,j);
2129  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
2130  }
2131  if( ipos < rows() ) {
2132  matrix_(ipos,index) = (~rhs)(ipos,j);
2133  }
2134  }
2135 }
2137 //*************************************************************************************************
2138 
2139 
2140 //*************************************************************************************************
2152 template< typename MT // Type of the dense matrix
2153  , bool SF // Symmetry flag
2154  , size_t... CCAs > // Compile time column arguments
2155 template< typename MT2 > // Type of the right-hand side dense matrix
2156 inline EnableIf_< typename Columns<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedAssign<MT2> >
2157  Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2158 {
2161 
2163 
2164  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2165  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2166 
2167  const size_t ipos( rows() & size_t(-SIMDSIZE) );
2168  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2169 
2170  if( useStreaming &&
2171  rows()*columns() > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2172  !(~rhs).isAliased( &matrix_ ) )
2173  {
2174  for( size_t j=0UL; j<columns(); ++j )
2175  {
2176  size_t i( 0UL );
2177  Iterator left( begin(j) );
2178  ConstIterator_<MT2> right( (~rhs).begin(j) );
2179 
2180  for( ; i<ipos; i+=SIMDSIZE ) {
2181  left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2182  }
2183  for( ; i<rows(); ++i ) {
2184  *left = *right;
2185  }
2186  }
2187  }
2188  else
2189  {
2190  for( size_t j=0UL; j<columns(); ++j )
2191  {
2192  size_t i( 0UL );
2193  Iterator left( begin(j) );
2194  ConstIterator_<MT2> right( (~rhs).begin(j) );
2195 
2196  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2197  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2198  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2199  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2200  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2201  }
2202  for( ; i<ipos; i+=SIMDSIZE ) {
2203  left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2204  }
2205  for( ; i<rows(); ++i ) {
2206  *left = *right; ++left; ++right;
2207  }
2208  }
2209  }
2210 }
2212 //*************************************************************************************************
2213 
2214 
2215 //*************************************************************************************************
2227 template< typename MT // Type of the dense matrix
2228  , bool SF // Symmetry flag
2229  , size_t... CCAs > // Compile time column arguments
2230 template< typename MT2 > // Type of the right-hand side dense matrix
2231 inline void Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2232 {
2235 
2237 
2238  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2239  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2240 
2241  constexpr size_t block( BLOCK_SIZE );
2242 
2243  if( rows() < block && columns() < block )
2244  {
2245  const size_t ipos( (~rhs).rows() & size_t(-2) );
2246  for( size_t j=0UL; j<columns(); ++j ) {
2247  const size_t index( idx(j) );
2248  for( size_t i=0UL; i<ipos; i+=2UL ) {
2249  matrix_(i ,index) = (~rhs)(i ,j);
2250  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
2251  }
2252  if( ipos < (~rhs).rows() ) {
2253  matrix_(ipos,index) = (~rhs)(ipos,j);
2254  }
2255  }
2256  }
2257  else
2258  {
2259  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2260  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2261  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2262  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2263  for( size_t j=jj; j<jend; ++j ) {
2264  const size_t index( idx(j) );
2265  for( size_t i=ii; i<iend; ++i ) {
2266  matrix_(i,index) = (~rhs)(i,j);
2267  }
2268  }
2269  }
2270  }
2271  }
2272 }
2274 //*************************************************************************************************
2275 
2276 
2277 //*************************************************************************************************
2289 template< typename MT // Type of the dense matrix
2290  , bool SF // Symmetry flag
2291  , size_t... CCAs > // Compile time column arguments
2292 template< typename MT2 > // Type of the right-hand side sparse matrix
2293 inline void Columns<MT,true,true,SF,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2294 {
2297 
2298  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2299  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2300 
2301  for( size_t j=0UL; j<columns(); ++j ) {
2302  const size_t index( idx(j) );
2303  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2304  matrix_(element->index(),index) = element->value();
2305  }
2306 }
2308 //*************************************************************************************************
2309 
2310 
2311 //*************************************************************************************************
2323 template< typename MT // Type of the dense matrix
2324  , bool SF // Symmetry flag
2325  , size_t... CCAs > // Compile time column arguments
2326 template< typename MT2 > // Type of the right-hand side sparse matrix
2327 inline void Columns<MT,true,true,SF,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2328 {
2331 
2333 
2334  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2335  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2336 
2337  for( size_t i=0UL; i<rows(); ++i ) {
2338  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2339  matrix_(i,idx(element->index())) = element->value();
2340  }
2341 }
2343 //*************************************************************************************************
2344 
2345 
2346 //*************************************************************************************************
2358 template< typename MT // Type of the dense matrix
2359  , bool SF // Symmetry flag
2360  , size_t... CCAs > // Compile time column arguments
2361 template< typename MT2 > // Type of the right-hand side dense matrix
2362 inline DisableIf_< typename Columns<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
2363  Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2364 {
2367 
2368  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2369  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2370 
2371  const size_t ipos( rows() & size_t(-2) );
2372  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2373 
2374  for( size_t j=0UL; j<columns(); ++j )
2375  {
2376  const size_t index( idx(j) );
2377  if( IsDiagonal<MT2>::value ) {
2378  matrix_(j,index) += (~rhs)(j,j);
2379  }
2380  else {
2381  for( size_t i=0UL; i<ipos; i+=2UL ) {
2382  matrix_(i ,index) += (~rhs)(i ,j);
2383  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
2384  }
2385  if( ipos < rows() ) {
2386  matrix_(ipos,index) += (~rhs)(ipos,j);
2387  }
2388  }
2389  }
2390 }
2392 //*************************************************************************************************
2393 
2394 
2395 //*************************************************************************************************
2407 template< typename MT // Type of the dense matrix
2408  , bool SF // Symmetry flag
2409  , size_t... CCAs > // Compile time column arguments
2410 template< typename MT2 > // Type of the right-hand side dense matrix
2411 inline EnableIf_< typename Columns<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedAddAssign<MT2> >
2412  Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2413 {
2416 
2418 
2419  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2420  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2421 
2422  for( size_t j=0UL; j<columns(); ++j )
2423  {
2424  const size_t ibegin( ( IsLower<MT2>::value )
2425  ?( ( IsStrictlyLower<MT2>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
2426  :( 0UL ) );
2427  const size_t iend ( ( IsUpper<MT2>::value )
2428  ?( IsStrictlyUpper<MT2>::value ? j : j+1UL )
2429  :( rows() ) );
2430  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
2431 
2432  const size_t ipos( iend & size_t(-SIMDSIZE) );
2433  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2434 
2435  size_t i( ibegin );
2436  Iterator left( begin(j) + ibegin );
2437  ConstIterator_<MT2> right( (~rhs).begin(j) + ibegin );
2438 
2439  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2440  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2441  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2442  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2443  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2444  }
2445  for( ; i<ipos; i+=SIMDSIZE ) {
2446  left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2447  }
2448  for( ; i<iend; ++i ) {
2449  *left += *right; ++left; ++right;
2450  }
2451  }
2452 }
2454 //*************************************************************************************************
2455 
2456 
2457 //*************************************************************************************************
2469 template< typename MT // Type of the dense matrix
2470  , bool SF // Symmetry flag
2471  , size_t... CCAs > // Compile time column arguments
2472 template< typename MT2 > // Type of the right-hand side dense matrix
2473 inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2474 {
2477 
2479 
2480  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2481  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2482 
2483  constexpr size_t block( BLOCK_SIZE );
2484 
2485  if( rows() < block && columns() < block )
2486  {
2487  const size_t ipos( (~rhs).rows() & size_t(-2) );
2488  for( size_t j=0UL; j<columns(); ++j ) {
2489  const size_t index( idx(j) );
2490  for( size_t i=0UL; i<ipos; i+=2UL ) {
2491  matrix_(i ,index) += (~rhs)(i ,j);
2492  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
2493  }
2494  if( ipos < (~rhs).rows() )
2495  matrix_(ipos,index) += (~rhs)(ipos,j);
2496  }
2497  }
2498  else
2499  {
2500  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2501  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2502  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2503  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2504  for( size_t j=jj; j<jend; ++j ) {
2505  const size_t index( idx(j) );
2506  for( size_t i=ii; i<iend; ++i ) {
2507  matrix_(i,index) += (~rhs)(i,j);
2508  }
2509  }
2510  }
2511  }
2512  }
2513 }
2515 //*************************************************************************************************
2516 
2517 
2518 //*************************************************************************************************
2530 template< typename MT // Type of the dense matrix
2531  , bool SF // Symmetry flag
2532  , size_t... CCAs > // Compile time column arguments
2533 template< typename MT2 > // Type of the right-hand side sparse matrix
2534 inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
2535 {
2538 
2539  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2540  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2541 
2542  for( size_t j=0UL; j<columns(); ++j ) {
2543  const size_t index( idx(j) );
2544  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2545  matrix_(element->index(),index) += element->value();
2546  }
2547 }
2549 //*************************************************************************************************
2550 
2551 
2552 //*************************************************************************************************
2564 template< typename MT // Type of the dense matrix
2565  , bool SF // Symmetry flag
2566  , size_t... CCAs > // Compile time column arguments
2567 template< typename MT2 > // Type of the right-hand side sparse matrix
2568 inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
2569 {
2572 
2574 
2575  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2576  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2577 
2578  for( size_t i=0UL; i<rows(); ++i ) {
2579  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2580  matrix_(i,idx(element->index())) += element->value();
2581  }
2582 }
2584 //*************************************************************************************************
2585 
2586 
2587 //*************************************************************************************************
2599 template< typename MT // Type of the dense matrix
2600  , bool SF // Symmetry flag
2601  , size_t... CCAs > // Compile time column arguments
2602 template< typename MT2 > // Type of the right-hand side dense matrix
2603 inline DisableIf_< typename Columns<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
2604  Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2605 {
2608 
2609  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2610  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2611 
2612  const size_t ipos( rows() & size_t(-2) );
2613  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2614 
2615  for( size_t j=0UL; j<columns(); ++j )
2616  {
2617  const size_t index( idx(j) );
2618 
2619  if( IsDiagonal<MT2>::value ) {
2620  matrix_(j,index) -= (~rhs)(j,j);
2621  }
2622  else {
2623  for( size_t i=0UL; i<ipos; i+=2UL ) {
2624  matrix_(i ,index) -= (~rhs)(i ,j);
2625  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
2626  }
2627  if( ipos < rows() ) {
2628  matrix_(ipos,index) -= (~rhs)(ipos,j);
2629  }
2630  }
2631  }
2632 }
2634 //*************************************************************************************************
2635 
2636 
2637 //*************************************************************************************************
2649 template< typename MT // Type of the dense matrix
2650  , bool SF // Symmetry flag
2651  , size_t... CCAs > // Compile time column arguments
2652 template< typename MT2 > // Type of the right-hand side dense matrix
2653 inline EnableIf_< typename Columns<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedSubAssign<MT2> >
2654  Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2655 {
2658 
2660 
2661  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2662  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2663 
2664  for( size_t j=0UL; j<columns(); ++j )
2665  {
2666  const size_t ibegin( ( IsLower<MT2>::value )
2667  ?( ( IsStrictlyLower<MT2>::value ? j+1UL : j ) & size_t(-SIMDSIZE) )
2668  :( 0UL ) );
2669  const size_t iend ( ( IsUpper<MT2>::value )
2670  ?( IsStrictlyUpper<MT2>::value ? j : j+1UL )
2671  :( rows() ) );
2672  BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
2673 
2674  const size_t ipos( iend & size_t(-SIMDSIZE) );
2675  BLAZE_INTERNAL_ASSERT( ( iend - ( iend % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2676 
2677  size_t i( ibegin );
2678  Iterator left( begin(j) + ibegin );
2679  ConstIterator_<MT2> right( (~rhs).begin(j) + ibegin );
2680 
2681  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2682  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2683  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2684  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2685  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2686  }
2687  for( ; i<ipos; i+=SIMDSIZE ) {
2688  left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2689  }
2690  for( ; i<iend; ++i ) {
2691  *left -= *right; ++left; ++right;
2692  }
2693  }
2694 }
2696 //*************************************************************************************************
2697 
2698 
2699 //*************************************************************************************************
2711 template< typename MT // Type of the dense matrix
2712  , bool SF // Symmetry flag
2713  , size_t... CCAs > // Compile time column arguments
2714 template< typename MT2 > // Type of the right-hand side dense matrix
2715 inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2716 {
2719 
2721 
2722  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2723  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2724 
2725  constexpr size_t block( BLOCK_SIZE );
2726 
2727  if( rows() < block && columns() < block )
2728  {
2729  const size_t ipos( (~rhs).rows() & size_t(-2) );
2730  for( size_t j=0UL; j<columns(); ++j ) {
2731  const size_t index( idx(j) );
2732  for( size_t i=0UL; i<ipos; i+=2UL ) {
2733  matrix_(i ,index) -= (~rhs)(i ,j);
2734  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
2735  }
2736  if( ipos < (~rhs).rows() )
2737  matrix_(ipos,index) -= (~rhs)(ipos,j);
2738  }
2739  }
2740  else
2741  {
2742  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2743  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2744  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2745  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2746  for( size_t j=jj; j<jend; ++j ) {
2747  const size_t index( idx(j) );
2748  for( size_t i=ii; i<iend; ++i ) {
2749  matrix_(i,index) -= (~rhs)(i,j);
2750  }
2751  }
2752  }
2753  }
2754  }
2755 }
2757 //*************************************************************************************************
2758 
2759 
2760 //*************************************************************************************************
2772 template< typename MT // Type of the dense matrix
2773  , bool SF // Symmetry flag
2774  , size_t... CCAs > // Compile time column arguments
2775 template< typename MT2 > // Type of the right-hand side sparse matrix
2776 inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
2777 {
2780 
2781  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2782  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2783 
2784  for( size_t j=0UL; j<columns(); ++j ) {
2785  const size_t index( idx(j) );
2786  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
2787  matrix_(element->index(),index) -= element->value();
2788  }
2789 }
2791 //*************************************************************************************************
2792 
2793 
2794 //*************************************************************************************************
2806 template< typename MT // Type of the dense matrix
2807  , bool SF // Symmetry flag
2808  , size_t... CCAs > // Compile time column arguments
2809 template< typename MT2 > // Type of the right-hand side sparse matrix
2810 inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
2811 {
2814 
2816 
2817  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2818  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2819 
2820  for( size_t i=0UL; i<rows(); ++i ) {
2821  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
2822  matrix_(i,idx(element->index())) -= element->value();
2823  }
2824 }
2826 //*************************************************************************************************
2827 
2828 
2829 //*************************************************************************************************
2841 template< typename MT // Type of the dense matrix
2842  , bool SF // Symmetry flag
2843  , size_t... CCAs > // Compile time column arguments
2844 template< typename MT2 > // Type of the right-hand side dense matrix
2845 inline DisableIf_< typename Columns<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
2846  Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2847 {
2850 
2851  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2852  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2853 
2854  const size_t ipos( rows() & size_t(-2) );
2855  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
2856 
2857  for( size_t j=0UL; j<columns(); ++j ) {
2858  const size_t index( idx(j) );
2859  for( size_t i=0UL; i<ipos; i+=2UL ) {
2860  matrix_(i ,index) *= (~rhs)(i ,j);
2861  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
2862  }
2863  if( ipos < rows() ) {
2864  matrix_(ipos,index) *= (~rhs)(ipos,j);
2865  }
2866  }
2867 }
2869 //*************************************************************************************************
2870 
2871 
2872 //*************************************************************************************************
2885 template< typename MT // Type of the dense matrix
2886  , bool SF // Symmetry flag
2887  , size_t... CCAs > // Compile time column arguments
2888 template< typename MT2 > // Type of the right-hand side dense matrix
2889 inline EnableIf_< typename Columns<MT,true,true,SF,CCAs...>::BLAZE_TEMPLATE VectorizedSchurAssign<MT2> >
2890  Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2891 {
2894 
2896 
2897  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2898  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2899 
2900  for( size_t j=0UL; j<columns(); ++j )
2901  {
2902  const size_t ipos( rows() & size_t(-SIMDSIZE) );
2903  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % (SIMDSIZE) ) ) == ipos, "Invalid end calculation" );
2904 
2905  size_t i( 0UL );
2906  Iterator left( begin(j) );
2907  ConstIterator_<MT2> right( (~rhs).begin(j) );
2908 
2909  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2910  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2911  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2912  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2913  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2914  }
2915  for( ; i<ipos; i+=SIMDSIZE ) {
2916  left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2917  }
2918  for( ; i<rows(); ++i ) {
2919  *left *= *right; ++left; ++right;
2920  }
2921  }
2922 }
2924 //*************************************************************************************************
2925 
2926 
2927 //*************************************************************************************************
2939 template< typename MT // Type of the dense matrix
2940  , bool SF // Symmetry flag
2941  , size_t... CCAs > // Compile time column arguments
2942 template< typename MT2 > // Type of the right-hand side dense matrix
2943 inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2944 {
2947 
2949 
2950  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
2951  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
2952 
2953  constexpr size_t block( BLOCK_SIZE );
2954 
2955  if( rows() < block && columns() < block )
2956  {
2957  const size_t ipos( (~rhs).rows() & size_t(-2) );
2958  for( size_t j=0UL; j<columns(); ++j ) {
2959  const size_t index( idx(j) );
2960  for( size_t i=0UL; i<ipos; i+=2UL ) {
2961  matrix_(i ,index) *= (~rhs)(i ,j);
2962  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
2963  }
2964  if( ipos < (~rhs).rows() )
2965  matrix_(ipos,index) *= (~rhs)(ipos,j);
2966  }
2967  }
2968  else
2969  {
2970  for( size_t jj=0UL; jj<columns(); jj+=block ) {
2971  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2972  for( size_t ii=0UL; ii<rows(); ii+=block ) {
2973  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2974  for( size_t j=jj; j<jend; ++j ) {
2975  const size_t index( idx(j) );
2976  for( size_t i=ii; i<iend; ++i ) {
2977  matrix_(i,index) *= (~rhs)(i,j);
2978  }
2979  }
2980  }
2981  }
2982  }
2983 }
2985 //*************************************************************************************************
2986 
2987 
2988 //*************************************************************************************************
3000 template< typename MT // Type of the dense matrix
3001  , bool SF // Symmetry flag
3002  , size_t... CCAs > // Compile time column arguments
3003 template< typename MT2 > // Type of the right-hand side sparse matrix
3004 inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
3005 {
3008 
3009  using blaze::reset;
3010 
3011  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3012  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3013 
3014  for( size_t j=0UL; j<columns(); ++j )
3015  {
3016  const size_t index( idx(j) );
3017  size_t i( 0UL );
3018 
3019  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
3020  for( ; i<element->index(); ++i )
3021  reset( matrix_(i,index) );
3022  matrix_(i,index) *= element->value();
3023  ++i;
3024  }
3025 
3026  for( ; i<rows(); ++i ) {
3027  reset( matrix_(i,index) );
3028  }
3029  }
3030 }
3032 //*************************************************************************************************
3033 
3034 
3035 //*************************************************************************************************
3047 template< typename MT // Type of the dense matrix
3048  , bool SF // Symmetry flag
3049  , size_t... CCAs > // Compile time column arguments
3050 template< typename MT2 > // Type of the right-hand side sparse matrix
3051 inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
3052 {
3055 
3056  using blaze::reset;
3057 
3059 
3060  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
3061  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
3062 
3063  for( size_t i=0UL; i<rows(); ++i )
3064  {
3065  size_t j( 0UL );
3066 
3067  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
3068  for( ; j<element->index(); ++j )
3069  reset( matrix_(i,idx(j)) );
3070  matrix_(i,idx(j)) *= element->value();
3071  ++j;
3072  }
3073 
3074  for( ; j<columns(); ++j ) {
3075  reset( matrix_(i,idx(j)) );
3076  }
3077  }
3078 }
3080 //*************************************************************************************************
3081 
3082 
3083 
3084 
3085 
3086 
3087 
3088 
3089 //=================================================================================================
3090 //
3091 // CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
3092 //
3093 //=================================================================================================
3094 
3095 //*************************************************************************************************
3103 template< typename MT // Type of the dense matrix
3104  , size_t... CCAs > // Compile time column arguments
3105 class Columns<MT,false,true,false,CCAs...>
3106  : public View< DenseMatrix< Columns<MT,false,true,false,CCAs...>, true > >
3107  , private ColumnsData<CCAs...>
3108 {
3109  private:
3110  //**Type definitions****************************************************************************
3111  using DataType = ColumnsData<CCAs...>;
3112  using Operand = If_< IsExpression<MT>, MT, MT& >;
3113  //**********************************************************************************************
3114 
3115  public:
3116  //**Type definitions****************************************************************************
3118  using This = Columns<MT,false,true,false,CCAs...>;
3119 
3120  using BaseType = DenseMatrix<This,true>;
3121  using ViewedType = MT;
3122  using ResultType = ColumnsTrait_<MT,CCAs...>;
3123  using OppositeType = OppositeType_<ResultType>;
3124  using TransposeType = TransposeType_<ResultType>;
3125  using ElementType = ElementType_<MT>;
3126  using ReturnType = ReturnType_<MT>;
3127  using CompositeType = const Columns&;
3128 
3130  using ConstReference = ConstReference_<MT>;
3131 
3133  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
3134 
3136  using ConstPointer = ConstPointer_<MT>;
3137 
3139  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, Pointer_<MT> >;
3140  //**********************************************************************************************
3141 
3142  //**ColumnsIterator class definition************************************************************
3145  template< typename MatrixType // Type of the dense matrix
3146  , typename IteratorType > // Type of the dense matrix iterator
3147  class ColumnsIterator
3148  {
3149  public:
3150  //**Type definitions*************************************************************************
3152  using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
3153 
3155  using ValueType = typename std::iterator_traits<IteratorType>::value_type;
3156 
3158  using PointerType = typename std::iterator_traits<IteratorType>::pointer;
3159 
3161  using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
3162 
3164  using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
3165 
3166  // STL iterator requirements
3167  using iterator_category = IteratorCategory;
3168  using value_type = ValueType;
3169  using pointer = PointerType;
3170  using reference = ReferenceType;
3171  using difference_type = DifferenceType;
3172  //*******************************************************************************************
3173 
3174  //**Constructor******************************************************************************
3177  inline ColumnsIterator() noexcept
3178  : matrix_( nullptr ) // The dense matrix containing the column
3179  , row_ ( 0UL ) // The current row index
3180  , column_( 0UL ) // The current column index
3181  , pos_ ( ) // Iterator to the current dense element
3182  {}
3183  //*******************************************************************************************
3184 
3185  //**Constructor******************************************************************************
3192  inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
3193  : matrix_( &matrix ) // The dense matrix containing the selected column
3194  , row_ ( row ) // The current row index
3195  , column_( column ) // The current column index
3196  , pos_ ( ) // Iterator to the current dense element
3197  {
3198  if( row_ != matrix_->rows() )
3199  pos_ = matrix_->begin( row_ ) + column_;
3200  }
3201  //*******************************************************************************************
3202 
3203  //**Constructor******************************************************************************
3208  template< typename MatrixType2, typename IteratorType2 >
3209  inline ColumnsIterator( const ColumnsIterator<MatrixType2,IteratorType2>& it ) noexcept
3210  : matrix_( it.matrix_ ) // The dense matrix containing the seleted column
3211  , row_ ( it.row_ ) // The current row index
3212  , column_( it.column_ ) // The current column index
3213  , pos_ ( it.pos_ ) // Iterator to the current dense element
3214  {}
3215  //*******************************************************************************************
3216 
3217  //**Addition assignment operator*************************************************************
3223  inline ColumnsIterator& operator+=( size_t inc ) noexcept {
3224  using blaze::reset;
3225  row_ += inc;
3226  if( row_ != matrix_->rows() )
3227  pos_ = matrix_->begin( row_ ) + column_;
3228  else reset( pos_ );
3229  return *this;
3230  }
3231  //*******************************************************************************************
3232 
3233  //**Subtraction assignment operator**********************************************************
3239  inline ColumnsIterator& operator-=( size_t dec ) noexcept {
3240  using blaze::reset;
3241  row_ -= dec;
3242  if( row_ != matrix_->rows() )
3243  pos_ = matrix_->begin( row_ ) + column_;
3244  else reset( pos_ );
3245  return *this;
3246  }
3247  //*******************************************************************************************
3248 
3249  //**Prefix increment operator****************************************************************
3254  inline ColumnsIterator& operator++() noexcept {
3255  using blaze::reset;
3256  ++row_;
3257  if( row_ != matrix_->rows() )
3258  pos_ = matrix_->begin( row_ ) + column_;
3259  else reset( pos_ );
3260  return *this;
3261  }
3262  //*******************************************************************************************
3263 
3264  //**Postfix increment operator***************************************************************
3269  inline const ColumnsIterator operator++( int ) noexcept {
3270  const ColumnsIterator tmp( *this );
3271  ++(*this);
3272  return tmp;
3273  }
3274  //*******************************************************************************************
3275 
3276  //**Prefix decrement operator****************************************************************
3281  inline ColumnsIterator& operator--() noexcept {
3282  using blaze::reset;
3283  --row_;
3284  if( row_ != matrix_->rows() )
3285  pos_ = matrix_->begin( row_ ) + column_;
3286  else reset( pos_ );
3287  return *this;
3288  }
3289  //*******************************************************************************************
3290 
3291  //**Postfix decrement operator***************************************************************
3296  inline const ColumnsIterator operator--( int ) noexcept {
3297  const ColumnsIterator tmp( *this );
3298  --(*this);
3299  return tmp;
3300  }
3301  //*******************************************************************************************
3302 
3303  //**Subscript operator***********************************************************************
3309  inline ReferenceType operator[]( size_t index ) const {
3310  BLAZE_USER_ASSERT( row_+index < matrix_->rows(), "Invalid access index detected" );
3311  const IteratorType pos( matrix_->begin( row_+index ) + column_ );
3312  return *pos;
3313  }
3314  //*******************************************************************************************
3315 
3316  //**Element access operator******************************************************************
3321  inline ReferenceType operator*() const {
3322  return *pos_;
3323  }
3324  //*******************************************************************************************
3325 
3326  //**Element access operator******************************************************************
3331  inline PointerType operator->() const {
3332  return pos_;
3333  }
3334  //*******************************************************************************************
3335 
3336  //**Equality operator************************************************************************
3342  template< typename MatrixType2, typename IteratorType2 >
3343  inline bool operator==( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3344  return row_ == rhs.row_;
3345  }
3346  //*******************************************************************************************
3347 
3348  //**Inequality operator**********************************************************************
3354  template< typename MatrixType2, typename IteratorType2 >
3355  inline bool operator!=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3356  return !( *this == rhs );
3357  }
3358  //*******************************************************************************************
3359 
3360  //**Less-than operator***********************************************************************
3366  template< typename MatrixType2, typename IteratorType2 >
3367  inline bool operator<( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3368  return row_ < rhs.row_;
3369  }
3370  //*******************************************************************************************
3371 
3372  //**Greater-than operator********************************************************************
3378  template< typename MatrixType2, typename IteratorType2 >
3379  inline bool operator>( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3380  return row_ > rhs.row_;
3381  }
3382  //*******************************************************************************************
3383 
3384  //**Less-or-equal-than operator**************************************************************
3390  template< typename MatrixType2, typename IteratorType2 >
3391  inline bool operator<=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3392  return row_ <= rhs.row_;
3393  }
3394  //*******************************************************************************************
3395 
3396  //**Greater-or-equal-than operator***********************************************************
3402  template< typename MatrixType2, typename IteratorType2 >
3403  inline bool operator>=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3404  return row_ >= rhs.row_;
3405  }
3406  //*******************************************************************************************
3407 
3408  //**Subtraction operator*********************************************************************
3414  inline DifferenceType operator-( const ColumnsIterator& rhs ) const noexcept {
3415  return row_ - rhs.row_;
3416  }
3417  //*******************************************************************************************
3418 
3419  //**Addition operator************************************************************************
3426  friend inline const ColumnsIterator operator+( const ColumnsIterator& it, size_t inc ) noexcept {
3427  return ColumnsIterator( *it.matrix_, it.row_+inc, it.column_ );
3428  }
3429  //*******************************************************************************************
3430 
3431  //**Addition operator************************************************************************
3438  friend inline const ColumnsIterator operator+( size_t inc, const ColumnsIterator& it ) noexcept {
3439  return ColumnsIterator( *it.matrix_, it.row_+inc, it.column_ );
3440  }
3441  //*******************************************************************************************
3442 
3443  //**Subtraction operator*********************************************************************
3450  friend inline const ColumnsIterator operator-( const ColumnsIterator& it, size_t dec ) noexcept {
3451  return ColumnsIterator( *it.matrix_, it.row_-dec, it.column_ );
3452  }
3453  //*******************************************************************************************
3454 
3455  private:
3456  //**Member variables*************************************************************************
3457  MatrixType* matrix_;
3458  size_t row_;
3459  size_t column_;
3460  IteratorType pos_;
3461  //*******************************************************************************************
3462 
3463  //**Friend declarations**********************************************************************
3464  template< typename MatrixType2, typename IteratorType2 > friend class ColumnsIterator;
3465  //*******************************************************************************************
3466  };
3467  //**********************************************************************************************
3468 
3469  //**Type definitions****************************************************************************
3471  using ConstIterator = ColumnsIterator< const MT, ConstIterator_<MT> >;
3472 
3474  using Iterator = If_< IsConst<MT>, ConstIterator, ColumnsIterator< MT, Iterator_<MT> > >;
3475  //**********************************************************************************************
3476 
3477  //**Compilation flags***************************************************************************
3479  enum : bool { simdEnabled = false };
3480 
3482  enum : bool { smpAssignable = MT::smpAssignable };
3483  //**********************************************************************************************
3484 
3485  //**Constructors********************************************************************************
3488  template< typename... RCAs >
3489  explicit inline Columns( MT& matrix, RCAs... args );
3490 
3491  inline Columns( const Columns& ) = default;
3492  inline Columns( Columns&& ) = default;
3494  //**********************************************************************************************
3495 
3496  //**Destructor**********************************************************************************
3497  // No explicitly declared destructor.
3498  //**********************************************************************************************
3499 
3500  //**Data access functions***********************************************************************
3503  inline Reference operator()( size_t i, size_t j );
3504  inline ConstReference operator()( size_t i, size_t j ) const;
3505  inline Reference at( size_t i, size_t j );
3506  inline ConstReference at( size_t i, size_t j ) const;
3507  inline Pointer data () noexcept;
3508  inline ConstPointer data () const noexcept;
3509  inline Pointer data ( size_t j ) noexcept;
3510  inline ConstPointer data ( size_t j ) const noexcept;
3511  inline Iterator begin ( size_t j );
3512  inline ConstIterator begin ( size_t j ) const;
3513  inline ConstIterator cbegin( size_t j ) const;
3514  inline Iterator end ( size_t j );
3515  inline ConstIterator end ( size_t j ) const;
3516  inline ConstIterator cend ( size_t j ) const;
3518  //**********************************************************************************************
3519 
3520  //**Assignment operators************************************************************************
3523  inline Columns& operator=( const ElementType& rhs );
3524  inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
3525  inline Columns& operator=( const Columns& rhs );
3526 
3527  template< typename MT2, bool SO2 >
3528  inline Columns& operator=( const Matrix<MT2,SO2>& rhs );
3529 
3530  template< typename MT2, bool SO2 >
3531  inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
3532  operator+=( const Matrix<MT2,SO2>& rhs );
3533 
3534  template< typename MT2, bool SO2 >
3535  inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
3536  operator+=( const Matrix<MT2,SO2>& rhs );
3537 
3538  template< typename MT2, bool SO2 >
3539  inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
3540  operator-=( const Matrix<MT2,SO2>& rhs );
3541 
3542  template< typename MT2, bool SO2 >
3543  inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
3544  operator-=( const Matrix<MT2,SO2>& rhs );
3545 
3546  template< typename MT2, bool SO2 >
3547  inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
3548  operator%=( const Matrix<MT2,SO2>& rhs );
3549 
3550  template< typename MT2, bool SO2 >
3551  inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns& >
3552  operator%=( const Matrix<MT2,SO2>& rhs );
3554  //**********************************************************************************************
3555 
3556  //**Utility functions***************************************************************************
3559  using DataType::idx;
3560  using DataType::idces;
3561  using DataType::columns;
3562 
3563  inline MT& operand() noexcept;
3564  inline const MT& operand() const noexcept;
3565 
3566  inline size_t rows() const noexcept;
3567  inline size_t spacing() const noexcept;
3568  inline size_t capacity() const noexcept;
3569  inline size_t capacity( size_t j ) const noexcept;
3570  inline size_t nonZeros() const;
3571  inline size_t nonZeros( size_t j ) const;
3572  inline void reset();
3573  inline void reset( size_t j );
3575  //**********************************************************************************************
3576 
3577  //**Numeric functions***************************************************************************
3580  inline Columns& transpose();
3581  inline Columns& ctranspose();
3582 
3583  template< typename Other > inline Columns& scale( const Other& scalar );
3585  //**********************************************************************************************
3586 
3587  //**Expression template evaluation functions****************************************************
3590  template< typename Other >
3591  inline bool canAlias( const Other* alias ) const noexcept;
3592 
3593  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
3594  inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
3595 
3596  template< typename Other >
3597  inline bool isAliased( const Other* alias ) const noexcept;
3598 
3599  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
3600  inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
3601 
3602  inline bool isAligned () const noexcept;
3603  inline bool canSMPAssign() const noexcept;
3604 
3605  template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
3606  template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3607  template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3608  template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3609 
3610  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
3611  template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3612  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3613  template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3614 
3615  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
3616  template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3617  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3618  template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3619 
3620  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
3621  template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
3622  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
3623  template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
3625  //**********************************************************************************************
3626 
3627  private:
3628  //**Member variables****************************************************************************
3631  Operand matrix_;
3632 
3633  //**********************************************************************************************
3634 
3635  //**Friend declarations*************************************************************************
3636  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Columns;
3637  //**********************************************************************************************
3638 
3639  //**Compile time checks*************************************************************************
3649  //**********************************************************************************************
3650 };
3652 //*************************************************************************************************
3653 
3654 
3655 
3656 
3657 //=================================================================================================
3658 //
3659 // CONSTRUCTORS
3660 //
3661 //=================================================================================================
3662 
3663 //*************************************************************************************************
3676 template< typename MT // Type of the dense matrix
3677  , size_t... CCAs > // Compile time column arguments
3678 template< typename... RCAs > // Runtime column arguments
3679 inline Columns<MT,false,true,false,CCAs...>::Columns( MT& matrix, RCAs... args )
3680  : DataType( args... ) // Base class initialization
3681  , matrix_ ( matrix ) // The matrix containing the columns
3682 {
3683  if( !Contains< TypeList<RCAs...>, Unchecked >::value ) {
3684  for( size_t j=0UL; j<columns(); ++j ) {
3685  if( matrix_.columns() <= idx(j) ) {
3686  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3687  }
3688  }
3689  }
3690 }
3692 //*************************************************************************************************
3693 
3694 
3695 
3696 
3697 //=================================================================================================
3698 //
3699 // DATA ACCESS FUNCTIONS
3700 //
3701 //=================================================================================================
3702 
3703 //*************************************************************************************************
3714 template< typename MT // Type of the dense matrix
3715  , size_t... CCAs > // Compile time column arguments
3716 inline typename Columns<MT,false,true,false,CCAs...>::Reference
3717  Columns<MT,false,true,false,CCAs...>::operator()( size_t i, size_t j )
3718 {
3719  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3720  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3721 
3722  return matrix_(i,idx(j));
3723 }
3725 //*************************************************************************************************
3726 
3727 
3728 //*************************************************************************************************
3739 template< typename MT // Type of the dense matrix
3740  , size_t... CCAs > // Compile time column arguments
3741 inline typename Columns<MT,false,true,false,CCAs...>::ConstReference
3742  Columns<MT,false,true,false,CCAs...>::operator()( size_t i, size_t j ) const
3743 {
3744  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3745  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3746 
3747  return const_cast<const MT&>( matrix_ )(i,idx(j));
3748 }
3750 //*************************************************************************************************
3751 
3752 
3753 //*************************************************************************************************
3765 template< typename MT // Type of the dense matrix
3766  , size_t... CCAs > // Compile time column arguments
3767 inline typename Columns<MT,false,true,false,CCAs...>::Reference
3768  Columns<MT,false,true,false,CCAs...>::at( size_t i, size_t j )
3769 {
3770  if( i >= rows() ) {
3771  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3772  }
3773  if( j >= columns() ) {
3774  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3775  }
3776  return (*this)(i,j);
3777 }
3779 //*************************************************************************************************
3780 
3781 
3782 //*************************************************************************************************
3794 template< typename MT // Type of the dense matrix
3795  , size_t... CCAs > // Compile time column arguments
3796 inline typename Columns<MT,false,true,false,CCAs...>::ConstReference
3797  Columns<MT,false,true,false,CCAs...>::at( size_t i, size_t j ) const
3798 {
3799  if( i >= rows() ) {
3800  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3801  }
3802  if( j >= columns() ) {
3803  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3804  }
3805  return (*this)(i,j);
3806 }
3808 //*************************************************************************************************
3809 
3810 
3811 //*************************************************************************************************
3821 template< typename MT // Type of the dense matrix
3822  , size_t... CCAs > // Compile time column arguments
3823 inline typename Columns<MT,false,true,false,CCAs...>::Pointer
3825 {
3826  return matrix_.data() + idx(0UL);
3827 }
3829 //*************************************************************************************************
3830 
3831 
3832 //*************************************************************************************************
3842 template< typename MT // Type of the dense matrix
3843  , size_t... CCAs > // Compile time column arguments
3844 inline typename Columns<MT,false,true,false,CCAs...>::ConstPointer
3846 {
3847  return matrix_.data() + idx(0UL);
3848 }
3850 //*************************************************************************************************
3851 
3852 
3853 //*************************************************************************************************
3862 template< typename MT // Type of the dense matrix
3863  , size_t... CCAs > // Compile time column arguments
3864 inline typename Columns<MT,false,true,false,CCAs...>::Pointer
3865  Columns<MT,false,true,false,CCAs...>::data( size_t j ) noexcept
3866 {
3867  return matrix_.data() + idx(j);
3868 }
3870 //*************************************************************************************************
3871 
3872 
3873 //*************************************************************************************************
3882 template< typename MT // Type of the dense matrix
3883  , size_t... CCAs > // Compile time column arguments
3884 inline typename Columns<MT,false,true,false,CCAs...>::ConstPointer
3885  Columns<MT,false,true,false,CCAs...>::data( size_t j ) const noexcept
3886 {
3887  return matrix_.data() + idx(j);
3888 }
3890 //*************************************************************************************************
3891 
3892 
3893 //*************************************************************************************************
3902 template< typename MT // Type of the dense matrix
3903  , size_t... CCAs > // Compile time column arguments
3904 inline typename Columns<MT,false,true,false,CCAs...>::Iterator
3906 {
3907  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3908  return Iterator( matrix_, 0UL, idx(j) );
3909 }
3911 //*************************************************************************************************
3912 
3913 
3914 //*************************************************************************************************
3923 template< typename MT // Type of the dense matrix
3924  , size_t... CCAs > // Compile time column arguments
3925 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
3927 {
3928  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3929  return ConstIterator( matrix_, 0UL, idx(j) );
3930 }
3932 //*************************************************************************************************
3933 
3934 
3935 //*************************************************************************************************
3944 template< typename MT // Type of the dense matrix
3945  , size_t... CCAs > // Compile time column arguments
3946 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
3948 {
3949  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3950  return ConstIterator( matrix_, 0UL, idx(j) );
3951 }
3953 //*************************************************************************************************
3954 
3955 
3956 //*************************************************************************************************
3965 template< typename MT // Type of the dense matrix
3966  , size_t... CCAs > // Compile time column arguments
3967 inline typename Columns<MT,false,true,false,CCAs...>::Iterator
3969 {
3970  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3971  return Iterator( matrix_, rows(), idx(j) );
3972 }
3974 //*************************************************************************************************
3975 
3976 
3977 //*************************************************************************************************
3986 template< typename MT // Type of the dense matrix
3987  , size_t... CCAs > // Compile time column arguments
3988 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
3990 {
3991  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3992  return ConstIterator( matrix_, rows(), idx(j) );
3993 }
3995 //*************************************************************************************************
3996 
3997 
3998 //*************************************************************************************************
4007 template< typename MT // Type of the dense matrix
4008  , size_t... CCAs > // Compile time column arguments
4009 inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
4011 {
4012  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4013  return ConstIterator( matrix_, rows(), idx(j) );
4014 }
4016 //*************************************************************************************************
4017 
4018 
4019 
4020 
4021 //=================================================================================================
4022 //
4023 // ASSIGNMENT OPERATORS
4024 //
4025 //=================================================================================================
4026 
4027 //*************************************************************************************************
4038 template< typename MT // Type of the dense matrix
4039  , size_t... CCAs > // Compile time column arguments
4040 inline Columns<MT,false,true,false,CCAs...>&
4041  Columns<MT,false,true,false,CCAs...>::operator=( const ElementType& rhs )
4042 {
4043  for( size_t j=0UL; j<columns(); ++j ) {
4044  column( matrix_, idx(j), unchecked ) = rhs;
4045  }
4046 
4047  return *this;
4048 }
4050 //*************************************************************************************************
4051 
4052 
4053 //*************************************************************************************************
4069 template< typename MT // Type of the dense matrix
4070  , size_t... CCAs > // Compile time column arguments
4071 inline Columns<MT,false,true,false,CCAs...>&
4072  Columns<MT,false,true,false,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
4073 {
4076 
4077  if( list.size() != rows() ) {
4078  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
4079  }
4080 
4081  if( IsRestricted<MT>::value ) {
4082  const InitializerMatrix<ElementType> tmp( list, columns() );
4083  for( size_t j=0UL; j<columns(); ++j ) {
4084  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4085  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4086  }
4087  }
4088  }
4089 
4090  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4091  size_t i( 0UL );
4092 
4093  for( const auto& rowList : list ) {
4094  size_t j( 0UL );
4095  for( const auto& element : rowList ) {
4096  matrix_(i,idx(j)) = element;
4097  ++j;
4098  }
4099  for( ; j<columns(); ++j ) {
4100  matrix_(i,idx(j)) = ElementType();
4101  }
4102  ++i;
4103  }
4104 
4105  return *this;
4106 }
4108 //*************************************************************************************************
4109 
4110 
4111 //*************************************************************************************************
4126 template< typename MT // Type of the dense matrix
4127  , size_t... CCAs > // Compile time column arguments
4128 inline Columns<MT,false,true,false,CCAs...>&
4129  Columns<MT,false,true,false,CCAs...>::operator=( const Columns& rhs )
4130 {
4133 
4136 
4137  if( this == &rhs || ( &matrix_ == &rhs.matrix_ && idces() == rhs.idces() ) )
4138  return *this;
4139 
4140  if( rows() != rhs.rows() || columns() != rhs.columns() ) {
4141  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4142  }
4143 
4144  if( IsRestricted<MT>::value ) {
4145  for( size_t j=0UL; j<columns(); ++j ) {
4146  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( rhs, j, unchecked ), 0UL ) ) {
4147  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4148  }
4149  }
4150  }
4151 
4152  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4153 
4154  if( rhs.canAlias( &matrix_ ) ) {
4155  const ResultType tmp( rhs );
4156  smpAssign( left, tmp );
4157  }
4158  else {
4159  smpAssign( left, rhs );
4160  }
4161 
4162  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4163 
4164  return *this;
4165 }
4167 //*************************************************************************************************
4168 
4169 
4170 //*************************************************************************************************
4185 template< typename MT // Type of the dense matrix
4186  , size_t... CCAs > // Compile time column arguments
4187 template< typename MT2 // Type of the right-hand side matrix
4188  , bool SO2 > // Storage order of the right-hand side matrix
4189 inline Columns<MT,false,true,false,CCAs...>&
4190  Columns<MT,false,true,false,CCAs...>::operator=( const Matrix<MT2,SO2>& rhs )
4191 {
4194 
4196 
4197  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4198  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4199  }
4200 
4201  using Right = If_< IsRestricted<MT>, CompositeType_<MT2>, const MT2& >;
4202  Right right( ~rhs );
4203 
4204  if( IsRestricted<MT>::value ) {
4205  for( size_t j=0UL; j<columns(); ++j ) {
4206  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( right, j, unchecked ), 0UL ) ) {
4207  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4208  }
4209  }
4210  }
4211 
4212  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4213 
4214  if( IsSparseMatrix<MT2>::value ) {
4215  reset();
4216  }
4217 
4218  if( IsReference<Right>::value && right.canAlias( &matrix_ ) ) {
4219  const ResultType_<MT2> tmp( right );
4220  smpAssign( left, tmp );
4221  }
4222  else {
4223  smpAssign( left, right );
4224  }
4225 
4226  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4227 
4228  return *this;
4229 }
4231 //*************************************************************************************************
4232 
4233 
4234 //*************************************************************************************************
4248 template< typename MT // Type of the dense matrix
4249  , size_t... CCAs > // Compile time column arguments
4250 template< typename MT2 // Type of the right-hand side matrix
4251  , bool SO2 > // Storage order of the right-hand side matrix
4252 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,false,true,false,CCAs...>& >
4253  Columns<MT,false,true,false,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4254 {
4257 
4261 
4262  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
4263 
4266 
4267  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4268  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4269  }
4270 
4271  if( IsRestricted<MT>::value ) {
4272  for( size_t j=0UL; j<columns(); ++j ) {
4273  if( !tryAddAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
4274  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4275  }
4276  }
4277  }
4278 
4279  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4280 
4281  if( (~rhs).canAlias( &matrix_ ) ) {
4282  const AddType tmp( *this + (~rhs) );
4283  smpAssign( left, tmp );
4284  }
4285  else {
4286  smpAddAssign( left, ~rhs );
4287  }
4288 
4289  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4290 
4291  return *this;
4292 }
4294 //*************************************************************************************************
4295 
4296 
4297 //*************************************************************************************************
4311 template< typename MT // Type of the dense matrix
4312  , size_t... CCAs > // Compile time column arguments
4313 template< typename MT2 // Type of the right-hand side matrix
4314  , bool SO2 > // Storage order of the right-hand side matrix
4315 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,false,true,false,CCAs...>& >
4316  Columns<MT,false,true,false,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4317 {
4320 
4324 
4325  using AddType = AddTrait_< ResultType, ResultType_<MT2> >;
4326 
4329 
4330  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4331  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4332  }
4333 
4334  const AddType tmp( *this + (~rhs) );
4335 
4336  if( IsRestricted<MT>::value ) {
4337  for( size_t j=0UL; j<columns(); ++j ) {
4338  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4339  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4340  }
4341  }
4342  }
4343 
4344  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4345 
4346  smpAssign( left, tmp );
4347 
4348  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4349 
4350  return *this;
4351 }
4353 //*************************************************************************************************
4354 
4355 
4356 //*************************************************************************************************
4370 template< typename MT // Type of the dense matrix
4371  , size_t... CCAs > // Compile time column arguments
4372 template< typename MT2 // Type of the right-hand side matrix
4373  , bool SO2 > // Storage order of the right-hand side matrix
4374 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,false,true,false,CCAs...>& >
4375  Columns<MT,false,true,false,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4376 {
4379 
4383 
4384  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
4385 
4388 
4389  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4390  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4391  }
4392 
4393  if( IsRestricted<MT>::value ) {
4394  for( size_t j=0UL; j<columns(); ++j ) {
4395  if( !trySubAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
4396  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4397  }
4398  }
4399  }
4400 
4401  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4402 
4403  if( (~rhs).canAlias( &matrix_ ) ) {
4404  const SubType tmp( *this - (~rhs ) );
4405  smpAssign( left, tmp );
4406  }
4407  else {
4408  smpSubAssign( left, ~rhs );
4409  }
4410 
4411  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4412 
4413  return *this;
4414 }
4416 //*************************************************************************************************
4417 
4418 
4419 //*************************************************************************************************
4433 template< typename MT // Type of the dense matrix
4434  , size_t... CCAs > // Compile time column arguments
4435 template< typename MT2 // Type of the right-hand side matrix
4436  , bool SO2 > // Storage order of the right-hand side matrix
4437 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,false,true,false,CCAs...>& >
4438  Columns<MT,false,true,false,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4439 {
4442 
4446 
4447  using SubType = SubTrait_< ResultType, ResultType_<MT2> >;
4448 
4451 
4452  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4453  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4454  }
4455 
4456  const SubType tmp( *this - (~rhs) );
4457 
4458  if( IsRestricted<MT>::value ) {
4459  for( size_t j=0UL; j<columns(); ++j ) {
4460  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4461  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4462  }
4463  }
4464  }
4465 
4466  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4467 
4468  smpAssign( left, tmp );
4469 
4470  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4471 
4472  return *this;
4473 }
4475 //*************************************************************************************************
4476 
4477 
4478 //*************************************************************************************************
4492 template< typename MT // Type of the dense matrix
4493  , size_t... CCAs > // Compile time column arguments
4494 template< typename MT2 // Type of the right-hand side matrix
4495  , bool SO2 > // Storage order of the right-hand side matrix
4496 inline DisableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,false,true,false,CCAs...>& >
4497  Columns<MT,false,true,false,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4498 {
4501 
4505 
4506  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
4507 
4509 
4510  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4511  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4512  }
4513 
4514  if( IsRestricted<MT>::value ) {
4515  for( size_t j=0UL; j<columns(); ++j ) {
4516  if( !tryMultAssign( column( matrix_, idx(j), unchecked ), column( ~rhs, j, unchecked ), 0UL ) ) {
4517  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4518  }
4519  }
4520  }
4521 
4522  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4523 
4524  if( (~rhs).canAlias( &matrix_ ) ) {
4525  const SchurType tmp( *this % (~rhs) );
4526  if( IsSparseMatrix<SchurType>::value )
4527  reset();
4528  smpAssign( left, tmp );
4529  }
4530  else {
4531  smpSchurAssign( left, ~rhs );
4532  }
4533 
4534  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4535 
4536  return *this;
4537 }
4539 //*************************************************************************************************
4540 
4541 
4542 //*************************************************************************************************
4556 template< typename MT // Type of the dense matrix
4557  , size_t... CCAs > // Compile time column arguments
4558 template< typename MT2 // Type of the right-hand side matrix
4559  , bool SO2 > // Storage order of the right-hand side matrix
4560 inline EnableIf_< And< IsRestricted<MT>, RequiresEvaluation<MT2> >, Columns<MT,false,true,false,CCAs...>& >
4561  Columns<MT,false,true,false,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4562 {
4565 
4569 
4570  using SchurType = SchurTrait_< ResultType, ResultType_<MT2> >;
4571 
4573 
4574  if( rows() != (~rhs).rows() || columns() != (~rhs).columns() ) {
4575  BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4576  }
4577 
4578  const SchurType tmp( *this % (~rhs) );
4579 
4580  if( IsRestricted<MT>::value ) {
4581  for( size_t j=0UL; j<columns(); ++j ) {
4582  if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4583  BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4584  }
4585  }
4586  }
4587 
4588  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4589 
4590  if( IsSparseMatrix<SchurType>::value ) {
4591  reset();
4592  }
4593 
4594  smpAssign( left, tmp );
4595 
4596  BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4597 
4598  return *this;
4599 }
4601 //*************************************************************************************************
4602 
4603 
4604 
4605 
4606 //=================================================================================================
4607 //
4608 // UTILITY FUNCTIONS
4609 //
4610 //=================================================================================================
4611 
4612 //*************************************************************************************************
4618 template< typename MT // Type of the dense matrix
4619  , size_t... CCAs > // Compile time column arguments
4620 inline MT& Columns<MT,false,true,false,CCAs...>::operand() noexcept
4621 {
4622  return matrix_;
4623 }
4625 //*************************************************************************************************
4626 
4627 
4628 //*************************************************************************************************
4634 template< typename MT // Type of the dense matrix
4635  , size_t... CCAs > // Compile time column arguments
4636 inline const MT& Columns<MT,false,true,false,CCAs...>::operand() const noexcept
4637 {
4638  return matrix_;
4639 }
4641 //*************************************************************************************************
4642 
4643 
4644 //*************************************************************************************************
4650 template< typename MT // Type of the dense matrix
4651  , size_t... CCAs > // Compile time column arguments
4652 inline size_t Columns<MT,false,true,false,CCAs...>::rows() const noexcept
4653 {
4654  return matrix_.rows();
4655 }
4657 //*************************************************************************************************
4658 
4659 
4660 //*************************************************************************************************
4669 template< typename MT // Type of the dense matrix
4670  , size_t... CCAs > // Compile time column arguments
4671 inline size_t Columns<MT,false,true,false,CCAs...>::spacing() const noexcept
4672 {
4673  return matrix_.spacing();
4674 }
4676 //*************************************************************************************************
4677 
4678 
4679 //*************************************************************************************************
4685 template< typename MT // Type of the dense matrix
4686  , size_t... CCAs > // Compile time column arguments
4687 inline size_t Columns<MT,false,true,false,CCAs...>::capacity() const noexcept
4688 {
4689  return rows() * columns();
4690 }
4692 //*************************************************************************************************
4693 
4694 
4695 //*************************************************************************************************
4704 template< typename MT // Type of the dense matrix
4705  , size_t... CCAs > // Compile time column arguments
4706 inline size_t Columns<MT,false,true,false,CCAs...>::capacity( size_t j ) const noexcept
4707 {
4708  UNUSED_PARAMETER( j );
4709 
4710  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4711 
4712  return rows();
4713 }
4715 //*************************************************************************************************
4716 
4717 
4718 //*************************************************************************************************
4724 template< typename MT // Type of the dense matrix
4725  , size_t... CCAs > // Compile time column arguments
4727 {
4728  size_t nonzeros( 0UL );
4729 
4730  for( size_t j=0UL; j<columns(); ++j ) {
4731  nonzeros += nonZeros( j );
4732  }
4733 
4734  return nonzeros;
4735 }
4737 //*************************************************************************************************
4738 
4739 
4740 //*************************************************************************************************
4749 template< typename MT // Type of the dense matrix
4750  , size_t... CCAs > // Compile time column arguments
4751 inline size_t Columns<MT,false,true,false,CCAs...>::nonZeros( size_t j ) const
4752 {
4753  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4754 
4755  size_t nonzeros( 0UL );
4756 
4757  const size_t index( idx(j) );
4758  for( size_t i=0UL; i<rows(); ++i ) {
4759  if( !isDefault( matrix_( i, index ) ) )
4760  ++nonzeros;
4761  }
4762 
4763  return nonzeros;
4764 }
4766 //*************************************************************************************************
4767 
4768 
4769 //*************************************************************************************************
4775 template< typename MT // Type of the dense matrix
4776  , size_t... CCAs > // Compile time column arguments
4778 {
4779  for( size_t j=0UL; j<columns(); ++j ) {
4780  reset( j );
4781  }
4782 }
4784 //*************************************************************************************************
4785 
4786 
4787 //*************************************************************************************************
4796 template< typename MT // Type of the dense matrix
4797  , size_t... CCAs > // Compile time column arguments
4798 inline void Columns<MT,false,true,false,CCAs...>::reset( size_t j )
4799 {
4800  using blaze::reset;
4801 
4802  const size_t index( idx(j) );
4803  for( size_t i=0UL; i<rows(); ++i ) {
4804  reset( matrix_( i, index ) );
4805  }
4806 }
4808 //*************************************************************************************************
4809 
4810 
4811 
4812 
4813 //=================================================================================================
4814 //
4815 // NUMERIC FUNCTIONS
4816 //
4817 //=================================================================================================
4818 
4819 //*************************************************************************************************
4832 template< typename MT // Type of the dense matrix
4833  , size_t... CCAs > // Compile time column arguments
4834 inline Columns<MT,false,true,false,CCAs...>&
4836 {
4839 
4840  if( rows() != columns() ) {
4841  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4842  }
4843 
4844  const ResultType tmp( trans( *this ) );
4845 
4846  if( IsRestricted<MT>::value ) {
4847  for( size_t j=0UL; j<columns(); ++j ) {
4848  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4849  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4850  }
4851  }
4852  }
4853 
4854  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4855 
4856  smpAssign( left, tmp );
4857 
4858  return *this;
4859 }
4861 //*************************************************************************************************
4862 
4863 
4864 //*************************************************************************************************
4877 template< typename MT // Type of the dense matrix
4878  , size_t... CCAs > // Compile time column arguments
4879 inline Columns<MT,false,true,false,CCAs...>&
4881 {
4884 
4885  if( rows() != columns() ) {
4886  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4887  }
4888 
4889  const ResultType tmp( ctrans( *this ) );
4890 
4891  if( IsRestricted<MT>::value ) {
4892  for( size_t j=0UL; j<columns(); ++j ) {
4893  if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4894  BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4895  }
4896  }
4897  }
4898 
4899  BLAZE_DECLTYPE_AUTO( left, derestrict( *this ) );
4900 
4901  smpAssign( left, tmp );
4902 
4903  return *this;
4904 }
4906 //*************************************************************************************************
4907 
4908 
4909 //*************************************************************************************************
4922 template< typename MT // Type of the dense matrix
4923  , size_t... CCAs > // Compile time column arguments
4924 template< typename Other > // Data type of the scalar value
4925 inline Columns<MT,false,true,false,CCAs...>&
4926  Columns<MT,false,true,false,CCAs...>::scale( const Other& scalar )
4927 {
4931 
4932  for( size_t j=0UL; j<columns(); ++j )
4933  {
4934  const size_t index ( idx(j) );
4935  const size_t ibegin( IsLower<MT>::value ? ( IsStrictlyLower<MT>::value ? index+1UL : index ) : 0UL );
4936  const size_t iend ( IsUpper<MT>::value ? ( IsStrictlyUpper<MT>::value ? index : index+1UL ) : rows() );
4937 
4938  for( size_t i=ibegin; i<iend; ++i ) {
4939  matrix_(i,index) *= scalar;
4940  }
4941  }
4942 
4943  return *this;
4944 }
4946 //*************************************************************************************************
4947 
4948 
4949 
4950 
4951 //=================================================================================================
4952 //
4953 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4954 //
4955 //=================================================================================================
4956 
4957 //*************************************************************************************************
4968 template< typename MT // Type of the dense matrix
4969  , size_t... CCAs > // Compile time column arguments
4970 template< typename Other > // Data type of the foreign expression
4971 inline bool Columns<MT,false,true,false,CCAs...>::canAlias( const Other* alias ) const noexcept
4972 {
4973  return matrix_.isAliased( alias );
4974 }
4976 //*************************************************************************************************
4977 
4978 
4979 //*************************************************************************************************
4991 template< typename MT // Type of the dense matrix
4992  , size_t... CCAs > // Compile time column arguments
4993 template< typename MT2 // Data type of the foreign dense column selection
4994  , bool SO2 // Storage order of the foreign dense column selection
4995  , bool SF2 // Symmetry flag of the foreign dense column selection
4996  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column selection
4997 inline bool
4998  Columns<MT,false,true,false,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
4999 {
5000  return matrix_.isAliased( &alias->matrix_ );
5001 }
5003 //*************************************************************************************************
5004 
5005 
5006 //*************************************************************************************************
5017 template< typename MT // Type of the dense matrix
5018  , size_t... CCAs > // Compile time column arguments
5019 template< typename Other > // Data type of the foreign expression
5020 inline bool Columns<MT,false,true,false,CCAs...>::isAliased( const Other* alias ) const noexcept
5021 {
5022  return matrix_.isAliased( alias );
5023 }
5025 //*************************************************************************************************
5026 
5027 
5028 //*************************************************************************************************
5040 template< typename MT // Type of the dense matrix
5041  , size_t... CCAs > // Compile time column arguments
5042 template< typename MT2 // Data type of the foreign dense column selection
5043  , bool SO2 // Storage order of the foreign dense column selection
5044  , bool SF2 // Symmetry flag of the foreign dense column selection
5045  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column selection
5046 inline bool
5047  Columns<MT,false,true,false,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5048 {
5049  return matrix_.isAliased( &alias->matrix_ );
5050 }
5052 //*************************************************************************************************
5053 
5054 
5055 //*************************************************************************************************
5065 template< typename MT // Type of the dense matrix
5066  , size_t... CCAs > // Compile time column arguments
5067 inline bool Columns<MT,false,true,false,CCAs...>::isAligned() const noexcept
5068 {
5069  return false;
5070 }
5072 //*************************************************************************************************
5073 
5074 
5075 //*************************************************************************************************
5086 template< typename MT // Type of the dense matrix
5087  , size_t... CCAs > // Compile time column arguments
5088 inline bool Columns<MT,false,true,false,CCAs...>::canSMPAssign() const noexcept
5089 {
5090  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
5091 }
5093 //*************************************************************************************************
5094 
5095 
5096 //*************************************************************************************************
5108 template< typename MT // Type of the dense matrix
5109  , size_t... CCAs > // Compile time column arguments
5110 template< typename MT2 > // Type of the right-hand side dense matrix
5111 inline void Columns<MT,false,true,false,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
5112 {
5115 
5116  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5117  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5118 
5119  const size_t ipos( rows() & size_t(-2) );
5120  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5121 
5122  for( size_t j=0UL; j<columns(); ++j ) {
5123  const size_t index( idx(j) );
5124  for( size_t i=0UL; i<ipos; i+=2UL ) {
5125  matrix_(i ,index) = (~rhs)(i ,j);
5126  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
5127  }
5128  if( ipos < rows() ) {
5129  matrix_(ipos,index) = (~rhs)(ipos,j);
5130  }
5131  }
5132 }
5134 //*************************************************************************************************
5135 
5136 
5137 //*************************************************************************************************
5149 template< typename MT // Type of the dense matrix
5150  , size_t... CCAs > // Compile time column arguments
5151 template< typename MT2 > // Type of the right-hand side dense matrix
5152 inline void Columns<MT,false,true,false,CCAs...>::assign( const DenseMatrix<MT2,false>& rhs )
5153 {
5156 
5158 
5159  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5160  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5161 
5162  constexpr size_t block( BLOCK_SIZE );
5163 
5164  if( rows() < block && columns() < block )
5165  {
5166  const size_t ipos( (~rhs).rows() & size_t(-2) );
5167  for( size_t j=0UL; j<columns(); ++j ) {
5168  const size_t index( idx(j) );
5169  for( size_t i=0UL; i<ipos; i+=2UL ) {
5170  matrix_(i ,index) = (~rhs)(i ,j);
5171  matrix_(i+1UL,index) = (~rhs)(i+1UL,j);
5172  }
5173  if( ipos < (~rhs).rows() ) {
5174  matrix_(ipos,index) = (~rhs)(ipos,j);
5175  }
5176  }
5177  }
5178  else
5179  {
5180  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5181  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5182  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5183  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5184  for( size_t j=jj; j<jend; ++j ) {
5185  const size_t index( idx(j) );
5186  for( size_t i=ii; i<iend; ++i ) {
5187  matrix_(i,index) = (~rhs)(i,j);
5188  }
5189  }
5190  }
5191  }
5192  }
5193 }
5195 //*************************************************************************************************
5196 
5197 
5198 //*************************************************************************************************
5210 template< typename MT // Type of the dense matrix
5211  , size_t... CCAs > // Compile time column arguments
5212 template< typename MT2 > // Type of the right-hand side sparse matrix
5213 inline void Columns<MT,false,true,false,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
5214 {
5217 
5218  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5219  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5220 
5221  for( size_t j=0UL; j<columns(); ++j ) {
5222  const size_t index( idx(j) );
5223  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5224  matrix_(element->index(),index) = element->value();
5225  }
5226 }
5228 //*************************************************************************************************
5229 
5230 
5231 //*************************************************************************************************
5243 template< typename MT // Type of the dense matrix
5244  , size_t... CCAs > // Compile time column arguments
5245 template< typename MT2 > // Type of the right-hand side sparse matrix
5246 inline void Columns<MT,false,true,false,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
5247 {
5250 
5252 
5253  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5254  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5255 
5256  for( size_t i=0UL; i<rows(); ++i ) {
5257  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5258  matrix_(i,idx(element->index())) = element->value();
5259  }
5260 }
5262 //*************************************************************************************************
5263 
5264 
5265 //*************************************************************************************************
5277 template< typename MT // Type of the dense matrix
5278  , size_t... CCAs > // Compile time column arguments
5279 template< typename MT2 > // Type of the right-hand side dense matrix
5280 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
5281 {
5284 
5285  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5286  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5287 
5288  const size_t ipos( rows() & size_t(-2) );
5289  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5290 
5291  for( size_t j=0UL; j<columns(); ++j )
5292  {
5293  const size_t index( idx(j) );
5294  if( IsDiagonal<MT2>::value ) {
5295  matrix_(j,index) += (~rhs)(j,j);
5296  }
5297  else {
5298  for( size_t i=0UL; i<ipos; i+=2UL ) {
5299  matrix_(i ,index) += (~rhs)(i ,j);
5300  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
5301  }
5302  if( ipos < rows() ) {
5303  matrix_(ipos,index) += (~rhs)(ipos,j);
5304  }
5305  }
5306  }
5307 }
5309 //*************************************************************************************************
5310 
5311 
5312 //*************************************************************************************************
5324 template< typename MT // Type of the dense matrix
5325  , size_t... CCAs > // Compile time column arguments
5326 template< typename MT2 > // Type of the right-hand side dense matrix
5327 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
5328 {
5331 
5333 
5334  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5335  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5336 
5337  constexpr size_t block( BLOCK_SIZE );
5338 
5339  if( rows() < block && columns() < block )
5340  {
5341  const size_t ipos( (~rhs).rows() & size_t(-2) );
5342  for( size_t j=0UL; j<columns(); ++j ) {
5343  const size_t index( idx(j) );
5344  for( size_t i=0UL; i<ipos; i+=2UL ) {
5345  matrix_(i ,index) += (~rhs)(i ,j);
5346  matrix_(i+1UL,index) += (~rhs)(i+1UL,j);
5347  }
5348  if( ipos < (~rhs).rows() )
5349  matrix_(ipos,index) += (~rhs)(ipos,j);
5350  }
5351  }
5352  else
5353  {
5354  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5355  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5356  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5357  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5358  for( size_t j=jj; j<jend; ++j ) {
5359  const size_t index( idx(j) );
5360  for( size_t i=ii; i<iend; ++i ) {
5361  matrix_(i,index) += (~rhs)(i,j);
5362  }
5363  }
5364  }
5365  }
5366  }
5367 }
5369 //*************************************************************************************************
5370 
5371 
5372 //*************************************************************************************************
5384 template< typename MT // Type of the dense matrix
5385  , size_t... CCAs > // Compile time column arguments
5386 template< typename MT2 > // Type of the right-hand side sparse matrix
5387 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
5388 {
5391 
5392  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5393  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5394 
5395  for( size_t j=0UL; j<columns(); ++j ) {
5396  const size_t index( idx(j) );
5397  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5398  matrix_(element->index(),index) += element->value();
5399  }
5400 }
5402 //*************************************************************************************************
5403 
5404 
5405 //*************************************************************************************************
5417 template< typename MT // Type of the dense matrix
5418  , size_t... CCAs > // Compile time column arguments
5419 template< typename MT2 > // Type of the right-hand side sparse matrix
5420 inline void Columns<MT,false,true,false,CCAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
5421 {
5424 
5426 
5427  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5428  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5429 
5430  for( size_t i=0UL; i<rows(); ++i ) {
5431  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5432  matrix_(i,idx(element->index())) += element->value();
5433  }
5434 }
5436 //*************************************************************************************************
5437 
5438 
5439 //*************************************************************************************************
5451 template< typename MT // Type of the dense matrix
5452  , size_t... CCAs > // Compile time column arguments
5453 template< typename MT2 > // Type of the right-hand side dense matrix
5454 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
5455 {
5458 
5459  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5460  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5461 
5462  const size_t ipos( rows() & size_t(-2) );
5463  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5464 
5465  for( size_t j=0UL; j<columns(); ++j )
5466  {
5467  const size_t index( idx(j) );
5468 
5469  if( IsDiagonal<MT2>::value ) {
5470  matrix_(j,index) -= (~rhs)(j,j);
5471  }
5472  else {
5473  for( size_t i=0UL; i<ipos; i+=2UL ) {
5474  matrix_(i ,index) -= (~rhs)(i ,j);
5475  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
5476  }
5477  if( ipos < rows() ) {
5478  matrix_(ipos,index) -= (~rhs)(ipos,j);
5479  }
5480  }
5481  }
5482 }
5484 //*************************************************************************************************
5485 
5486 
5487 //*************************************************************************************************
5499 template< typename MT // Type of the dense matrix
5500  , size_t... CCAs > // Compile time column arguments
5501 template< typename MT2 > // Type of the right-hand side dense matrix
5502 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
5503 {
5506 
5508 
5509  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5510  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5511 
5512  constexpr size_t block( BLOCK_SIZE );
5513 
5514  if( rows() < block && columns() < block )
5515  {
5516  const size_t ipos( (~rhs).rows() & size_t(-2) );
5517  for( size_t j=0UL; j<columns(); ++j ) {
5518  const size_t index( idx(j) );
5519  for( size_t i=0UL; i<ipos; i+=2UL ) {
5520  matrix_(i ,index) -= (~rhs)(i ,j);
5521  matrix_(i+1UL,index) -= (~rhs)(i+1UL,j);
5522  }
5523  if( ipos < (~rhs).rows() )
5524  matrix_(ipos,index) -= (~rhs)(ipos,j);
5525  }
5526  }
5527  else
5528  {
5529  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5530  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5531  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5532  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5533  for( size_t j=jj; j<jend; ++j ) {
5534  const size_t index( idx(j) );
5535  for( size_t i=ii; i<iend; ++i ) {
5536  matrix_(i,index) -= (~rhs)(i,j);
5537  }
5538  }
5539  }
5540  }
5541  }
5542 }
5544 //*************************************************************************************************
5545 
5546 
5547 //*************************************************************************************************
5559 template< typename MT // Type of the dense matrix
5560  , size_t... CCAs > // Compile time column arguments
5561 template< typename MT2 > // Type of the right-hand side sparse matrix
5562 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
5563 {
5566 
5567  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5568  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5569 
5570  for( size_t j=0UL; j<columns(); ++j ) {
5571  const size_t index( idx(j) );
5572  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element )
5573  matrix_(element->index(),index) -= element->value();
5574  }
5575 }
5577 //*************************************************************************************************
5578 
5579 
5580 //*************************************************************************************************
5592 template< typename MT // Type of the dense matrix
5593  , size_t... CCAs > // Compile time column arguments
5594 template< typename MT2 > // Type of the right-hand side sparse matrix
5595 inline void Columns<MT,false,true,false,CCAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
5596 {
5599 
5601 
5602  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5603  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5604 
5605  for( size_t i=0UL; i<rows(); ++i ) {
5606  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element )
5607  matrix_(i,idx(element->index())) -= element->value();
5608  }
5609 }
5611 //*************************************************************************************************
5612 
5613 
5614 //*************************************************************************************************
5626 template< typename MT // Type of the dense matrix
5627  , size_t... CCAs > // Compile time column arguments
5628 template< typename MT2 > // Type of the right-hand side dense matrix
5629 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
5630 {
5633 
5634  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5635  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5636 
5637  const size_t ipos( rows() & size_t(-2) );
5638  BLAZE_INTERNAL_ASSERT( ( rows() - ( rows() % 2UL ) ) == ipos, "Invalid end calculation" );
5639 
5640  for( size_t j=0UL; j<columns(); ++j ) {
5641  const size_t index( idx(j) );
5642  for( size_t i=0UL; i<ipos; i+=2UL ) {
5643  matrix_(i ,index) *= (~rhs)(i ,j);
5644  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
5645  }
5646  if( ipos < rows() ) {
5647  matrix_(ipos,index) *= (~rhs)(ipos,j);
5648  }
5649  }
5650 }
5652 //*************************************************************************************************
5653 
5654 
5655 //*************************************************************************************************
5667 template< typename MT // Type of the dense matrix
5668  , size_t... CCAs > // Compile time column arguments
5669 template< typename MT2 > // Type of the right-hand side dense matrix
5670 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
5671 {
5674 
5676 
5677  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5678  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5679 
5680  constexpr size_t block( BLOCK_SIZE );
5681 
5682  if( rows() < block && columns() < block )
5683  {
5684  const size_t ipos( (~rhs).rows() & size_t(-2) );
5685  for( size_t j=0UL; j<columns(); ++j ) {
5686  const size_t index( idx(j) );
5687  for( size_t i=0UL; i<ipos; i+=2UL ) {
5688  matrix_(i ,index) *= (~rhs)(i ,j);
5689  matrix_(i+1UL,index) *= (~rhs)(i+1UL,j);
5690  }
5691  if( ipos < (~rhs).rows() )
5692  matrix_(ipos,index) *= (~rhs)(ipos,j);
5693  }
5694  }
5695  else
5696  {
5697  for( size_t jj=0UL; jj<columns(); jj+=block ) {
5698  const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5699  for( size_t ii=0UL; ii<rows(); ii+=block ) {
5700  const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5701  for( size_t j=jj; j<jend; ++j ) {
5702  const size_t index( idx(j) );
5703  for( size_t i=ii; i<iend; ++i ) {
5704  matrix_(i,index) *= (~rhs)(i,j);
5705  }
5706  }
5707  }
5708  }
5709  }
5710 }
5712 //*************************************************************************************************
5713 
5714 
5715 //*************************************************************************************************
5727 template< typename MT // Type of the dense matrix
5728  , size_t... CCAs > // Compile time column arguments
5729 template< typename MT2 > // Type of the right-hand side sparse matrix
5730 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
5731 {
5732  using blaze::reset;
5733 
5736 
5737  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5738  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5739 
5740  for( size_t j=0UL; j<columns(); ++j )
5741  {
5742  const size_t index( idx(j) );
5743  size_t i( 0UL );
5744 
5745  for( ConstIterator_<MT2> element=(~rhs).begin(j); element!=(~rhs).end(j); ++element ) {
5746  for( ; i<element->index(); ++i )
5747  reset( matrix_(i,index) );
5748  matrix_(i,index) *= element->value();
5749  ++i;
5750  }
5751 
5752  for( ; i<rows(); ++i ) {
5753  reset( matrix_(i,index) );
5754  }
5755  }
5756 }
5758 //*************************************************************************************************
5759 
5760 
5761 //*************************************************************************************************
5773 template< typename MT // Type of the dense matrix
5774  , size_t... CCAs > // Compile time column arguments
5775 template< typename MT2 > // Type of the right-hand side sparse matrix
5776 inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
5777 {
5778  using blaze::reset;
5779 
5782 
5784 
5785  BLAZE_INTERNAL_ASSERT( rows() == (~rhs).rows() , "Invalid number of rows" );
5786  BLAZE_INTERNAL_ASSERT( columns() == (~rhs).columns(), "Invalid number of columns" );
5787 
5788  for( size_t i=0UL; i<rows(); ++i )
5789  {
5790  size_t j( 0UL );
5791 
5792  for( ConstIterator_<MT2> element=(~rhs).begin(i); element!=(~rhs).end(i); ++element ) {
5793  for( ; j<element->index(); ++j )
5794  reset( matrix_(i,idx(j)) );
5795  matrix_(i,idx(j)) *= element->value();
5796  ++j;
5797  }
5798 
5799  for( ; j<columns(); ++j ) {
5800  reset( matrix_(i,idx(j)) );
5801  }
5802  }
5803 }
5805 //*************************************************************************************************
5806 
5807 
5808 
5809 
5810 
5811 
5812 
5813 
5814 //=================================================================================================
5815 //
5816 // CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
5817 //
5818 //=================================================================================================
5819 
5820 //*************************************************************************************************
5828 template< typename MT // Type of the dense matrix
5829  , size_t... CCAs > // Compile time column arguments
5830 class Columns<MT,false,true,true,CCAs...>
5831  : public View< DenseMatrix< Columns<MT,false,true,true,CCAs...>, true > >
5832  , private ColumnsData<CCAs...>
5833 {
5834  private:
5835  //**Type definitions****************************************************************************
5836  using DataType = ColumnsData<CCAs...>;
5837  using Operand = If_< IsExpression<MT>, MT, MT& >;
5838  //**********************************************************************************************
5839 
5840  public:
5841  //**Type definitions****************************************************************************
5843  using This = Columns<MT,false,true,true,CCAs...>;
5844 
5845  using BaseType = DenseMatrix<This,true>;
5846  using ViewedType = MT;
5847  using ResultType = ColumnsTrait_<MT,CCAs...>;
5848  using OppositeType = OppositeType_<ResultType>;
5849  using TransposeType = TransposeType_<ResultType>;
5850  using ElementType = ElementType_<MT>;
5851  using SIMDType = SIMDTrait_<ElementType>;
5852  using ReturnType = ReturnType_<MT>;
5853  using CompositeType = const Columns&;
5854 
5856  using ConstReference = ConstReference_<MT>;
5857 
5859  using Reference = If_< IsConst<MT>, ConstReference, Reference_<MT> >;
5860 
5862  using ConstPointer = ConstPointer_<MT>;
5863 
5865  using Pointer = If_< Or< IsConst<MT>, Not< HasMutableDataAccess<MT> > >, ConstPointer, Pointer_<MT> >;
5866 
5868  using ConstIterator = ConstIterator_<MT>;
5869 
5871  using Iterator = If_< IsConst<MT>, ConstIterator, Iterator_<MT> >;
5872  //**********************************************************************************************
5873 
5874  //**Compilation flags***************************************************************************
5876  enum : bool { simdEnabled = MT::simdEnabled };
5877 
5879  enum : bool { smpAssignable = MT::smpAssignable };
5880  //**********************************************************************************************
5881 
5882  //**Constructors********************************************************************************
5885  template< typename... RCAs >
5886  explicit inline Columns( MT& matrix, RCAs... args );
5887 
5888  inline Columns( const Columns& ) = default;
5889  inline Columns( Columns&& ) = default;
5891  //**********************************************************************************************
5892 
5893  //**Destructor**********************************************************************************
5894  // No explicitly declared destructor.
5895  //**********************************************************************************************
5896 
5897  //**Data access functions***********************************************************************
5900  inline Reference operator()( size_t i, size_t j );
5901  inline ConstReference operator()( size_t i, size_t j ) const;
5902  inline Reference at( size_t i, size_t j );
5903  inline ConstReference at( size_t i, size_t j ) const;
5904  inline Pointer data () noexcept;
5905  inline ConstPointer data () const noexcept;
5906  inline Pointer data ( size_t j ) noexcept;
5907  inline ConstPointer data ( size_t j ) const noexcept;
5908  inline Iterator begin ( size_t j );
5909  inline ConstIterator begin ( size_t j ) const;
5910  inline ConstIterator cbegin( size_t j ) const;
5911  inline Iterator end ( size_t j );
5912  inline ConstIterator end ( size_t j ) const;
5913  inline ConstIterator cend ( size_t j ) const;
5915  //**********************************************************************************************
5916 
5917  //**Assignment operators************************************************************************
5920  inline Columns& operator=( const ElementType& rhs );
5921 
5922  Columns& operator=( const Columns& ) = delete;
5924  //**********************************************************************************************
5925 
5926  //**Utility functions***************************************************************************
5929  using DataType::idx;
5930  using DataType::idces;
5931  using DataType::columns;
5932 
5933  inline MT& operand() noexcept;
5934  inline const MT& operand() const noexcept;
5935 
5936  inline size_t rows() const noexcept;
5937  inline size_t spacing() const noexcept;
5938  inline size_t capacity() const noexcept;
5939  inline size_t capacity( size_t j ) const noexcept;
5940  inline size_t nonZeros() const;
5941  inline size_t nonZeros( size_t j ) const;
5942  inline void reset();
5943  inline void reset( size_t j );
5945  //**********************************************************************************************
5946 
5947  //**Expression template evaluation functions****************************************************
5950  template< typename Other >
5951  inline bool canAlias( const Other* alias ) const noexcept;
5952 
5953  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
5954  inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
5955 
5956  template< typename Other >
5957  inline bool isAliased( const Other* alias ) const noexcept;
5958 
5959  template< typename MT2, bool SO2, bool SF2, size_t... CCAs2 >
5960  inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
5961 
5962  inline bool isAligned () const noexcept;
5963  inline bool canSMPAssign() const noexcept;
5964 
5965  BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
5966  BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
5967  BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
5969  //**********************************************************************************************
5970 
5971  private:
5972  //**Member variables****************************************************************************
5975  Operand matrix_;
5976 
5977  //**********************************************************************************************
5978 
5979  //**Friend declarations*************************************************************************
5980  template< typename MT2, bool SO2, bool DF2, bool SF2, size_t... CCAs2 > friend class Columns;
5981  //**********************************************************************************************
5982 
5983  //**Compile time checks*************************************************************************
5993  //**********************************************************************************************
5994 };
5996 //*************************************************************************************************
5997 
5998 
5999 
6000 
6001 //=================================================================================================
6002 //
6003 // CONSTRUCTORS
6004 //
6005 //=================================================================================================
6006 
6007 //*************************************************************************************************
6020 template< typename MT // Type of the dense matrix
6021  , size_t... CCAs > // Compile time column arguments
6022 template< typename... RCAs > // Runtime column arguments
6023 inline Columns<MT,false,true,true,CCAs...>::Columns( MT& matrix, RCAs... args )
6024  : DataType( args... ) // Base class initialization
6025  , matrix_ ( matrix ) // The matrix containing the columns
6026 {
6027  if( !Contains< TypeList<RCAs...>, Unchecked >::value ) {
6028  for( size_t j=0UL; j<columns(); ++j ) {
6029  if( matrix_.columns() <= idx(j) ) {
6030  BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
6031  }
6032  }
6033  }
6034 }
6036 //*************************************************************************************************
6037 
6038 
6039 
6040 
6041 //=================================================================================================
6042 //
6043 // DATA ACCESS FUNCTIONS
6044 //
6045 //=================================================================================================
6046 
6047 //*************************************************************************************************
6058 template< typename MT // Type of the dense matrix
6059  , size_t... CCAs > // Compile time column arguments
6060 inline typename Columns<MT,false,true,true,CCAs...>::Reference
6061  Columns<MT,false,true,true,CCAs...>::operator()( size_t i, size_t j )
6062 {
6063  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6064  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6065 
6066  return matrix_(idx(j),i);
6067 }
6069 //*************************************************************************************************
6070 
6071 
6072 //*************************************************************************************************
6083 template< typename MT // Type of the dense matrix
6084  , size_t... CCAs > // Compile time column arguments
6085 inline typename Columns<MT,false,true,true,CCAs...>::ConstReference
6086  Columns<MT,false,true,true,CCAs...>::operator()( size_t i, size_t j ) const
6087 {
6088  BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6089  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6090 
6091  return const_cast<const MT&>( matrix_ )(idx(j),i);
6092 }
6094 //*************************************************************************************************
6095 
6096 
6097 //*************************************************************************************************
6109 template< typename MT // Type of the dense matrix
6110  , size_t... CCAs > // Compile time column arguments
6111 inline typename Columns<MT,false,true,true,CCAs...>::Reference
6112  Columns<MT,false,true,true,CCAs...>::at( size_t i, size_t j )
6113 {
6114  if( i >= rows() ) {
6115  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6116  }
6117  if( j >= columns() ) {
6118  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6119  }
6120  return (*this)(i,j);
6121 }
6123 //*************************************************************************************************
6124 
6125 
6126 //*************************************************************************************************
6138 template< typename MT // Type of the dense matrix
6139  , size_t... CCAs > // Compile time column arguments
6140 inline typename Columns<MT,false,true,true,CCAs...>::ConstReference
6141  Columns<MT,false,true,true,CCAs...>::at( size_t i, size_t j ) const
6142 {
6143  if( i >= rows() ) {
6144  BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6145  }
6146  if( j >= columns() ) {
6147  BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6148  }
6149  return (*this)(i,j);
6150 }
6152 //*************************************************************************************************
6153 
6154 
6155 //*************************************************************************************************
6165 template< typename MT // Type of the dense matrix
6166  , size_t... CCAs > // Compile time column arguments
6167 inline typename Columns<MT,false,true,true,CCAs...>::Pointer
6169 {
6170  return matrix_.data( idx(0UL) );
6171 }
6173 //*************************************************************************************************
6174 
6175 
6176 //*************************************************************************************************
6186 template< typename MT // Type of the dense matrix
6187  , size_t... CCAs > // Compile time column arguments
6188 inline typename Columns<MT,false,true,true,CCAs...>::ConstPointer
6190 {
6191  return matrix_.data( idx(0UL) );
6192 }
6194 //*************************************************************************************************
6195 
6196 
6197 //*************************************************************************************************
6206 template< typename MT // Type of the dense matrix
6207  , size_t... CCAs > // Compile time column arguments
6208 inline typename Columns<MT,false,true,true,CCAs...>::Pointer
6209  Columns<MT,false,true,true,CCAs...>::data( size_t j ) noexcept
6210 {
6211  return matrix_.data( idx(j) );
6212 }
6214 //*************************************************************************************************
6215 
6216 
6217 //*************************************************************************************************
6226 template< typename MT // Type of the dense matrix
6227  , size_t... CCAs > // Compile time column arguments
6228 inline typename Columns<MT,false,true,true,CCAs...>::ConstPointer
6229  Columns<MT,false,true,true,CCAs...>::data( size_t j ) const noexcept
6230 {
6231  return matrix_.data( idx(j) );
6232 }
6234 //*************************************************************************************************
6235 
6236 
6237 //*************************************************************************************************
6246 template< typename MT // Type of the dense matrix
6247  , size_t... CCAs > // Compile time column arguments
6248 inline typename Columns<MT,false,true,true,CCAs...>::Iterator
6250 {
6251  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6252  return matrix_.begin( idx(j) );
6253 }
6255 //*************************************************************************************************
6256 
6257 
6258 //*************************************************************************************************
6267 template< typename MT // Type of the dense matrix
6268  , size_t... CCAs > // Compile time column arguments
6269 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6271 {
6272  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6273  return matrix_.cbegin( idx(j) );
6274 }
6276 //*************************************************************************************************
6277 
6278 
6279 //*************************************************************************************************
6288 template< typename MT // Type of the dense matrix
6289  , size_t... CCAs > // Compile time column arguments
6290 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6292 {
6293  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6294  return matrix_.cbegin( idx(j) );
6295 }
6297 //*************************************************************************************************
6298 
6299 
6300 //*************************************************************************************************
6309 template< typename MT // Type of the dense matrix
6310  , size_t... CCAs > // Compile time column arguments
6311 inline typename Columns<MT,false,true,true,CCAs...>::Iterator
6313 {
6314  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6315  return matrix_.end( idx(j) );
6316 }
6318 //*************************************************************************************************
6319 
6320 
6321 //*************************************************************************************************
6330 template< typename MT // Type of the dense matrix
6331  , size_t... CCAs > // Compile time column arguments
6332 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6334 {
6335  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6336  return matrix_.cend( idx(j) );
6337 }
6339 //*************************************************************************************************
6340 
6341 
6342 //*************************************************************************************************
6351 template< typename MT // Type of the dense matrix
6352  , size_t... CCAs > // Compile time column arguments
6353 inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6355 {
6356  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6357  return matrix_.cend( idx(j) );
6358 }
6360 //*************************************************************************************************
6361 
6362 
6363 
6364 
6365 //=================================================================================================
6366 //
6367 // ASSIGNMENT OPERATORS
6368 //
6369 //=================================================================================================
6370 
6371 //*************************************************************************************************
6382 template< typename MT // Type of the dense matrix
6383  , size_t... CCAs > // Compile time column arguments
6384 inline Columns<MT,false,true,true,CCAs...>&
6385  Columns<MT,false,true,true,CCAs...>::operator=( const ElementType& rhs )
6386 {
6387  for( size_t j=0UL; j<columns(); ++j ) {
6388  row( matrix_, idx(j), unchecked ) = rhs;
6389  }
6390 
6391  return *this;
6392 }
6394 //*************************************************************************************************
6395 
6396 
6397 
6398 
6399 //=================================================================================================
6400 //
6401 // UTILITY FUNCTIONS
6402 //
6403 //=================================================================================================
6404 
6405 //*************************************************************************************************
6411 template< typename MT // Type of the dense matrix
6412  , size_t... CCAs > // Compile time column arguments
6413 inline MT& Columns<MT,false,true,true,CCAs...>::operand() noexcept
6414 {
6415  return matrix_;
6416 }
6418 //*************************************************************************************************
6419 
6420 
6421 //*************************************************************************************************
6427 template< typename MT // Type of the dense matrix
6428  , size_t... CCAs > // Compile time column arguments
6429 inline const MT& Columns<MT,false,true,true,CCAs...>::operand() const noexcept
6430 {
6431  return matrix_;
6432 }
6434 //*************************************************************************************************
6435 
6436 
6437 //*************************************************************************************************
6443 template< typename MT // Type of the dense matrix
6444  , size_t... CCAs > // Compile time column arguments
6445 inline size_t Columns<MT,false,true,true,CCAs...>::rows() const noexcept
6446 {
6447  return matrix_.rows();
6448 }
6450 //*************************************************************************************************
6451 
6452 
6453 //*************************************************************************************************
6462 template< typename MT // Type of the dense matrix
6463  , size_t... CCAs > // Compile time column arguments
6464 inline size_t Columns<MT,false,true,true,CCAs...>::spacing() const noexcept
6465 {
6466  return matrix_.spacing();
6467 }
6469 //*************************************************************************************************
6470 
6471 
6472 //*************************************************************************************************
6478 template< typename MT // Type of the dense matrix
6479  , size_t... CCAs > // Compile time column arguments
6480 inline size_t Columns<MT,false,true,true,CCAs...>::capacity() const noexcept
6481 {
6482  return rows() * columns();
6483 }
6485 //*************************************************************************************************
6486 
6487 
6488 //*************************************************************************************************
6497 template< typename MT // Type of the dense matrix
6498  , size_t... CCAs > // Compile time column arguments
6499 inline size_t Columns<MT,false,true,true,CCAs...>::capacity( size_t j ) const noexcept
6500 {
6501  UNUSED_PARAMETER( j );
6502 
6503  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6504 
6505  return rows();
6506 }
6508 //*************************************************************************************************
6509 
6510 
6511 //*************************************************************************************************
6517 template< typename MT // Type of the dense matrix
6518  , size_t... CCAs > // Compile time column arguments
6520 {
6521  size_t nonzeros( 0UL );
6522 
6523  for( size_t j=0UL; j<columns(); ++j ) {
6524  nonzeros += matrix_.nonZeros( idx(j) );
6525  }
6526 
6527  return nonzeros;
6528 }
6530 //*************************************************************************************************
6531 
6532 
6533 //*************************************************************************************************
6542 template< typename MT // Type of the dense matrix
6543  , size_t... CCAs > // Compile time column arguments
6544 inline size_t Columns<MT,false,true,true,CCAs...>::nonZeros( size_t j ) const
6545 {
6546  BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6547 
6548  return matrix_.nonZeros( idx(j) );
6549 }
6551 //*************************************************************************************************
6552 
6553 
6554 //*************************************************************************************************
6560 template< typename MT // Type of the dense matrix
6561  , size_t... CCAs > // Compile time column arguments
6563 {
6564  for( size_t j=0UL; j<columns(); ++j ) {
6565  matrix_.reset( idx(j) );
6566  }
6567 }
6569 //*************************************************************************************************
6570 
6571 
6572 //*************************************************************************************************
6581 template< typename MT // Type of the dense matrix
6582  , size_t... CCAs > // Compile time column arguments
6583 inline void Columns<MT,false,true,true,CCAs...>::reset( size_t j )
6584 {
6585  matrix_.reset( idx(j) );
6586 }
6588 //*************************************************************************************************
6589 
6590 
6591 //=================================================================================================
6592 //
6593 // EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6594 //
6595 //=================================================================================================
6596 
6597 //*************************************************************************************************
6608 template< typename MT // Type of the dense matrix
6609  , size_t... CCAs > // Compile time column arguments
6610 template< typename Other > // Data type of the foreign expression
6611 inline bool Columns<MT,false,true,true,CCAs...>::canAlias( const Other* alias ) const noexcept
6612 {
6613  return matrix_.isAliased( alias );
6614 }
6616 //*************************************************************************************************
6617 
6618 
6619 //*************************************************************************************************
6631 template< typename MT // Type of the dense matrix
6632  , size_t... CCAs > // Compile time column arguments
6633 template< typename MT2 // Data type of the foreign dense column selection
6634  , bool SO2 // Storage order of the foreign dense column selection
6635  , bool SF2 // Symmetry flag of the foreign dense column selection
6636  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column selection
6637 inline bool
6638  Columns<MT,false,true,true,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
6639 {
6640  return matrix_.isAliased( &alias->matrix_ );
6641 }
6643 //*************************************************************************************************
6644 
6645 
6646 //*************************************************************************************************
6657 template< typename MT // Type of the dense matrix
6658  , size_t... CCAs > // Compile time column arguments
6659 template< typename Other > // Data type of the foreign expression
6660 inline bool Columns<MT,false,true,true,CCAs...>::isAliased( const Other* alias ) const noexcept
6661 {
6662  return matrix_.isAliased( alias );
6663 }
6665 //*************************************************************************************************
6666 
6667 
6668 //*************************************************************************************************
6680 template< typename MT // Type of the dense matrix
6681  , size_t... CCAs > // Compile time column arguments
6682 template< typename MT2 // Data type of the foreign dense column selection
6683  , bool SO2 // Storage order of the foreign dense column selection
6684  , bool SF2 // Symmetry flag of the foreign dense column selection
6685  , size_t... CCAs2 > // Compile time column arguments of the foreign dense column selection
6686 inline bool
6687  Columns<MT,false,true,true,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
6688 {
6689  return matrix_.isAliased( &alias->matrix_ );
6690 }
6692 //*************************************************************************************************
6693 
6694 
6695 //*************************************************************************************************
6705 template< typename MT // Type of the dense matrix
6706  , size_t... CCAs > // Compile time column arguments
6707 inline bool Columns<MT,false,true,true,CCAs...>::isAligned() const noexcept
6708 {
6709  return matrix_.isAligned();
6710 }
6712 //*************************************************************************************************
6713 
6714 
6715 //*************************************************************************************************
6726 template< typename MT // Type of the dense matrix
6727  , size_t... CCAs > // Compile time column arguments
6728 inline bool Columns<MT,false,true,true,CCAs...>::canSMPAssign() const noexcept
6729 {
6730  return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
6731 }
6733 //*************************************************************************************************
6734 
6735 
6736 //*************************************************************************************************
6751 template< typename MT // Type of the dense matrix
6752  , size_t... CCAs > // Compile time column arguments
6753 BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6754  Columns<MT,false,true,true,CCAs...>::load( size_t i, size_t j ) const noexcept
6755 {
6756  return matrix_.load( idx(j), i );
6757 }
6759 //*************************************************************************************************
6760 
6761 
6762 //*************************************************************************************************
6777 template< typename MT // Type of the dense matrix
6778  , size_t... CCAs > // Compile time column arguments
6779 BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6780  Columns<MT,false,true,true,CCAs...>::loada( size_t i, size_t j ) const noexcept
6781 {
6782  return matrix_.loada( idx(j), i );
6783 }
6785 //*************************************************************************************************
6786 
6787 
6788 //*************************************************************************************************
6803 template< typename MT // Type of the dense matrix
6804  , size_t... CCAs > // Compile time column arguments
6805 BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6806  Columns<MT,false,true,true,CCAs...>::loadu( size_t i, size_t j ) const noexcept
6807 {
6808  return matrix_.loadu( idx(j), i );
6809 }
6811 //*************************************************************************************************
6812 
6813 } // namespace blaze
6814 
6815 #endif
Constraint on the data type.
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.This macro encapsulates the default way o...
Definition: Exception.h:235
Constraint on the data type.
Header file for auxiliary alias declarations.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:131
Header file for the blaze::checked and blaze::unchecked instances.
Header file for the implementation of the Columns base template.
Header file for kernel specific block sizes.
CompressedMatrix< Type, false > OppositeType
Result type with opposite storage order for expression template evaluations.
Definition: CompressedMatrix.h:3077
Header file for the Schur product trait.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Header file for the UNUSED_PARAMETER function template.
EnableIf_< IsDenseMatrix< MT1 > > smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:196
Header file for the subtraction trait.
BLAZE_ALWAYS_INLINE size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:522
Header file for basic type definitions.
Header file for the View base class.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:164
Header file for the IsSparseMatrix type trait.
Header file for the IsDiagonal type trait.
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.In case the given data type T is a computational expression (i...
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a dense, N-dimensional matrix type...
Definition: DenseMatrix.h:61
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:3076
BLAZE_ALWAYS_INLINE MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:364
CompressedMatrix< Type, true > This
Type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3074
void reset(const DiagonalProxy< MT > &proxy)
Resetting the represented element to the default initial values.
Definition: DiagonalProxy.h:588
const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:701
constexpr Unchecked unchecked
Global Unchecked instance.The blaze::unchecked instance is an optional token for the creation of view...
Definition: Check.h:138
typename DisableIf< Condition, T >::Type DisableIf_
Auxiliary type for the DisableIf class template.The DisableIf_ alias declaration provides a convenien...
Definition: DisableIf.h:224
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:3078
Header file for the And class template.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a submatrix type (i.e. a dense or sparse submatrix), a compilation error is created.
Definition: Submatrix.h:81
BLAZE_ALWAYS_INLINE void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:827
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a lower or upper unitriangular matrix ty...
Definition: UniTriangular.h:81
const Type & ConstReference
Reference to a constant matrix value.
Definition: CompressedMatrix.h:3083
BLAZE_ALWAYS_INLINE size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:560
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a symmetric matrix type...
Definition: Symmetric.h:60
Header file for the decltype(auto) workaround.
const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:733
Element * Iterator
Iterator over non-constant elements.
Definition: CompressedMatrix.h:3084
Constraints on the storage order of matrix types.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.In case the given data type T is a transposition expression (i...
Definition: TransExpr.h:81
Header file for the RequiresEvaluation type trait.
Header file for the extended initializer_list functionality.
System settings for performance optimizations.
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:77
EnableIf_< IsDenseMatrix< MT1 > > smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:133
BLAZE_ALWAYS_INLINE MT::ConstIterator cend(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:474
BLAZE_ALWAYS_INLINE MT::ConstIterator cbegin(const Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:408
Constraint on the data type.
Constraint on the data type.
BLAZE_ALWAYS_INLINE size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:252
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
Header file for the DisableIf class template.
Header file for the IsStrictlyUpper type trait.
Header file for the IsSymmetric type trait.
typename ColumnsTrait< MT, CCAs... >::Type ColumnsTrait_
Auxiliary alias declaration for the ColumnsTrait type trait.The ColumnsTrait_ alias declaration provi...
Definition: ColumnsTrait.h:145
MatrixAccessProxy< This > Reference
Reference to a non-constant matrix value.
Definition: CompressedMatrix.h:3082
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:1359
Header file for nested template disabiguation.
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
SparseMatrix< This, true > BaseType
Base type of this CompressedMatrix instance.
Definition: CompressedMatrix.h:3075
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.In case the given data type T is not a pointer type, a compilation error ...
Definition: Pointer.h:79
EnableIf_< IsDenseMatrix< MT1 > > smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:102
Type ElementType
Type of the compressed matrix elements.
Definition: CompressedMatrix.h:3079
Header file for the Or class template.
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.This macro encapsulates the default way of Bl...
Definition: Exception.h:331
Header file for the HasSIMDAdd type trait.
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:367
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value...
Definition: Accuracy.h:443
Header file for the Not class template.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:3085
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value. ...
Definition: Accuracy.h:250
Header file for all SIMD functionality.
Header file for the IsLower type trait.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:506
BLAZE_ALWAYS_INLINE const EnableIf_< And< IsIntegral< T >, HasSize< T, 1UL > >, If_< IsSigned< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:80
Constraint on the data type.
#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.
BLAZE_ALWAYS_INLINE MT::Iterator end(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator just past the last element of row/column i.
Definition: Matrix.h:430
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COLUMNS_TYPE(T)
Constraint on the data type.In case the given data type T is a column selection type (i...
Definition: Columns.h:81
decltype(auto) operator*(const DenseMatrix< MT1, false > &lhs, const DenseMatrix< MT2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:8893
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:290
Constraint on the data type.
Header file for the EnableIf class template.
Header file for the IsStrictlyLower type trait.
Constraint on the data type.
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:75
Header file for the IsSIMDCombinable type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is a symmetric matrix type, a compilation error is created.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is not a row-major dense or sparse matrix t...
Definition: RowMajorMatrix.h:61
Header file for the HasSIMDMult type trait.
Header file for the IsConst type trait.
BLAZE_ALWAYS_INLINE T1 & operator+=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Addition assignment operator for the addition of two SIMD packs.
Definition: BasicTypes.h:1357
Header file for run time assertion macros.
Header file for the addition trait.
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:131
Header file for the reset shim.
Header file for the cache size of the target architecture.
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.In case the given data type T is not a reference type, a compilation error is created.
Definition: Reference.h:79
Constraint on the data type.
Constraint on the data type.
Header file for the HasSIMDSub type trait.
Constraints on the storage order of matrix types.
Header file for the HasMutableDataAccess type trait.
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.In case the given data type T requires an intermediate evaluation within ...
Definition: RequiresEvaluation.h:81
Header file for the IsReference type trait.
typename EnableIf< Condition, T >::Type EnableIf_
Auxiliary alias declaration for the EnableIf class template.The EnableIf_ alias declaration provides ...
Definition: EnableIf.h:224
BLAZE_ALWAYS_INLINE EnableIf_< And< IsIntegral< T1 >, HasSize< T1, 1UL > > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:76
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:490
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:3080
BLAZE_ALWAYS_INLINE MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:169
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:789
Header file for the implementation of the ColumnsData class template.
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:3081
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:254
bool isDefault(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is in default state.
Definition: DiagonalProxy.h:628
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.In case the given data type T is an Hermitian matrix type, a compilation error is created.
Definition: Hermitian.h:79
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.This macro encapsulates the default way of Bla...
Definition: Exception.h:187
BLAZE_ALWAYS_INLINE T1 & operator-=(SIMDPack< T1 > &lhs, const SIMDPack< T2 > &rhs)
Subtraction assignment operator for the subtraction of two SIMD packs.
Definition: BasicTypes.h:1375
Header file for the IsUpper type trait.
void UNUSED_PARAMETER(const Args &...)
Suppression of unused parameter warnings.
Definition: Unused.h:81
Header file for the IsHermitian type trait.
Header file for the IsRestricted type trait.
System settings for the inline keywords.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the IsExpression type trait class.
Constraint on the data type.
BLAZE_ALWAYS_INLINE void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:801