Blaze 3.9
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>
63#include <blaze/math/SIMD.h>
87#include <blaze/system/Inline.h>
90#include <blaze/util/Assert.h>
94#include <blaze/util/EnableIf.h>
96#include <blaze/util/mpl/If.h>
97#include <blaze/util/Types.h>
100
101
102namespace blaze {
103
104//=================================================================================================
105//
106// CLASS TEMPLATE SPECIALIZATION FOR COLUMN-MAJOR DENSE MATRICES
107//
108//=================================================================================================
109
110//*************************************************************************************************
118template< typename MT // Type of the dense matrix
119 , bool SF // Symmetry flag
120 , typename... CCAs > // Compile time column arguments
121class Columns<MT,true,true,SF,CCAs...>
122 : public View< DenseMatrix< Columns<MT,true,true,SF,CCAs...>, true > >
123 , private ColumnsData<CCAs...>
124{
125 private:
126 //**Type definitions****************************************************************************
127 using DataType = ColumnsData<CCAs...>;
128 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
129 //**********************************************************************************************
130
131 //**Compile time flags**************************************************************************
132 using DataType::N;
133 //**********************************************************************************************
134
135 //**********************************************************************************************
137 template< typename MT1, typename MT2 >
138 static constexpr bool EnforceEvaluation_v =
139 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
140 //**********************************************************************************************
141
142 public:
143 //**Type definitions****************************************************************************
145 using This = Columns<MT,true,true,SF,CCAs...>;
146
148 using BaseType = View< DenseMatrix<This,true> >;
149
150 using ViewedType = MT;
151 using ResultType = ColumnsTrait_t<MT,N>;
152 using OppositeType = OppositeType_t<ResultType>;
153 using TransposeType = TransposeType_t<ResultType>;
154 using ElementType = ElementType_t<MT>;
155 using SIMDType = SIMDTrait_t<ElementType>;
156 using ReturnType = ReturnType_t<MT>;
157 using CompositeType = const Columns&;
158
160 using ConstReference = ConstReference_t<MT>;
161
163 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
164
166 using ConstPointer = ConstPointer_t<MT>;
167
169 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
170
172 using ConstIterator = ConstIterator_t<MT>;
173
175 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
176 //**********************************************************************************************
177
178 //**Compilation flags***************************************************************************
180 static constexpr bool simdEnabled = MT::simdEnabled;
181
183 static constexpr bool smpAssignable = MT::smpAssignable;
184
186 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
187 //**********************************************************************************************
188
189 //**Constructors********************************************************************************
192 template< typename... RCAs >
193 explicit inline Columns( MT& matrix, RCAs... args );
194
195 Columns( const Columns& ) = default;
196 Columns( Columns&& ) = default;
198 //**********************************************************************************************
199
200 //**Destructor**********************************************************************************
203 ~Columns() = default;
205 //**********************************************************************************************
206
207 //**Data access functions***********************************************************************
210 inline Reference operator()( size_t i, size_t j );
211 inline ConstReference operator()( size_t i, size_t j ) const;
212 inline Reference at( size_t i, size_t j );
213 inline ConstReference at( size_t i, size_t j ) const;
214 inline Pointer data () noexcept;
215 inline ConstPointer data () const noexcept;
216 inline Pointer data ( size_t j ) noexcept;
217 inline ConstPointer data ( size_t j ) const noexcept;
218 inline Iterator begin ( size_t j );
219 inline ConstIterator begin ( size_t j ) const;
220 inline ConstIterator cbegin( size_t j ) const;
221 inline Iterator end ( size_t j );
222 inline ConstIterator end ( size_t j ) const;
223 inline ConstIterator cend ( size_t j ) const;
225 //**********************************************************************************************
226
227 //**Assignment operators************************************************************************
230 inline Columns& operator=( const ElementType& rhs );
231 inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
232 inline Columns& operator=( const Columns& rhs );
233
234 template< typename MT2, bool SO2 >
235 inline Columns& operator=( const Matrix<MT2,SO2>& rhs );
236
237 template< typename MT2, bool SO2 >
238 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
239 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
240
241 template< typename MT2, bool SO2 >
242 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
243 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
244
245 template< typename MT2, bool SO2 >
246 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
247 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
248
249 template< typename MT2, bool SO2 >
250 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
251 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
252
253 template< typename MT2, bool SO2 >
254 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
255 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
256
257 template< typename MT2, bool SO2 >
258 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
259 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
261 //**********************************************************************************************
262
263 //**Utility functions***************************************************************************
266 using DataType::idx;
267 using DataType::idces;
268 using DataType::columns;
269
270 inline MT& operand() noexcept;
271 inline const MT& operand() const noexcept;
272
273 inline size_t rows() const noexcept;
274 inline size_t spacing() const noexcept;
275 inline size_t capacity() const noexcept;
276 inline size_t capacity( size_t j ) const noexcept;
277 inline size_t nonZeros() const;
278 inline size_t nonZeros( size_t j ) const;
279 inline void reset();
280 inline void reset( size_t j );
282 //**********************************************************************************************
283
284 //**Numeric functions***************************************************************************
287 inline Columns& transpose();
288 inline Columns& ctranspose();
289
290 template< typename Other > inline Columns& scale( const Other& scalar );
292 //**********************************************************************************************
293
294 private:
295 //**********************************************************************************************
297 template< typename MT2 >
298 static constexpr bool VectorizedAssign_v =
299 ( useOptimizedKernels &&
300 simdEnabled && MT2::simdEnabled &&
301 IsSIMDCombinable_v< ElementType, ElementType_t<MT2> > );
302 //**********************************************************************************************
303
304 //**********************************************************************************************
306 template< typename MT2 >
307 static constexpr bool VectorizedAddAssign_v =
308 ( VectorizedAssign_v<MT2> &&
309 HasSIMDAdd_v< ElementType, ElementType_t<MT2> > &&
310 !IsDiagonal_v<MT2> );
311 //**********************************************************************************************
312
313 //**********************************************************************************************
315 template< typename MT2 >
316 static constexpr bool VectorizedSubAssign_v =
317 ( VectorizedAssign_v<MT2> &&
318 HasSIMDSub_v< ElementType, ElementType_t<MT2> > &&
319 !IsDiagonal_v<MT2> );
320 //**********************************************************************************************
321
322 //**********************************************************************************************
324 template< typename MT2 >
325 static constexpr bool VectorizedSchurAssign_v =
326 ( VectorizedAssign_v<MT2> &&
327 HasSIMDMult_v< ElementType, ElementType_t<MT2> > );
328 //**********************************************************************************************
329
330 //**SIMD properties*****************************************************************************
332 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
333 //**********************************************************************************************
334
335 public:
336 //**Expression template evaluation functions****************************************************
339 template< typename Other >
340 inline bool canAlias( const Other* alias ) const noexcept;
341
342 template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
343 inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
344
345 template< typename Other >
346 inline bool isAliased( const Other* alias ) const noexcept;
347
348 template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
349 inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
350
351 inline bool isAligned () const noexcept;
352 inline bool canSMPAssign() const noexcept;
353
354 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
355 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
356 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
357
358 BLAZE_ALWAYS_INLINE void store ( size_t i, size_t j, const SIMDType& value ) noexcept;
359 BLAZE_ALWAYS_INLINE void storea( size_t i, size_t j, const SIMDType& value ) noexcept;
360 BLAZE_ALWAYS_INLINE void storeu( size_t i, size_t j, const SIMDType& value ) noexcept;
361 BLAZE_ALWAYS_INLINE void stream( size_t i, size_t j, const SIMDType& value ) noexcept;
362
363 template< typename MT2 >
364 inline auto assign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedAssign_v<MT2> >;
365
366 template< typename MT2 >
367 inline auto assign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedAssign_v<MT2> >;
368
369 template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
370
371 template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
372 template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
373
374 template< typename MT2 >
375 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedAddAssign_v<MT2> >;
376
377 template< typename MT2 >
378 inline auto addAssign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedAddAssign_v<MT2> >;
379
380 template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
381 template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
382 template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
383
384 template< typename MT2 >
385 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedSubAssign_v<MT2> >;
386
387 template< typename MT2 >
388 inline auto subAssign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedSubAssign_v<MT2> >;
389
390 template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
391 template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
392 template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
393
394 template< typename MT2 >
395 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) -> DisableIf_t< VectorizedSchurAssign_v<MT2> >;
396
397 template< typename MT2 >
398 inline auto schurAssign( const DenseMatrix<MT2,true>& rhs ) -> EnableIf_t< VectorizedSchurAssign_v<MT2> >;
399
400 template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
401 template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
402 template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
404 //**********************************************************************************************
405
406 private:
407 //**Member variables****************************************************************************
410 Operand matrix_;
412 //**********************************************************************************************
413
414 //**Friend declarations*************************************************************************
415 template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
416 //**********************************************************************************************
417
418 //**Compile time checks*************************************************************************
427 //**********************************************************************************************
428};
430//*************************************************************************************************
431
432
433
434
435//=================================================================================================
436//
437// CONSTRUCTORS
438//
439//=================================================================================================
440
441//*************************************************************************************************
454template< typename MT // Type of the dense matrix
455 , bool SF // Symmetry flag
456 , typename... CCAs > // Compile time column arguments
457template< typename... RCAs > // Runtime column arguments
458inline Columns<MT,true,true,SF,CCAs...>::Columns( MT& matrix, RCAs... args )
459 : DataType( args... ) // Base class initialization
460 , matrix_ ( matrix ) // The matrix containing the columns
461{
462 if( isChecked( args... ) ) {
463 for( size_t j=0UL; j<columns(); ++j ) {
464 if( matrix_.columns() <= idx(j) ) {
465 BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
466 }
467 }
468 }
469}
471//*************************************************************************************************
472
473
474
475
476//=================================================================================================
477//
478// DATA ACCESS FUNCTIONS
479//
480//=================================================================================================
481
482//*************************************************************************************************
493template< typename MT // Type of the dense matrix
494 , bool SF // Symmetry flag
495 , typename... CCAs > // Compile time column arguments
496inline typename Columns<MT,true,true,SF,CCAs...>::Reference
497 Columns<MT,true,true,SF,CCAs...>::operator()( size_t i, size_t j )
498{
499 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
500 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
501
502 return matrix_(i,idx(j));
503}
505//*************************************************************************************************
506
507
508//*************************************************************************************************
519template< typename MT // Type of the dense matrix
520 , bool SF // Symmetry flag
521 , typename... CCAs > // Compile time column arguments
522inline typename Columns<MT,true,true,SF,CCAs...>::ConstReference
523 Columns<MT,true,true,SF,CCAs...>::operator()( size_t i, size_t j ) const
524{
525 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
526 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
527
528 return const_cast<const MT&>( matrix_ )(i,idx(j));
529}
531//*************************************************************************************************
532
533
534//*************************************************************************************************
546template< typename MT // Type of the dense matrix
547 , bool SF // Symmetry flag
548 , typename... CCAs > // Compile time column arguments
549inline typename Columns<MT,true,true,SF,CCAs...>::Reference
550 Columns<MT,true,true,SF,CCAs...>::at( size_t i, size_t j )
551{
552 if( i >= rows() ) {
553 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
554 }
555 if( j >= columns() ) {
556 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
557 }
558 return (*this)(i,j);
559}
561//*************************************************************************************************
562
563
564//*************************************************************************************************
576template< typename MT // Type of the dense matrix
577 , bool SF // Symmetry flag
578 , typename... CCAs > // Compile time column arguments
579inline typename Columns<MT,true,true,SF,CCAs...>::ConstReference
580 Columns<MT,true,true,SF,CCAs...>::at( size_t i, size_t j ) const
581{
582 if( i >= rows() ) {
583 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
584 }
585 if( j >= columns() ) {
586 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
587 }
588 return (*this)(i,j);
589}
591//*************************************************************************************************
592
593
594//*************************************************************************************************
604template< typename MT // Type of the dense matrix
605 , bool SF // Symmetry flag
606 , typename... CCAs > // Compile time column arguments
607inline typename Columns<MT,true,true,SF,CCAs...>::Pointer
609{
610 return matrix_.data( idx(0UL) );
611}
613//*************************************************************************************************
614
615
616//*************************************************************************************************
626template< typename MT // Type of the dense matrix
627 , bool SF // Symmetry flag
628 , typename... CCAs > // Compile time column arguments
629inline typename Columns<MT,true,true,SF,CCAs...>::ConstPointer
631{
632 return matrix_.data( idx(0UL) );
633}
635//*************************************************************************************************
636
637
638//*************************************************************************************************
647template< typename MT // Type of the dense matrix
648 , bool SF // Symmetry flag
649 , typename... CCAs > // Compile time column arguments
650inline typename Columns<MT,true,true,SF,CCAs...>::Pointer
651 Columns<MT,true,true,SF,CCAs...>::data( size_t j ) noexcept
652{
653 return matrix_.data( idx(j) );
654}
656//*************************************************************************************************
657
658
659//*************************************************************************************************
668template< typename MT // Type of the dense matrix
669 , bool SF // Symmetry flag
670 , typename... CCAs > // Compile time column arguments
671inline typename Columns<MT,true,true,SF,CCAs...>::ConstPointer
672 Columns<MT,true,true,SF,CCAs...>::data( size_t j ) const noexcept
673{
674 return matrix_.data( idx(j) );
675}
677//*************************************************************************************************
678
679
680//*************************************************************************************************
689template< typename MT // Type of the dense matrix
690 , bool SF // Symmetry flag
691 , typename... CCAs > // Compile time column arguments
692inline typename Columns<MT,true,true,SF,CCAs...>::Iterator
694{
695 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
696 return matrix_.begin( idx(j) );
697}
699//*************************************************************************************************
700
701
702//*************************************************************************************************
711template< typename MT // Type of the dense matrix
712 , bool SF // Symmetry flag
713 , typename... CCAs > // Compile time column arguments
714inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
716{
717 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
718 return matrix_.cbegin( idx(j) );
719}
721//*************************************************************************************************
722
723
724//*************************************************************************************************
733template< typename MT // Type of the dense matrix
734 , bool SF // Symmetry flag
735 , typename... CCAs > // Compile time column arguments
736inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
738{
739 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
740 return matrix_.cbegin( idx(j) );
741}
743//*************************************************************************************************
744
745
746//*************************************************************************************************
755template< typename MT // Type of the dense matrix
756 , bool SF // Symmetry flag
757 , typename... CCAs > // Compile time column arguments
758inline typename Columns<MT,true,true,SF,CCAs...>::Iterator
760{
761 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
762 return matrix_.end( idx(j) );
763}
765//*************************************************************************************************
766
767
768//*************************************************************************************************
777template< typename MT // Type of the dense matrix
778 , bool SF // Symmetry flag
779 , typename... CCAs > // Compile time column arguments
780inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
782{
783 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
784 return matrix_.cend( idx(j) );
785}
787//*************************************************************************************************
788
789
790//*************************************************************************************************
799template< typename MT // Type of the dense matrix
800 , bool SF // Symmetry flag
801 , typename... CCAs > // Compile time column arguments
802inline typename Columns<MT,true,true,SF,CCAs...>::ConstIterator
804{
805 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
806 return matrix_.cend( idx(j) );
807}
809//*************************************************************************************************
810
811
812
813
814//=================================================================================================
815//
816// ASSIGNMENT OPERATORS
817//
818//=================================================================================================
819
820//*************************************************************************************************
831template< typename MT // Type of the dense matrix
832 , bool SF // Symmetry flag
833 , typename... CCAs > // Compile time column arguments
834inline Columns<MT,true,true,SF,CCAs...>&
835 Columns<MT,true,true,SF,CCAs...>::operator=( const ElementType& rhs )
836{
837 for( size_t j=0UL; j<columns(); ++j ) {
838 column( matrix_, idx(j), unchecked ) = rhs;
839 }
840
841 return *this;
842}
844//*************************************************************************************************
845
846
847//*************************************************************************************************
863template< typename MT // Type of the dense matrix
864 , bool SF // Symmetry flag
865 , typename... CCAs > // Compile time column arguments
866inline Columns<MT,true,true,SF,CCAs...>&
867 Columns<MT,true,true,SF,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
868{
871
872 if( list.size() != rows() ) {
873 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
874 }
875
876 if( IsRestricted_v<MT> ) {
877 const InitializerMatrix<ElementType> tmp( list, columns() );
878 for( size_t j=0UL; j<columns(); ++j ) {
879 if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
880 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
881 }
882 }
883 }
884
885 decltype(auto) left( derestrict( *this ) );
886 size_t i( 0UL );
887
888 for( const auto& rowList : list ) {
889 size_t j( 0UL );
890 for( const auto& element : rowList ) {
891 matrix_(i,idx(j)) = element;
892 ++j;
893 }
894 for( ; j<columns(); ++j ) {
895 matrix_(i,idx(j)) = ElementType();
896 }
897 ++i;
898 }
899
900 return *this;
901}
903//*************************************************************************************************
904
905
906//*************************************************************************************************
921template< typename MT // Type of the dense matrix
922 , bool SF // Symmetry flag
923 , typename... CCAs > // Compile time column arguments
924inline Columns<MT,true,true,SF,CCAs...>&
925 Columns<MT,true,true,SF,CCAs...>::operator=( const Columns& rhs )
926{
929
932
933 if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
934 return *this;
935
936 if( rows() != rhs.rows() || columns() != rhs.columns() ) {
937 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
938 }
939
940 if( IsRestricted_v<MT> ) {
941 for( size_t j=0UL; j<columns(); ++j ) {
942 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( rhs, j, unchecked ), 0UL ) ) {
943 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
944 }
945 }
946 }
947
948 decltype(auto) left( derestrict( *this ) );
949
950 if( rhs.canAlias( this ) ) {
951 const ResultType tmp( rhs );
952 smpAssign( left, tmp );
953 }
954 else {
955 smpAssign( left, rhs );
956 }
957
958 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
959
960 return *this;
961}
963//*************************************************************************************************
964
965
966//*************************************************************************************************
981template< typename MT // Type of the dense matrix
982 , bool SF // Symmetry flag
983 , typename... CCAs > // Compile time column arguments
984template< typename MT2 // Type of the right-hand side matrix
985 , bool SO2 > // Storage order of the right-hand side matrix
986inline Columns<MT,true,true,SF,CCAs...>&
987 Columns<MT,true,true,SF,CCAs...>::operator=( const Matrix<MT2,SO2>& rhs )
988{
991
993
994 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
995 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
996 }
997
998 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
999 Right right( *rhs );
1000
1001 if( IsRestricted_v<MT> ) {
1002 for( size_t j=0UL; j<columns(); ++j ) {
1003 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( right, j, unchecked ), 0UL ) ) {
1004 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1005 }
1006 }
1007 }
1008
1009 decltype(auto) left( derestrict( *this ) );
1010
1011 if( IsSparseMatrix_v<MT2> ) {
1012 reset();
1013 }
1014
1015 if( IsReference_v<Right> && right.canAlias( this ) ) {
1016 const ResultType_t<MT2> tmp( right );
1017 smpAssign( left, tmp );
1018 }
1019 else {
1020 smpAssign( left, right );
1021 }
1022
1023 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1024
1025 return *this;
1026}
1028//*************************************************************************************************
1029
1030
1031//*************************************************************************************************
1045template< typename MT // Type of the dense matrix
1046 , bool SF // Symmetry flag
1047 , typename... CCAs > // Compile time column arguments
1048template< typename MT2 // Type of the right-hand side matrix
1049 , bool SO2 > // Storage order of the right-hand side matrix
1050inline auto Columns<MT,true,true,SF,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1051 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1052{
1055
1059
1060 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1061
1064
1065 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1066 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1067 }
1068
1069 if( IsRestricted_v<MT> ) {
1070 for( size_t j=0UL; j<columns(); ++j ) {
1071 if( !tryAddAssign( column( matrix_, idx(j), unchecked ), column( *rhs, j, unchecked ), 0UL ) ) {
1072 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1073 }
1074 }
1075 }
1076
1077 decltype(auto) left( derestrict( *this ) );
1078
1079 if( (*rhs).canAlias( this ) ) {
1080 const AddType tmp( *this + (*rhs) );
1081 smpAssign( left, tmp );
1082 }
1083 else {
1084 smpAddAssign( left, *rhs );
1085 }
1086
1087 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1088
1089 return *this;
1090}
1092//*************************************************************************************************
1093
1094
1095//*************************************************************************************************
1109template< typename MT // Type of the dense matrix
1110 , bool SF // Symmetry flag
1111 , typename... CCAs > // Compile time column arguments
1112template< typename MT2 // Type of the right-hand side matrix
1113 , bool SO2 > // Storage order of the right-hand side matrix
1114inline auto Columns<MT,true,true,SF,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
1115 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1116{
1119
1123
1124 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
1125
1128
1129 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1130 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1131 }
1132
1133 const AddType tmp( *this + (*rhs) );
1134
1135 if( IsRestricted_v<MT> ) {
1136 for( size_t j=0UL; j<columns(); ++j ) {
1137 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1138 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1139 }
1140 }
1141 }
1142
1143 decltype(auto) left( derestrict( *this ) );
1144
1145 smpAssign( left, tmp );
1146
1147 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1148
1149 return *this;
1150}
1152//*************************************************************************************************
1153
1154
1155//*************************************************************************************************
1169template< typename MT // Type of the dense matrix
1170 , bool SF // Symmetry flag
1171 , typename... CCAs > // Compile time column arguments
1172template< typename MT2 // Type of the right-hand side matrix
1173 , bool SO2 > // Storage order of the right-hand side matrix
1174inline auto Columns<MT,true,true,SF,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1175 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1176{
1179
1183
1184 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1185
1188
1189 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1190 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1191 }
1192
1193 if( IsRestricted_v<MT> ) {
1194 for( size_t j=0UL; j<columns(); ++j ) {
1195 if( !trySubAssign( column( matrix_, idx(j), unchecked ), column( *rhs, j, unchecked ), 0UL ) ) {
1196 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1197 }
1198 }
1199 }
1200
1201 decltype(auto) left( derestrict( *this ) );
1202
1203 if( (*rhs).canAlias( this ) ) {
1204 const SubType tmp( *this - (*rhs ) );
1205 smpAssign( left, tmp );
1206 }
1207 else {
1208 smpSubAssign( left, *rhs );
1209 }
1210
1211 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1212
1213 return *this;
1214}
1216//*************************************************************************************************
1217
1218
1219//*************************************************************************************************
1233template< typename MT // Type of the dense matrix
1234 , bool SF // Symmetry flag
1235 , typename... CCAs > // Compile time column arguments
1236template< typename MT2 // Type of the right-hand side matrix
1237 , bool SO2 > // Storage order of the right-hand side matrix
1238inline auto Columns<MT,true,true,SF,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
1239 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1240{
1243
1247
1248 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
1249
1252
1253 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1254 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1255 }
1256
1257 const SubType tmp( *this - (*rhs) );
1258
1259 if( IsRestricted_v<MT> ) {
1260 for( size_t j=0UL; j<columns(); ++j ) {
1261 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1262 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1263 }
1264 }
1265 }
1266
1267 decltype(auto) left( derestrict( *this ) );
1268
1269 smpAssign( left, tmp );
1270
1271 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1272
1273 return *this;
1274}
1276//*************************************************************************************************
1277
1278
1279//*************************************************************************************************
1293template< typename MT // Type of the dense matrix
1294 , bool SF // Symmetry flag
1295 , typename... CCAs > // Compile time column arguments
1296template< typename MT2 // Type of the right-hand side matrix
1297 , bool SO2 > // Storage order of the right-hand side matrix
1298inline auto Columns<MT,true,true,SF,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1299 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1300{
1303
1307
1308 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1309
1311
1312 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1313 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1314 }
1315
1316 if( IsRestricted_v<MT> ) {
1317 for( size_t j=0UL; j<columns(); ++j ) {
1318 if( !tryMultAssign( column( matrix_, idx(j), unchecked ), column( *rhs, j, unchecked ), 0UL ) ) {
1319 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1320 }
1321 }
1322 }
1323
1324 decltype(auto) left( derestrict( *this ) );
1325
1326 if( (*rhs).canAlias( this ) ) {
1327 const SchurType tmp( *this % (*rhs) );
1328 if( IsSparseMatrix_v<SchurType> )
1329 reset();
1330 smpAssign( left, tmp );
1331 }
1332 else {
1333 smpSchurAssign( left, *rhs );
1334 }
1335
1336 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1337
1338 return *this;
1339}
1341//*************************************************************************************************
1342
1343
1344//*************************************************************************************************
1358template< typename MT // Type of the dense matrix
1359 , bool SF // Symmetry flag
1360 , typename... CCAs > // Compile time column arguments
1361template< typename MT2 // Type of the right-hand side matrix
1362 , bool SO2 > // Storage order of the right-hand side matrix
1363inline auto Columns<MT,true,true,SF,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
1364 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
1365{
1368
1372
1373 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
1374
1376
1377 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
1378 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
1379 }
1380
1381 const SchurType tmp( *this % (*rhs) );
1382
1383 if( IsRestricted_v<MT> ) {
1384 for( size_t j=0UL; j<columns(); ++j ) {
1385 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
1386 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
1387 }
1388 }
1389 }
1390
1391 decltype(auto) left( derestrict( *this ) );
1392
1393 if( IsSparseMatrix_v<SchurType> ) {
1394 reset();
1395 }
1396
1397 smpAssign( left, tmp );
1398
1399 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
1400
1401 return *this;
1402}
1404//*************************************************************************************************
1405
1406
1407
1408
1409//=================================================================================================
1410//
1411// UTILITY FUNCTIONS
1412//
1413//=================================================================================================
1414
1415//*************************************************************************************************
1421template< typename MT // Type of the dense matrix
1422 , bool SF // Symmetry flag
1423 , typename... CCAs > // Compile time column arguments
1424inline MT& Columns<MT,true,true,SF,CCAs...>::operand() noexcept
1425{
1426 return matrix_;
1427}
1429//*************************************************************************************************
1430
1431
1432//*************************************************************************************************
1438template< typename MT // Type of the dense matrix
1439 , bool SF // Symmetry flag
1440 , typename... CCAs > // Compile time column arguments
1441inline const MT& Columns<MT,true,true,SF,CCAs...>::operand() const noexcept
1442{
1443 return matrix_;
1444}
1446//*************************************************************************************************
1447
1448
1449//*************************************************************************************************
1455template< typename MT // Type of the dense matrix
1456 , bool SF // Symmetry flag
1457 , typename... CCAs > // Compile time column arguments
1458inline size_t Columns<MT,true,true,SF,CCAs...>::rows() const noexcept
1459{
1460 return matrix_.rows();
1461}
1463//*************************************************************************************************
1464
1465
1466//*************************************************************************************************
1475template< typename MT // Type of the dense matrix
1476 , bool SF // Symmetry flag
1477 , typename... CCAs > // Compile time column arguments
1478inline size_t Columns<MT,true,true,SF,CCAs...>::spacing() const noexcept
1479{
1480 return matrix_.spacing();
1481}
1483//*************************************************************************************************
1484
1485
1486//*************************************************************************************************
1492template< typename MT // Type of the dense matrix
1493 , bool SF // Symmetry flag
1494 , typename... CCAs > // Compile time column arguments
1495inline size_t Columns<MT,true,true,SF,CCAs...>::capacity() const noexcept
1496{
1497 return rows() * columns();
1498}
1500//*************************************************************************************************
1501
1502
1503//*************************************************************************************************
1512template< typename MT // Type of the dense matrix
1513 , bool SF // Symmetry flag
1514 , typename... CCAs > // Compile time column arguments
1515inline size_t Columns<MT,true,true,SF,CCAs...>::capacity( size_t j ) const noexcept
1516{
1517 MAYBE_UNUSED( j );
1518
1519 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1520
1521 return rows();
1522}
1524//*************************************************************************************************
1525
1526
1527//*************************************************************************************************
1533template< typename MT // Type of the dense matrix
1534 , bool SF // Symmetry flag
1535 , typename... CCAs > // Compile time column arguments
1537{
1538 size_t nonzeros( 0UL );
1539
1540 for( size_t j=0UL; j<columns(); ++j ) {
1541 nonzeros += matrix_.nonZeros( idx(j) );
1542 }
1543
1544 return nonzeros;
1545}
1547//*************************************************************************************************
1548
1549
1550//*************************************************************************************************
1559template< typename MT // Type of the dense matrix
1560 , bool SF // Symmetry flag
1561 , typename... CCAs > // Compile time column arguments
1562inline size_t Columns<MT,true,true,SF,CCAs...>::nonZeros( size_t j ) const
1563{
1564 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
1565
1566 return matrix_.nonZeros( idx(j) );
1567}
1569//*************************************************************************************************
1570
1571
1572//*************************************************************************************************
1578template< typename MT // Type of the dense matrix
1579 , bool SF // Symmetry flag
1580 , typename... CCAs > // Compile time column arguments
1582{
1583 for( size_t j=0UL; j<columns(); ++j ) {
1584 matrix_.reset( idx(j) );
1585 }
1586}
1588//*************************************************************************************************
1589
1590
1591//*************************************************************************************************
1600template< typename MT // Type of the dense matrix
1601 , bool SF // Symmetry flag
1602 , typename... CCAs > // Compile time column arguments
1603inline void Columns<MT,true,true,SF,CCAs...>::reset( size_t j )
1604{
1605 matrix_.reset( idx(j) );
1606}
1608//*************************************************************************************************
1609
1610
1611
1612
1613//=================================================================================================
1614//
1615// NUMERIC FUNCTIONS
1616//
1617//=================================================================================================
1618
1619//*************************************************************************************************
1632template< typename MT // Type of the dense matrix
1633 , bool SF // Symmetry flag
1634 , typename... CCAs > // Compile time column arguments
1635inline Columns<MT,true,true,SF,CCAs...>&
1637{
1640
1641 if( rows() != columns() ) {
1642 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1643 }
1644
1645 const ResultType tmp( trans( *this ) );
1646
1647 if( IsRestricted_v<MT> ) {
1648 for( size_t j=0UL; j<columns(); ++j ) {
1649 if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
1650 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1651 }
1652 }
1653 }
1654
1655 decltype(auto) left( derestrict( *this ) );
1656
1657 smpAssign( left, tmp );
1658
1659 return *this;
1660}
1662//*************************************************************************************************
1663
1664
1665//*************************************************************************************************
1678template< typename MT // Type of the dense matrix
1679 , bool SF // Symmetry flag
1680 , typename... CCAs > // Compile time column arguments
1681inline Columns<MT,true,true,SF,CCAs...>&
1683{
1686
1687 if( rows() != columns() ) {
1688 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
1689 }
1690
1691 const ResultType tmp( ctrans( *this ) );
1692
1693 if( IsRestricted_v<MT> ) {
1694 for( size_t j=0UL; j<columns(); ++j ) {
1695 if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
1696 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
1697 }
1698 }
1699 }
1700
1701 decltype(auto) left( derestrict( *this ) );
1702
1703 smpAssign( left, tmp );
1704
1705 return *this;
1706}
1708//*************************************************************************************************
1709
1710
1711//*************************************************************************************************
1724template< typename MT // Type of the dense matrix
1725 , bool SF // Symmetry flag
1726 , typename... CCAs > // Compile time column arguments
1727template< typename Other > // Data type of the scalar value
1728inline Columns<MT,true,true,SF,CCAs...>&
1729 Columns<MT,true,true,SF,CCAs...>::scale( const Other& scalar )
1730{
1734
1735 for( size_t j=0UL; j<columns(); ++j )
1736 {
1737 const size_t index ( idx(j) );
1738 const size_t ibegin( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index+1UL : index ) : 0UL );
1739 const size_t iend ( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index : index+1UL ) : rows() );
1740
1741 for( size_t i=ibegin; i<iend; ++i ) {
1742 matrix_(i,index) *= scalar;
1743 }
1744 }
1745
1746 return *this;
1747}
1749//*************************************************************************************************
1750
1751
1752
1753
1754//=================================================================================================
1755//
1756// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
1757//
1758//=================================================================================================
1759
1760//*************************************************************************************************
1771template< typename MT // Type of the dense matrix
1772 , bool SF // Symmetry flag
1773 , typename... CCAs > // Compile time column arguments
1774template< typename Other > // Data type of the foreign expression
1775inline bool Columns<MT,true,true,SF,CCAs...>::canAlias( const Other* alias ) const noexcept
1776{
1777 return matrix_.isAliased( &unview( *alias ) );
1778}
1780//*************************************************************************************************
1781
1782
1783//*************************************************************************************************
1795template< typename MT // Type of the dense matrix
1796 , bool SF // Symmetry flag
1797 , typename... CCAs > // Compile time column arguments
1798template< typename MT2 // Data type of the foreign dense column selection
1799 , bool SO2 // Storage order of the foreign dense column selection
1800 , bool SF2 // Symmetry flag of the foreign dense column selection
1801 , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
1802inline bool
1803 Columns<MT,true,true,SF,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1804{
1805 return matrix_.isAliased( &alias->matrix_ );
1806}
1808//*************************************************************************************************
1809
1810
1811//*************************************************************************************************
1822template< typename MT // Type of the dense matrix
1823 , bool SF // Symmetry flag
1824 , typename... CCAs > // Compile time column arguments
1825template< typename Other > // Data type of the foreign expression
1826inline bool Columns<MT,true,true,SF,CCAs...>::isAliased( const Other* alias ) const noexcept
1827{
1828 return matrix_.isAliased( &unview( *alias ) );
1829}
1831//*************************************************************************************************
1832
1833
1834//*************************************************************************************************
1846template< typename MT // Type of the dense matrix
1847 , bool SF // Symmetry flag
1848 , typename... CCAs > // Compile time column arguments
1849template< typename MT2 // Data type of the foreign dense column selection
1850 , bool SO2 // Storage order of the foreign dense column selection
1851 , bool SF2 // Symmetry flag of the foreign dense column selection
1852 , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
1853inline bool
1854 Columns<MT,true,true,SF,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
1855{
1856 return matrix_.isAliased( &alias->matrix_ );
1857}
1859//*************************************************************************************************
1860
1861
1862//*************************************************************************************************
1872template< typename MT // Type of the dense matrix
1873 , bool SF // Symmetry flag
1874 , typename... CCAs > // Compile time column arguments
1875inline bool Columns<MT,true,true,SF,CCAs...>::isAligned() const noexcept
1876{
1877 return matrix_.isAligned();
1878}
1880//*************************************************************************************************
1881
1882
1883//*************************************************************************************************
1894template< typename MT // Type of the dense matrix
1895 , bool SF // Symmetry flag
1896 , typename... CCAs > // Compile time column arguments
1897inline bool Columns<MT,true,true,SF,CCAs...>::canSMPAssign() const noexcept
1898{
1899 return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
1900}
1902//*************************************************************************************************
1903
1904
1905//*************************************************************************************************
1920template< typename MT // Type of the dense matrix
1921 , bool SF // Symmetry flag
1922 , typename... CCAs > // Compile time column arguments
1923BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1924 Columns<MT,true,true,SF,CCAs...>::load( size_t i, size_t j ) const noexcept
1925{
1926 return matrix_.load( i, idx(j) );
1927}
1929//*************************************************************************************************
1930
1931
1932//*************************************************************************************************
1947template< typename MT // Type of the dense matrix
1948 , bool SF // Symmetry flag
1949 , typename... CCAs > // Compile time column arguments
1950BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1951 Columns<MT,true,true,SF,CCAs...>::loada( size_t i, size_t j ) const noexcept
1952{
1953 return matrix_.loada( i, idx(j) );
1954}
1956//*************************************************************************************************
1957
1958
1959//*************************************************************************************************
1974template< typename MT // Type of the dense matrix
1975 , bool SF // Symmetry flag
1976 , typename... CCAs > // Compile time column arguments
1977BLAZE_ALWAYS_INLINE typename Columns<MT,true,true,SF,CCAs...>::SIMDType
1978 Columns<MT,true,true,SF,CCAs...>::loadu( size_t i, size_t j ) const noexcept
1979{
1980 return matrix_.loadu( i, idx(j) );
1981}
1983//*************************************************************************************************
1984
1985
1986//*************************************************************************************************
2002template< typename MT // Type of the dense matrix
2003 , bool SF // Symmetry flag
2004 , typename... CCAs > // Compile time column arguments
2006 Columns<MT,true,true,SF,CCAs...>::store( size_t i, size_t j, const SIMDType& value ) noexcept
2007{
2008 matrix_.store( i, idx(j), value );
2009}
2011//*************************************************************************************************
2012
2013
2014//*************************************************************************************************
2030template< typename MT // Type of the dense matrix
2031 , bool SF // Symmetry flag
2032 , typename... CCAs > // Compile time column arguments
2034 Columns<MT,true,true,SF,CCAs...>::storea( size_t i, size_t j, const SIMDType& value ) noexcept
2035{
2036 matrix_.storea( i, idx(j), value );
2037}
2039//*************************************************************************************************
2040
2041
2042//*************************************************************************************************
2058template< typename MT // Type of the dense matrix
2059 , bool SF // Symmetry flag
2060 , typename... CCAs > // Compile time column arguments
2062 Columns<MT,true,true,SF,CCAs...>::storeu( size_t i, size_t j, const SIMDType& value ) noexcept
2063{
2064 matrix_.storeu( i, idx(j), value );
2065}
2067//*************************************************************************************************
2068
2069
2070//*************************************************************************************************
2086template< typename MT // Type of the dense matrix
2087 , bool SF // Symmetry flag
2088 , typename... CCAs > // Compile time column arguments
2090 Columns<MT,true,true,SF,CCAs...>::stream( size_t i, size_t j, const SIMDType& value ) noexcept
2091{
2092 matrix_.stream( i, idx(j), value );
2093}
2095//*************************************************************************************************
2096
2097
2098//*************************************************************************************************
2110template< typename MT // Type of the dense matrix
2111 , bool SF // Symmetry flag
2112 , typename... CCAs > // Compile time column arguments
2113template< typename MT2 > // Type of the right-hand side dense matrix
2114inline auto Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2115 -> DisableIf_t< VectorizedAssign_v<MT2> >
2116{
2119
2120 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2121 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2122
2123 const size_t ipos( prevMultiple( rows(), 2UL ) );
2124 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
2125
2126 for( size_t j=0UL; j<columns(); ++j ) {
2127 const size_t index( idx(j) );
2128 for( size_t i=0UL; i<ipos; i+=2UL ) {
2129 matrix_(i ,index) = (*rhs)(i ,j);
2130 matrix_(i+1UL,index) = (*rhs)(i+1UL,j);
2131 }
2132 if( ipos < rows() ) {
2133 matrix_(ipos,index) = (*rhs)(ipos,j);
2134 }
2135 }
2136}
2138//*************************************************************************************************
2139
2140
2141//*************************************************************************************************
2153template< typename MT // Type of the dense matrix
2154 , bool SF // Symmetry flag
2155 , typename... CCAs > // Compile time column arguments
2156template< typename MT2 > // Type of the right-hand side dense matrix
2157inline auto Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
2158 -> EnableIf_t< VectorizedAssign_v<MT2> >
2159{
2162
2164
2165 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2166 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2167
2168 const size_t ipos( prevMultiple( rows(), SIMDSIZE ) );
2169 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
2170
2171 if( useStreaming &&
2172 rows()*columns() > ( cacheSize / ( sizeof(ElementType) * 3UL ) ) &&
2173 !(*rhs).isAliased( this ) )
2174 {
2175 for( size_t j=0UL; j<columns(); ++j )
2176 {
2177 size_t i( 0UL );
2178 Iterator left( begin(j) );
2179 ConstIterator_t<MT2> right( (*rhs).begin(j) );
2180
2181 for( ; i<ipos; i+=SIMDSIZE ) {
2182 left.stream( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2183 }
2184 for( ; i<rows(); ++i ) {
2185 *left = *right;
2186 }
2187 }
2188 }
2189 else
2190 {
2191 for( size_t j=0UL; j<columns(); ++j )
2192 {
2193 size_t i( 0UL );
2194 Iterator left( begin(j) );
2195 ConstIterator_t<MT2> right( (*rhs).begin(j) );
2196
2197 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
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 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2202 }
2203 for( ; i<ipos; i+=SIMDSIZE ) {
2204 left.store( right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2205 }
2206 for( ; i<rows(); ++i ) {
2207 *left = *right; ++left; ++right;
2208 }
2209 }
2210 }
2211}
2213//*************************************************************************************************
2214
2215
2216//*************************************************************************************************
2228template< typename MT // Type of the dense matrix
2229 , bool SF // Symmetry flag
2230 , typename... CCAs > // Compile time column arguments
2231template< typename MT2 > // Type of the right-hand side dense matrix
2232inline void Columns<MT,true,true,SF,CCAs...>::assign( const DenseMatrix<MT2,false>& rhs )
2233{
2236
2238
2239 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2240 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2241
2242 constexpr size_t block( BLOCK_SIZE );
2243
2244 if( rows() < block && columns() < block )
2245 {
2246 const size_t ipos( prevMultiple( (*rhs).rows(), 2UL ) );
2247 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).rows(), "Invalid end calculation" );
2248
2249 for( size_t j=0UL; j<columns(); ++j ) {
2250 const size_t index( idx(j) );
2251 for( size_t i=0UL; i<ipos; i+=2UL ) {
2252 matrix_(i ,index) = (*rhs)(i ,j);
2253 matrix_(i+1UL,index) = (*rhs)(i+1UL,j);
2254 }
2255 if( ipos < (*rhs).rows() ) {
2256 matrix_(ipos,index) = (*rhs)(ipos,j);
2257 }
2258 }
2259 }
2260 else
2261 {
2262 for( size_t jj=0UL; jj<columns(); jj+=block ) {
2263 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2264 for( size_t ii=0UL; ii<rows(); ii+=block ) {
2265 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2266 for( size_t j=jj; j<jend; ++j ) {
2267 const size_t index( idx(j) );
2268 for( size_t i=ii; i<iend; ++i ) {
2269 matrix_(i,index) = (*rhs)(i,j);
2270 }
2271 }
2272 }
2273 }
2274 }
2275}
2277//*************************************************************************************************
2278
2279
2280//*************************************************************************************************
2292template< typename MT // Type of the dense matrix
2293 , bool SF // Symmetry flag
2294 , typename... CCAs > // Compile time column arguments
2295template< typename MT2 > // Type of the right-hand side sparse matrix
2296inline void Columns<MT,true,true,SF,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
2297{
2300
2301 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2302 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2303
2304 for( size_t j=0UL; j<columns(); ++j ) {
2305 const size_t index( idx(j) );
2306 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2307 matrix_(element->index(),index) = element->value();
2308 }
2309}
2311//*************************************************************************************************
2312
2313
2314//*************************************************************************************************
2326template< typename MT // Type of the dense matrix
2327 , bool SF // Symmetry flag
2328 , typename... CCAs > // Compile time column arguments
2329template< typename MT2 > // Type of the right-hand side sparse matrix
2330inline void Columns<MT,true,true,SF,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
2331{
2334
2336
2337 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2338 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2339
2340 for( size_t i=0UL; i<rows(); ++i ) {
2341 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2342 matrix_(i,idx(element->index())) = element->value();
2343 }
2344}
2346//*************************************************************************************************
2347
2348
2349//*************************************************************************************************
2361template< typename MT // Type of the dense matrix
2362 , bool SF // Symmetry flag
2363 , typename... CCAs > // Compile time column arguments
2364template< typename MT2 > // Type of the right-hand side dense matrix
2365inline auto Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2366 -> DisableIf_t< VectorizedAddAssign_v<MT2> >
2367{
2370
2371 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2372 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2373
2374 const size_t ipos( prevMultiple( rows(), 2UL ) );
2375 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
2376
2377 for( size_t j=0UL; j<columns(); ++j )
2378 {
2379 const size_t index( idx(j) );
2380 if( IsDiagonal_v<MT2> ) {
2381 matrix_(j,index) += (*rhs)(j,j);
2382 }
2383 else {
2384 for( size_t i=0UL; i<ipos; i+=2UL ) {
2385 matrix_(i ,index) += (*rhs)(i ,j);
2386 matrix_(i+1UL,index) += (*rhs)(i+1UL,j);
2387 }
2388 if( ipos < rows() ) {
2389 matrix_(ipos,index) += (*rhs)(ipos,j);
2390 }
2391 }
2392 }
2393}
2395//*************************************************************************************************
2396
2397
2398//*************************************************************************************************
2410template< typename MT // Type of the dense matrix
2411 , bool SF // Symmetry flag
2412 , typename... CCAs > // Compile time column arguments
2413template< typename MT2 > // Type of the right-hand side dense matrix
2414inline auto Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
2415 -> EnableIf_t< VectorizedAddAssign_v<MT2> >
2416{
2419
2421
2422 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2423 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2424
2425 for( size_t j=0UL; j<columns(); ++j )
2426 {
2427 const size_t ibegin( ( IsLower_v<MT2> )
2428 ?( prevMultiple( ( IsStrictlyLower_v<MT2> ? j+1UL : j ), SIMDSIZE ) )
2429 :( 0UL ) );
2430 const size_t iend ( ( IsUpper_v<MT2> )
2431 ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
2432 :( rows() ) );
2433 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
2434
2435 const size_t ipos( prevMultiple( iend, SIMDSIZE ) );
2436 BLAZE_INTERNAL_ASSERT( ipos <= iend, "Invalid end calculation" );
2437
2438 size_t i( ibegin );
2439 Iterator left( begin(j) + ibegin );
2440 ConstIterator_t<MT2> right( (*rhs).begin(j) + ibegin );
2441
2442 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2443 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2444 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2445 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2446 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2447 }
2448 for( ; i<ipos; i+=SIMDSIZE ) {
2449 left.store( left.load() + right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2450 }
2451 for( ; i<iend; ++i ) {
2452 *left += *right; ++left; ++right;
2453 }
2454 }
2455}
2457//*************************************************************************************************
2458
2459
2460//*************************************************************************************************
2472template< typename MT // Type of the dense matrix
2473 , bool SF // Symmetry flag
2474 , typename... CCAs > // Compile time column arguments
2475template< typename MT2 > // Type of the right-hand side dense matrix
2476inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
2477{
2480
2482
2483 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2484 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2485
2486 constexpr size_t block( BLOCK_SIZE );
2487
2488 if( rows() < block && columns() < block )
2489 {
2490 const size_t ipos( prevMultiple( (*rhs).rows(), 2UL ) );
2491 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).rows(), "Invalid end calculation" );
2492
2493 for( size_t j=0UL; j<columns(); ++j ) {
2494 const size_t index( idx(j) );
2495 for( size_t i=0UL; i<ipos; i+=2UL ) {
2496 matrix_(i ,index) += (*rhs)(i ,j);
2497 matrix_(i+1UL,index) += (*rhs)(i+1UL,j);
2498 }
2499 if( ipos < (*rhs).rows() )
2500 matrix_(ipos,index) += (*rhs)(ipos,j);
2501 }
2502 }
2503 else
2504 {
2505 for( size_t jj=0UL; jj<columns(); jj+=block ) {
2506 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2507 for( size_t ii=0UL; ii<rows(); ii+=block ) {
2508 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2509 for( size_t j=jj; j<jend; ++j ) {
2510 const size_t index( idx(j) );
2511 for( size_t i=ii; i<iend; ++i ) {
2512 matrix_(i,index) += (*rhs)(i,j);
2513 }
2514 }
2515 }
2516 }
2517 }
2518}
2520//*************************************************************************************************
2521
2522
2523//*************************************************************************************************
2535template< typename MT // Type of the dense matrix
2536 , bool SF // Symmetry flag
2537 , typename... CCAs > // Compile time column arguments
2538template< typename MT2 > // Type of the right-hand side sparse matrix
2539inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
2540{
2543
2544 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2545 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2546
2547 for( size_t j=0UL; j<columns(); ++j ) {
2548 const size_t index( idx(j) );
2549 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2550 matrix_(element->index(),index) += element->value();
2551 }
2552}
2554//*************************************************************************************************
2555
2556
2557//*************************************************************************************************
2569template< typename MT // Type of the dense matrix
2570 , bool SF // Symmetry flag
2571 , typename... CCAs > // Compile time column arguments
2572template< typename MT2 > // Type of the right-hand side sparse matrix
2573inline void Columns<MT,true,true,SF,CCAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
2574{
2577
2579
2580 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2581 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2582
2583 for( size_t i=0UL; i<rows(); ++i ) {
2584 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2585 matrix_(i,idx(element->index())) += element->value();
2586 }
2587}
2589//*************************************************************************************************
2590
2591
2592//*************************************************************************************************
2604template< typename MT // Type of the dense matrix
2605 , bool SF // Symmetry flag
2606 , typename... CCAs > // Compile time column arguments
2607template< typename MT2 > // Type of the right-hand side dense matrix
2608inline auto Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2609 -> DisableIf_t< VectorizedSubAssign_v<MT2> >
2610{
2613
2614 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2615 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2616
2617 const size_t ipos( prevMultiple( rows(), 2UL ) );
2618 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
2619
2620 for( size_t j=0UL; j<columns(); ++j )
2621 {
2622 const size_t index( idx(j) );
2623
2624 if( IsDiagonal_v<MT2> ) {
2625 matrix_(j,index) -= (*rhs)(j,j);
2626 }
2627 else {
2628 for( size_t i=0UL; i<ipos; i+=2UL ) {
2629 matrix_(i ,index) -= (*rhs)(i ,j);
2630 matrix_(i+1UL,index) -= (*rhs)(i+1UL,j);
2631 }
2632 if( ipos < rows() ) {
2633 matrix_(ipos,index) -= (*rhs)(ipos,j);
2634 }
2635 }
2636 }
2637}
2639//*************************************************************************************************
2640
2641
2642//*************************************************************************************************
2654template< typename MT // Type of the dense matrix
2655 , bool SF // Symmetry flag
2656 , typename... CCAs > // Compile time column arguments
2657template< typename MT2 > // Type of the right-hand side dense matrix
2658inline auto Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
2659 -> EnableIf_t< VectorizedSubAssign_v<MT2> >
2660{
2663
2665
2666 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2667 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2668
2669 for( size_t j=0UL; j<columns(); ++j )
2670 {
2671 const size_t ibegin( ( IsLower_v<MT2> )
2672 ?( prevMultiple( ( IsStrictlyLower_v<MT2> ? j+1UL : j ), SIMDSIZE ) )
2673 :( 0UL ) );
2674 const size_t iend ( ( IsUpper_v<MT2> )
2675 ?( IsStrictlyUpper_v<MT2> ? j : j+1UL )
2676 :( rows() ) );
2677 BLAZE_INTERNAL_ASSERT( ibegin <= iend, "Invalid loop indices detected" );
2678
2679 const size_t ipos( prevMultiple( iend, SIMDSIZE ) );
2680 BLAZE_INTERNAL_ASSERT( ipos <= iend, "Invalid end calculation" );
2681
2682 size_t i( ibegin );
2683 Iterator left( begin(j) + ibegin );
2684 ConstIterator_t<MT2> right( (*rhs).begin(j) + ibegin );
2685
2686 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2687 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2688 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2689 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2690 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2691 }
2692 for( ; i<ipos; i+=SIMDSIZE ) {
2693 left.store( left.load() - right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2694 }
2695 for( ; i<iend; ++i ) {
2696 *left -= *right; ++left; ++right;
2697 }
2698 }
2699}
2701//*************************************************************************************************
2702
2703
2704//*************************************************************************************************
2716template< typename MT // Type of the dense matrix
2717 , bool SF // Symmetry flag
2718 , typename... CCAs > // Compile time column arguments
2719template< typename MT2 > // Type of the right-hand side dense matrix
2720inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
2721{
2724
2726
2727 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2728 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2729
2730 constexpr size_t block( BLOCK_SIZE );
2731
2732 if( rows() < block && columns() < block )
2733 {
2734 const size_t ipos( prevMultiple( (*rhs).rows(), 2UL ) );
2735 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).rows(), "Invalid end calculation" );
2736
2737 for( size_t j=0UL; j<columns(); ++j ) {
2738 const size_t index( idx(j) );
2739 for( size_t i=0UL; i<ipos; i+=2UL ) {
2740 matrix_(i ,index) -= (*rhs)(i ,j);
2741 matrix_(i+1UL,index) -= (*rhs)(i+1UL,j);
2742 }
2743 if( ipos < (*rhs).rows() )
2744 matrix_(ipos,index) -= (*rhs)(ipos,j);
2745 }
2746 }
2747 else
2748 {
2749 for( size_t jj=0UL; jj<columns(); jj+=block ) {
2750 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2751 for( size_t ii=0UL; ii<rows(); ii+=block ) {
2752 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2753 for( size_t j=jj; j<jend; ++j ) {
2754 const size_t index( idx(j) );
2755 for( size_t i=ii; i<iend; ++i ) {
2756 matrix_(i,index) -= (*rhs)(i,j);
2757 }
2758 }
2759 }
2760 }
2761 }
2762}
2764//*************************************************************************************************
2765
2766
2767//*************************************************************************************************
2779template< typename MT // Type of the dense matrix
2780 , bool SF // Symmetry flag
2781 , typename... CCAs > // Compile time column arguments
2782template< typename MT2 > // Type of the right-hand side sparse matrix
2783inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
2784{
2787
2788 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2789 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2790
2791 for( size_t j=0UL; j<columns(); ++j ) {
2792 const size_t index( idx(j) );
2793 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
2794 matrix_(element->index(),index) -= element->value();
2795 }
2796}
2798//*************************************************************************************************
2799
2800
2801//*************************************************************************************************
2813template< typename MT // Type of the dense matrix
2814 , bool SF // Symmetry flag
2815 , typename... CCAs > // Compile time column arguments
2816template< typename MT2 > // Type of the right-hand side sparse matrix
2817inline void Columns<MT,true,true,SF,CCAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
2818{
2821
2823
2824 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2825 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2826
2827 for( size_t i=0UL; i<rows(); ++i ) {
2828 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
2829 matrix_(i,idx(element->index())) -= element->value();
2830 }
2831}
2833//*************************************************************************************************
2834
2835
2836//*************************************************************************************************
2848template< typename MT // Type of the dense matrix
2849 , bool SF // Symmetry flag
2850 , typename... CCAs > // Compile time column arguments
2851template< typename MT2 > // Type of the right-hand side dense matrix
2852inline auto Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2853 -> DisableIf_t< VectorizedSchurAssign_v<MT2> >
2854{
2857
2858 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2859 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2860
2861 const size_t ipos( prevMultiple( rows(), 2UL ) );
2862 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
2863
2864 for( size_t j=0UL; j<columns(); ++j ) {
2865 const size_t index( idx(j) );
2866 for( size_t i=0UL; i<ipos; i+=2UL ) {
2867 matrix_(i ,index) *= (*rhs)(i ,j);
2868 matrix_(i+1UL,index) *= (*rhs)(i+1UL,j);
2869 }
2870 if( ipos < rows() ) {
2871 matrix_(ipos,index) *= (*rhs)(ipos,j);
2872 }
2873 }
2874}
2876//*************************************************************************************************
2877
2878
2879//*************************************************************************************************
2892template< typename MT // Type of the dense matrix
2893 , bool SF // Symmetry flag
2894 , typename... CCAs > // Compile time column arguments
2895template< typename MT2 > // Type of the right-hand side dense matrix
2896inline auto Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
2897 -> EnableIf_t< VectorizedSchurAssign_v<MT2> >
2898{
2901
2903
2904 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2905 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2906
2907 for( size_t j=0UL; j<columns(); ++j )
2908 {
2909 const size_t ipos( prevMultiple( rows(), SIMDSIZE ) );
2910 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
2911
2912 size_t i( 0UL );
2913 Iterator left( begin(j) );
2914 ConstIterator_t<MT2> right( (*rhs).begin(j) );
2915
2916 for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
2917 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2918 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2919 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2920 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2921 }
2922 for( ; i<ipos; i+=SIMDSIZE ) {
2923 left.store( left.load() * right.load() ); left += SIMDSIZE; right += SIMDSIZE;
2924 }
2925 for( ; i<rows(); ++i ) {
2926 *left *= *right; ++left; ++right;
2927 }
2928 }
2929}
2931//*************************************************************************************************
2932
2933
2934//*************************************************************************************************
2946template< typename MT // Type of the dense matrix
2947 , bool SF // Symmetry flag
2948 , typename... CCAs > // Compile time column arguments
2949template< typename MT2 > // Type of the right-hand side dense matrix
2950inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
2951{
2954
2956
2957 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
2958 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
2959
2960 constexpr size_t block( BLOCK_SIZE );
2961
2962 if( rows() < block && columns() < block )
2963 {
2964 const size_t ipos( prevMultiple( (*rhs).rows(), 2UL ) );
2965 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).rows(), "Invalid end calculation" );
2966
2967 for( size_t j=0UL; j<columns(); ++j ) {
2968 const size_t index( idx(j) );
2969 for( size_t i=0UL; i<ipos; i+=2UL ) {
2970 matrix_(i ,index) *= (*rhs)(i ,j);
2971 matrix_(i+1UL,index) *= (*rhs)(i+1UL,j);
2972 }
2973 if( ipos < (*rhs).rows() )
2974 matrix_(ipos,index) *= (*rhs)(ipos,j);
2975 }
2976 }
2977 else
2978 {
2979 for( size_t jj=0UL; jj<columns(); jj+=block ) {
2980 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
2981 for( size_t ii=0UL; ii<rows(); ii+=block ) {
2982 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
2983 for( size_t j=jj; j<jend; ++j ) {
2984 const size_t index( idx(j) );
2985 for( size_t i=ii; i<iend; ++i ) {
2986 matrix_(i,index) *= (*rhs)(i,j);
2987 }
2988 }
2989 }
2990 }
2991 }
2992}
2994//*************************************************************************************************
2995
2996
2997//*************************************************************************************************
3009template< typename MT // Type of the dense matrix
3010 , bool SF // Symmetry flag
3011 , typename... CCAs > // Compile time column arguments
3012template< typename MT2 > // Type of the right-hand side sparse matrix
3013inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
3014{
3017
3018 using blaze::reset;
3019
3020 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
3021 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
3022
3023 for( size_t j=0UL; j<columns(); ++j )
3024 {
3025 const size_t index( idx(j) );
3026 size_t i( 0UL );
3027
3028 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
3029 for( ; i<element->index(); ++i )
3030 reset( matrix_(i,index) );
3031 matrix_(i,index) *= element->value();
3032 ++i;
3033 }
3034
3035 for( ; i<rows(); ++i ) {
3036 reset( matrix_(i,index) );
3037 }
3038 }
3039}
3041//*************************************************************************************************
3042
3043
3044//*************************************************************************************************
3056template< typename MT // Type of the dense matrix
3057 , bool SF // Symmetry flag
3058 , typename... CCAs > // Compile time column arguments
3059template< typename MT2 > // Type of the right-hand side sparse matrix
3060inline void Columns<MT,true,true,SF,CCAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
3061{
3064
3065 using blaze::reset;
3066
3068
3069 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
3070 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
3071
3072 for( size_t i=0UL; i<rows(); ++i )
3073 {
3074 size_t j( 0UL );
3075
3076 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
3077 for( ; j<element->index(); ++j )
3078 reset( matrix_(i,idx(j)) );
3079 matrix_(i,idx(j)) *= element->value();
3080 ++j;
3081 }
3082
3083 for( ; j<columns(); ++j ) {
3084 reset( matrix_(i,idx(j)) );
3085 }
3086 }
3087}
3089//*************************************************************************************************
3090
3091
3092
3093
3094
3095
3096
3097
3098//=================================================================================================
3099//
3100// CLASS TEMPLATE SPECIALIZATION FOR GENERAL ROW-MAJOR DENSE MATRICES
3101//
3102//=================================================================================================
3103
3104//*************************************************************************************************
3112template< typename MT // Type of the dense matrix
3113 , typename... CCAs > // Compile time column arguments
3114class Columns<MT,false,true,false,CCAs...>
3115 : public View< DenseMatrix< Columns<MT,false,true,false,CCAs...>, true > >
3116 , private ColumnsData<CCAs...>
3117{
3118 private:
3119 //**Type definitions****************************************************************************
3120 using DataType = ColumnsData<CCAs...>;
3121 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
3122 //**********************************************************************************************
3123
3124 //**Compile time flags**************************************************************************
3125 using DataType::N;
3126 //**********************************************************************************************
3127
3128 //**********************************************************************************************
3130 template< typename MT1, typename MT2 >
3131 static constexpr bool EnforceEvaluation_v =
3132 ( IsRestricted_v<MT1> && RequiresEvaluation_v<MT2> );
3133 //**********************************************************************************************
3134
3135 public:
3136 //**Type definitions****************************************************************************
3138 using This = Columns<MT,false,true,false,CCAs...>;
3139
3141 using BaseType = View< DenseMatrix<This,true> >;
3142
3143 using ViewedType = MT;
3144 using ResultType = ColumnsTrait_t<MT,N>;
3145 using OppositeType = OppositeType_t<ResultType>;
3146 using TransposeType = TransposeType_t<ResultType>;
3147 using ElementType = ElementType_t<MT>;
3148 using ReturnType = ReturnType_t<MT>;
3149 using CompositeType = const Columns&;
3150
3152 using ConstReference = ConstReference_t<MT>;
3153
3155 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
3156
3158 using ConstPointer = ConstPointer_t<MT>;
3159
3161 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
3162 //**********************************************************************************************
3163
3164 //**ColumnsIterator class definition************************************************************
3167 template< typename MatrixType // Type of the dense matrix
3168 , typename IteratorType > // Type of the dense matrix iterator
3169 class ColumnsIterator
3170 {
3171 public:
3172 //**Type definitions*************************************************************************
3174 using IteratorCategory = typename std::iterator_traits<IteratorType>::iterator_category;
3175
3177 using ValueType = typename std::iterator_traits<IteratorType>::value_type;
3178
3180 using PointerType = typename std::iterator_traits<IteratorType>::pointer;
3181
3183 using ReferenceType = typename std::iterator_traits<IteratorType>::reference;
3184
3186 using DifferenceType = typename std::iterator_traits<IteratorType>::difference_type;
3187
3188 // STL iterator requirements
3189 using iterator_category = IteratorCategory;
3190 using value_type = ValueType;
3191 using pointer = PointerType;
3192 using reference = ReferenceType;
3193 using difference_type = DifferenceType;
3194 //*******************************************************************************************
3195
3196 //**Constructor******************************************************************************
3199 inline ColumnsIterator() noexcept
3200 : matrix_( nullptr ) // The dense matrix containing the column
3201 , row_ ( 0UL ) // The current row index
3202 , column_( 0UL ) // The current column index
3203 , pos_ ( ) // Iterator to the current dense element
3204 {}
3205 //*******************************************************************************************
3206
3207 //**Constructor******************************************************************************
3214 inline ColumnsIterator( MatrixType& matrix, size_t row, size_t column ) noexcept
3215 : matrix_( &matrix ) // The dense matrix containing the selected column
3216 , row_ ( row ) // The current row index
3217 , column_( column ) // The current column index
3218 , pos_ ( ) // Iterator to the current dense element
3219 {
3220 if( row_ != matrix_->rows() )
3221 pos_ = matrix_->begin( row_ ) + column_;
3222 }
3223 //*******************************************************************************************
3224
3225 //**Constructor******************************************************************************
3230 template< typename MatrixType2, typename IteratorType2 >
3231 inline ColumnsIterator( const ColumnsIterator<MatrixType2,IteratorType2>& it ) noexcept
3232 : matrix_( it.matrix_ ) // The dense matrix containing the seleted column
3233 , row_ ( it.row_ ) // The current row index
3234 , column_( it.column_ ) // The current column index
3235 , pos_ ( it.pos_ ) // Iterator to the current dense element
3236 {}
3237 //*******************************************************************************************
3238
3239 //**Addition assignment operator*************************************************************
3245 inline ColumnsIterator& operator+=( size_t inc ) noexcept {
3246 using blaze::reset;
3247 row_ += inc;
3248 if( row_ != matrix_->rows() )
3249 pos_ = matrix_->begin( row_ ) + column_;
3250 else reset( pos_ );
3251 return *this;
3252 }
3253 //*******************************************************************************************
3254
3255 //**Subtraction assignment operator**********************************************************
3261 inline ColumnsIterator& operator-=( size_t dec ) noexcept {
3262 using blaze::reset;
3263 row_ -= dec;
3264 if( row_ != matrix_->rows() )
3265 pos_ = matrix_->begin( row_ ) + column_;
3266 else reset( pos_ );
3267 return *this;
3268 }
3269 //*******************************************************************************************
3270
3271 //**Prefix increment operator****************************************************************
3276 inline ColumnsIterator& operator++() noexcept {
3277 using blaze::reset;
3278 ++row_;
3279 if( row_ != matrix_->rows() )
3280 pos_ = matrix_->begin( row_ ) + column_;
3281 else reset( pos_ );
3282 return *this;
3283 }
3284 //*******************************************************************************************
3285
3286 //**Postfix increment operator***************************************************************
3291 inline const ColumnsIterator operator++( int ) noexcept {
3292 const ColumnsIterator tmp( *this );
3293 ++(*this);
3294 return tmp;
3295 }
3296 //*******************************************************************************************
3297
3298 //**Prefix decrement operator****************************************************************
3303 inline ColumnsIterator& operator--() noexcept {
3304 using blaze::reset;
3305 --row_;
3306 if( row_ != matrix_->rows() )
3307 pos_ = matrix_->begin( row_ ) + column_;
3308 else reset( pos_ );
3309 return *this;
3310 }
3311 //*******************************************************************************************
3312
3313 //**Postfix decrement operator***************************************************************
3318 inline const ColumnsIterator operator--( int ) noexcept {
3319 const ColumnsIterator tmp( *this );
3320 --(*this);
3321 return tmp;
3322 }
3323 //*******************************************************************************************
3324
3325 //**Subscript operator***********************************************************************
3331 inline ReferenceType operator[]( size_t index ) const {
3332 BLAZE_USER_ASSERT( row_+index < matrix_->rows(), "Invalid access index detected" );
3333 const IteratorType pos( matrix_->begin( row_+index ) + column_ );
3334 return *pos;
3335 }
3336 //*******************************************************************************************
3337
3338 //**Element access operator******************************************************************
3343 inline ReferenceType operator*() const {
3344 return *pos_;
3345 }
3346 //*******************************************************************************************
3347
3348 //**Element access operator******************************************************************
3353 inline PointerType operator->() const {
3354 return pos_;
3355 }
3356 //*******************************************************************************************
3357
3358 //**Equality operator************************************************************************
3364 template< typename MatrixType2, typename IteratorType2 >
3365 inline bool operator==( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3366 return row_ == rhs.row_;
3367 }
3368 //*******************************************************************************************
3369
3370 //**Inequality operator**********************************************************************
3376 template< typename MatrixType2, typename IteratorType2 >
3377 inline bool operator!=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3378 return !( *this == rhs );
3379 }
3380 //*******************************************************************************************
3381
3382 //**Less-than operator***********************************************************************
3388 template< typename MatrixType2, typename IteratorType2 >
3389 inline bool operator<( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3390 return row_ < rhs.row_;
3391 }
3392 //*******************************************************************************************
3393
3394 //**Greater-than operator********************************************************************
3400 template< typename MatrixType2, typename IteratorType2 >
3401 inline bool operator>( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3402 return row_ > rhs.row_;
3403 }
3404 //*******************************************************************************************
3405
3406 //**Less-or-equal-than operator**************************************************************
3412 template< typename MatrixType2, typename IteratorType2 >
3413 inline bool operator<=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3414 return row_ <= rhs.row_;
3415 }
3416 //*******************************************************************************************
3417
3418 //**Greater-or-equal-than operator***********************************************************
3424 template< typename MatrixType2, typename IteratorType2 >
3425 inline bool operator>=( const ColumnsIterator<MatrixType2,IteratorType2>& rhs ) const noexcept {
3426 return row_ >= rhs.row_;
3427 }
3428 //*******************************************************************************************
3429
3430 //**Subtraction operator*********************************************************************
3436 inline DifferenceType operator-( const ColumnsIterator& rhs ) const noexcept {
3437 return row_ - rhs.row_;
3438 }
3439 //*******************************************************************************************
3440
3441 //**Addition operator************************************************************************
3448 friend inline const ColumnsIterator operator+( const ColumnsIterator& it, size_t inc ) noexcept {
3449 return ColumnsIterator( *it.matrix_, it.row_+inc, it.column_ );
3450 }
3451 //*******************************************************************************************
3452
3453 //**Addition operator************************************************************************
3460 friend inline const ColumnsIterator operator+( size_t inc, const ColumnsIterator& it ) noexcept {
3461 return ColumnsIterator( *it.matrix_, it.row_+inc, it.column_ );
3462 }
3463 //*******************************************************************************************
3464
3465 //**Subtraction operator*********************************************************************
3472 friend inline const ColumnsIterator operator-( const ColumnsIterator& it, size_t dec ) noexcept {
3473 return ColumnsIterator( *it.matrix_, it.row_-dec, it.column_ );
3474 }
3475 //*******************************************************************************************
3476
3477 private:
3478 //**Member variables*************************************************************************
3479 MatrixType* matrix_;
3480 size_t row_;
3481 size_t column_;
3482 IteratorType pos_;
3483 //*******************************************************************************************
3484
3485 //**Friend declarations**********************************************************************
3486 template< typename MatrixType2, typename IteratorType2 > friend class ColumnsIterator;
3487 //*******************************************************************************************
3488 };
3489 //**********************************************************************************************
3490
3491 //**Type definitions****************************************************************************
3493 using ConstIterator = ColumnsIterator< const MT, ConstIterator_t<MT> >;
3494
3496 using Iterator = If_t< IsConst_v<MT>, ConstIterator, ColumnsIterator< MT, Iterator_t<MT> > >;
3497 //**********************************************************************************************
3498
3499 //**Compilation flags***************************************************************************
3501 static constexpr bool simdEnabled = false;
3502
3504 static constexpr bool smpAssignable = MT::smpAssignable;
3505
3507 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
3508 //**********************************************************************************************
3509
3510 //**Constructors********************************************************************************
3513 template< typename... RCAs >
3514 explicit inline Columns( MT& matrix, RCAs... args );
3515
3516 Columns( const Columns& ) = default;
3517 Columns( Columns&& ) = default;
3519 //**********************************************************************************************
3520
3521 //**Destructor**********************************************************************************
3524 ~Columns() = default;
3526 //**********************************************************************************************
3527
3528 //**Data access functions***********************************************************************
3531 inline Reference operator()( size_t i, size_t j );
3532 inline ConstReference operator()( size_t i, size_t j ) const;
3533 inline Reference at( size_t i, size_t j );
3534 inline ConstReference at( size_t i, size_t j ) const;
3535 inline Pointer data () noexcept;
3536 inline ConstPointer data () const noexcept;
3537 inline Pointer data ( size_t j ) noexcept;
3538 inline ConstPointer data ( size_t j ) const noexcept;
3539 inline Iterator begin ( size_t j );
3540 inline ConstIterator begin ( size_t j ) const;
3541 inline ConstIterator cbegin( size_t j ) const;
3542 inline Iterator end ( size_t j );
3543 inline ConstIterator end ( size_t j ) const;
3544 inline ConstIterator cend ( size_t j ) const;
3546 //**********************************************************************************************
3547
3548 //**Assignment operators************************************************************************
3551 inline Columns& operator=( const ElementType& rhs );
3552 inline Columns& operator=( initializer_list< initializer_list<ElementType> > list );
3553 inline Columns& operator=( const Columns& rhs );
3554
3555 template< typename MT2, bool SO2 >
3556 inline Columns& operator=( const Matrix<MT2,SO2>& rhs );
3557
3558 template< typename MT2, bool SO2 >
3559 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3560 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3561
3562 template< typename MT2, bool SO2 >
3563 inline auto operator+=( const Matrix<MT2,SO2>& rhs )
3564 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3565
3566 template< typename MT2, bool SO2 >
3567 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3568 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3569
3570 template< typename MT2, bool SO2 >
3571 inline auto operator-=( const Matrix<MT2,SO2>& rhs )
3572 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3573
3574 template< typename MT2, bool SO2 >
3575 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3576 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3577
3578 template< typename MT2, bool SO2 >
3579 inline auto operator%=( const Matrix<MT2,SO2>& rhs )
3580 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >;
3582 //**********************************************************************************************
3583
3584 //**Utility functions***************************************************************************
3587 using DataType::idx;
3588 using DataType::idces;
3589 using DataType::columns;
3590
3591 inline MT& operand() noexcept;
3592 inline const MT& operand() const noexcept;
3593
3594 inline size_t rows() const noexcept;
3595 inline size_t spacing() const noexcept;
3596 inline size_t capacity() const noexcept;
3597 inline size_t capacity( size_t j ) const noexcept;
3598 inline size_t nonZeros() const;
3599 inline size_t nonZeros( size_t j ) const;
3600 inline void reset();
3601 inline void reset( size_t j );
3603 //**********************************************************************************************
3604
3605 //**Numeric functions***************************************************************************
3608 inline Columns& transpose();
3609 inline Columns& ctranspose();
3610
3611 template< typename Other > inline Columns& scale( const Other& scalar );
3613 //**********************************************************************************************
3614
3615 //**Expression template evaluation functions****************************************************
3618 template< typename Other >
3619 inline bool canAlias( const Other* alias ) const noexcept;
3620
3621 template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
3622 inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
3623
3624 template< typename Other >
3625 inline bool isAliased( const Other* alias ) const noexcept;
3626
3627 template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
3628 inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
3629
3630 inline bool isAligned () const noexcept;
3631 inline bool canSMPAssign() const noexcept;
3632
3633 template< typename MT2 > inline void assign( const DenseMatrix<MT2,true>& rhs );
3634 template< typename MT2 > inline void assign( const DenseMatrix<MT2,false>& rhs );
3635 template< typename MT2 > inline void assign( const SparseMatrix<MT2,true>& rhs );
3636 template< typename MT2 > inline void assign( const SparseMatrix<MT2,false>& rhs );
3637
3638 template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,true>& rhs );
3639 template< typename MT2 > inline void addAssign( const DenseMatrix<MT2,false>& rhs );
3640 template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,true>& rhs );
3641 template< typename MT2 > inline void addAssign( const SparseMatrix<MT2,false>& rhs );
3642
3643 template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,true>& rhs );
3644 template< typename MT2 > inline void subAssign( const DenseMatrix<MT2,false>& rhs );
3645 template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,true>& rhs );
3646 template< typename MT2 > inline void subAssign( const SparseMatrix<MT2,false>& rhs );
3647
3648 template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,true>& rhs );
3649 template< typename MT2 > inline void schurAssign( const DenseMatrix<MT2,false>& rhs );
3650 template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,true>& rhs );
3651 template< typename MT2 > inline void schurAssign( const SparseMatrix<MT2,false>& rhs );
3653 //**********************************************************************************************
3654
3655 private:
3656 //**Member variables****************************************************************************
3659 Operand matrix_;
3661 //**********************************************************************************************
3662
3663 //**Friend declarations*************************************************************************
3664 template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
3665 //**********************************************************************************************
3666
3667 //**Compile time checks*************************************************************************
3677 //**********************************************************************************************
3678};
3680//*************************************************************************************************
3681
3682
3683
3684
3685//=================================================================================================
3686//
3687// CONSTRUCTORS
3688//
3689//=================================================================================================
3690
3691//*************************************************************************************************
3704template< typename MT // Type of the dense matrix
3705 , typename... CCAs > // Compile time column arguments
3706template< typename... RCAs > // Runtime column arguments
3707inline Columns<MT,false,true,false,CCAs...>::Columns( MT& matrix, RCAs... args )
3708 : DataType( args... ) // Base class initialization
3709 , matrix_ ( matrix ) // The matrix containing the columns
3710{
3711 if( isChecked( args... ) ) {
3712 for( size_t j=0UL; j<columns(); ++j ) {
3713 if( matrix_.columns() <= idx(j) ) {
3714 BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
3715 }
3716 }
3717 }
3718}
3720//*************************************************************************************************
3721
3722
3723
3724
3725//=================================================================================================
3726//
3727// DATA ACCESS FUNCTIONS
3728//
3729//=================================================================================================
3730
3731//*************************************************************************************************
3742template< typename MT // Type of the dense matrix
3743 , typename... CCAs > // Compile time column arguments
3744inline typename Columns<MT,false,true,false,CCAs...>::Reference
3745 Columns<MT,false,true,false,CCAs...>::operator()( size_t i, size_t j )
3746{
3747 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3748 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3749
3750 return matrix_(i,idx(j));
3751}
3753//*************************************************************************************************
3754
3755
3756//*************************************************************************************************
3767template< typename MT // Type of the dense matrix
3768 , typename... CCAs > // Compile time column arguments
3769inline typename Columns<MT,false,true,false,CCAs...>::ConstReference
3770 Columns<MT,false,true,false,CCAs...>::operator()( size_t i, size_t j ) const
3771{
3772 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
3773 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3774
3775 return const_cast<const MT&>( matrix_ )(i,idx(j));
3776}
3778//*************************************************************************************************
3779
3780
3781//*************************************************************************************************
3793template< typename MT // Type of the dense matrix
3794 , typename... CCAs > // Compile time column arguments
3795inline typename Columns<MT,false,true,false,CCAs...>::Reference
3796 Columns<MT,false,true,false,CCAs...>::at( size_t i, size_t j )
3797{
3798 if( i >= rows() ) {
3799 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3800 }
3801 if( j >= columns() ) {
3802 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3803 }
3804 return (*this)(i,j);
3805}
3807//*************************************************************************************************
3808
3809
3810//*************************************************************************************************
3822template< typename MT // Type of the dense matrix
3823 , typename... CCAs > // Compile time column arguments
3824inline typename Columns<MT,false,true,false,CCAs...>::ConstReference
3825 Columns<MT,false,true,false,CCAs...>::at( size_t i, size_t j ) const
3826{
3827 if( i >= rows() ) {
3828 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
3829 }
3830 if( j >= columns() ) {
3831 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
3832 }
3833 return (*this)(i,j);
3834}
3836//*************************************************************************************************
3837
3838
3839//*************************************************************************************************
3849template< typename MT // Type of the dense matrix
3850 , typename... CCAs > // Compile time column arguments
3851inline typename Columns<MT,false,true,false,CCAs...>::Pointer
3853{
3854 return matrix_.data() + idx(0UL);
3855}
3857//*************************************************************************************************
3858
3859
3860//*************************************************************************************************
3870template< typename MT // Type of the dense matrix
3871 , typename... CCAs > // Compile time column arguments
3872inline typename Columns<MT,false,true,false,CCAs...>::ConstPointer
3874{
3875 return matrix_.data() + idx(0UL);
3876}
3878//*************************************************************************************************
3879
3880
3881//*************************************************************************************************
3890template< typename MT // Type of the dense matrix
3891 , typename... CCAs > // Compile time column arguments
3892inline typename Columns<MT,false,true,false,CCAs...>::Pointer
3894{
3895 return matrix_.data() + idx(j);
3896}
3898//*************************************************************************************************
3899
3900
3901//*************************************************************************************************
3910template< typename MT // Type of the dense matrix
3911 , typename... CCAs > // Compile time column arguments
3912inline typename Columns<MT,false,true,false,CCAs...>::ConstPointer
3913 Columns<MT,false,true,false,CCAs...>::data( size_t j ) const noexcept
3914{
3915 return matrix_.data() + idx(j);
3916}
3918//*************************************************************************************************
3919
3920
3921//*************************************************************************************************
3930template< typename MT // Type of the dense matrix
3931 , typename... CCAs > // Compile time column arguments
3932inline typename Columns<MT,false,true,false,CCAs...>::Iterator
3934{
3935 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3936 return Iterator( matrix_, 0UL, idx(j) );
3937}
3939//*************************************************************************************************
3940
3941
3942//*************************************************************************************************
3951template< typename MT // Type of the dense matrix
3952 , typename... CCAs > // Compile time column arguments
3953inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
3955{
3956 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3957 return ConstIterator( matrix_, 0UL, idx(j) );
3958}
3960//*************************************************************************************************
3961
3962
3963//*************************************************************************************************
3972template< typename MT // Type of the dense matrix
3973 , typename... CCAs > // Compile time column arguments
3974inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
3976{
3977 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3978 return ConstIterator( matrix_, 0UL, idx(j) );
3979}
3981//*************************************************************************************************
3982
3983
3984//*************************************************************************************************
3993template< typename MT // Type of the dense matrix
3994 , typename... CCAs > // Compile time column arguments
3995inline typename Columns<MT,false,true,false,CCAs...>::Iterator
3997{
3998 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
3999 return Iterator( matrix_, rows(), idx(j) );
4000}
4002//*************************************************************************************************
4003
4004
4005//*************************************************************************************************
4014template< typename MT // Type of the dense matrix
4015 , typename... CCAs > // Compile time column arguments
4016inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
4018{
4019 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4020 return ConstIterator( matrix_, rows(), idx(j) );
4021}
4023//*************************************************************************************************
4024
4025
4026//*************************************************************************************************
4035template< typename MT // Type of the dense matrix
4036 , typename... CCAs > // Compile time column arguments
4037inline typename Columns<MT,false,true,false,CCAs...>::ConstIterator
4039{
4040 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4041 return ConstIterator( matrix_, rows(), idx(j) );
4042}
4044//*************************************************************************************************
4045
4046
4047
4048
4049//=================================================================================================
4050//
4051// ASSIGNMENT OPERATORS
4052//
4053//=================================================================================================
4054
4055//*************************************************************************************************
4066template< typename MT // Type of the dense matrix
4067 , typename... CCAs > // Compile time column arguments
4068inline Columns<MT,false,true,false,CCAs...>&
4069 Columns<MT,false,true,false,CCAs...>::operator=( const ElementType& rhs )
4070{
4071 for( size_t j=0UL; j<columns(); ++j ) {
4072 column( matrix_, idx(j), unchecked ) = rhs;
4073 }
4074
4075 return *this;
4076}
4078//*************************************************************************************************
4079
4080
4081//*************************************************************************************************
4097template< typename MT // Type of the dense matrix
4098 , typename... CCAs > // Compile time column arguments
4099inline Columns<MT,false,true,false,CCAs...>&
4100 Columns<MT,false,true,false,CCAs...>::operator=( initializer_list< initializer_list<ElementType> > list )
4101{
4104
4105 if( list.size() != rows() ) {
4106 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to column selection" );
4107 }
4108
4109 if( IsRestricted_v<MT> ) {
4110 const InitializerMatrix<ElementType> tmp( list, columns() );
4111 for( size_t j=0UL; j<columns(); ++j ) {
4112 if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4113 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4114 }
4115 }
4116 }
4117
4118 decltype(auto) left( derestrict( *this ) );
4119 size_t i( 0UL );
4120
4121 for( const auto& rowList : list ) {
4122 size_t j( 0UL );
4123 for( const auto& element : rowList ) {
4124 matrix_(i,idx(j)) = element;
4125 ++j;
4126 }
4127 for( ; j<columns(); ++j ) {
4128 matrix_(i,idx(j)) = ElementType();
4129 }
4130 ++i;
4131 }
4132
4133 return *this;
4134}
4136//*************************************************************************************************
4137
4138
4139//*************************************************************************************************
4154template< typename MT // Type of the dense matrix
4155 , typename... CCAs > // Compile time column arguments
4156inline Columns<MT,false,true,false,CCAs...>&
4157 Columns<MT,false,true,false,CCAs...>::operator=( const Columns& rhs )
4158{
4161
4164
4165 if( this == &rhs || ( &matrix_ == &rhs.matrix_ && compareIndices( *this, rhs ) ) )
4166 return *this;
4167
4168 if( rows() != rhs.rows() || columns() != rhs.columns() ) {
4169 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4170 }
4171
4172 if( IsRestricted_v<MT> ) {
4173 for( size_t j=0UL; j<columns(); ++j ) {
4174 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( rhs, j, unchecked ), 0UL ) ) {
4175 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4176 }
4177 }
4178 }
4179
4180 decltype(auto) left( derestrict( *this ) );
4181
4182 if( rhs.canAlias( this ) ) {
4183 const ResultType tmp( rhs );
4184 smpAssign( left, tmp );
4185 }
4186 else {
4187 smpAssign( left, rhs );
4188 }
4189
4190 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4191
4192 return *this;
4193}
4195//*************************************************************************************************
4196
4197
4198//*************************************************************************************************
4213template< typename MT // Type of the dense matrix
4214 , typename... CCAs > // Compile time column arguments
4215template< typename MT2 // Type of the right-hand side matrix
4216 , bool SO2 > // Storage order of the right-hand side matrix
4217inline Columns<MT,false,true,false,CCAs...>&
4218 Columns<MT,false,true,false,CCAs...>::operator=( const Matrix<MT2,SO2>& rhs )
4219{
4222
4224
4225 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4226 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4227 }
4228
4229 using Right = If_t< IsRestricted_v<MT>, CompositeType_t<MT2>, const MT2& >;
4230 Right right( *rhs );
4231
4232 if( IsRestricted_v<MT> ) {
4233 for( size_t j=0UL; j<columns(); ++j ) {
4234 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( right, j, unchecked ), 0UL ) ) {
4235 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4236 }
4237 }
4238 }
4239
4240 decltype(auto) left( derestrict( *this ) );
4241
4242 if( IsSparseMatrix_v<MT2> ) {
4243 reset();
4244 }
4245
4246 if( IsReference_v<Right> && right.canAlias( this ) ) {
4247 const ResultType_t<MT2> tmp( right );
4248 smpAssign( left, tmp );
4249 }
4250 else {
4251 smpAssign( left, right );
4252 }
4253
4254 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4255
4256 return *this;
4257}
4259//*************************************************************************************************
4260
4261
4262//*************************************************************************************************
4276template< typename MT // Type of the dense matrix
4277 , typename... CCAs > // Compile time column arguments
4278template< typename MT2 // Type of the right-hand side matrix
4279 , bool SO2 > // Storage order of the right-hand side matrix
4280inline auto Columns<MT,false,true,false,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4281 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4282{
4285
4289
4290 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4291
4294
4295 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4296 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4297 }
4298
4299 if( IsRestricted_v<MT> ) {
4300 for( size_t j=0UL; j<columns(); ++j ) {
4301 if( !tryAddAssign( column( matrix_, idx(j), unchecked ), column( *rhs, j, unchecked ), 0UL ) ) {
4302 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4303 }
4304 }
4305 }
4306
4307 decltype(auto) left( derestrict( *this ) );
4308
4309 if( (*rhs).canAlias( this ) ) {
4310 const AddType tmp( *this + (*rhs) );
4311 smpAssign( left, tmp );
4312 }
4313 else {
4314 smpAddAssign( left, *rhs );
4315 }
4316
4317 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4318
4319 return *this;
4320}
4322//*************************************************************************************************
4323
4324
4325//*************************************************************************************************
4339template< typename MT // Type of the dense matrix
4340 , typename... CCAs > // Compile time column arguments
4341template< typename MT2 // Type of the right-hand side matrix
4342 , bool SO2 > // Storage order of the right-hand side matrix
4343inline auto Columns<MT,false,true,false,CCAs...>::operator+=( const Matrix<MT2,SO2>& rhs )
4344 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4345{
4348
4352
4353 using AddType = AddTrait_t< ResultType, ResultType_t<MT2> >;
4354
4357
4358 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4359 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4360 }
4361
4362 const AddType tmp( *this + (*rhs) );
4363
4364 if( IsRestricted_v<MT> ) {
4365 for( size_t j=0UL; j<columns(); ++j ) {
4366 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4367 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4368 }
4369 }
4370 }
4371
4372 decltype(auto) left( derestrict( *this ) );
4373
4374 smpAssign( left, tmp );
4375
4376 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4377
4378 return *this;
4379}
4381//*************************************************************************************************
4382
4383
4384//*************************************************************************************************
4398template< typename MT // Type of the dense matrix
4399 , typename... CCAs > // Compile time column arguments
4400template< typename MT2 // Type of the right-hand side matrix
4401 , bool SO2 > // Storage order of the right-hand side matrix
4402inline auto Columns<MT,false,true,false,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4403 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4404{
4407
4411
4412 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4413
4416
4417 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4418 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4419 }
4420
4421 if( IsRestricted_v<MT> ) {
4422 for( size_t j=0UL; j<columns(); ++j ) {
4423 if( !trySubAssign( column( matrix_, idx(j), unchecked ), column( *rhs, j, unchecked ), 0UL ) ) {
4424 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4425 }
4426 }
4427 }
4428
4429 decltype(auto) left( derestrict( *this ) );
4430
4431 if( (*rhs).canAlias( this ) ) {
4432 const SubType tmp( *this - (*rhs ) );
4433 smpAssign( left, tmp );
4434 }
4435 else {
4436 smpSubAssign( left, *rhs );
4437 }
4438
4439 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4440
4441 return *this;
4442}
4444//*************************************************************************************************
4445
4446
4447//*************************************************************************************************
4461template< typename MT // Type of the dense matrix
4462 , typename... CCAs > // Compile time column arguments
4463template< typename MT2 // Type of the right-hand side matrix
4464 , bool SO2 > // Storage order of the right-hand side matrix
4465inline auto Columns<MT,false,true,false,CCAs...>::operator-=( const Matrix<MT2,SO2>& rhs )
4466 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4467{
4470
4474
4475 using SubType = SubTrait_t< ResultType, ResultType_t<MT2> >;
4476
4479
4480 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4481 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4482 }
4483
4484 const SubType tmp( *this - (*rhs) );
4485
4486 if( IsRestricted_v<MT> ) {
4487 for( size_t j=0UL; j<columns(); ++j ) {
4488 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4489 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4490 }
4491 }
4492 }
4493
4494 decltype(auto) left( derestrict( *this ) );
4495
4496 smpAssign( left, tmp );
4497
4498 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4499
4500 return *this;
4501}
4503//*************************************************************************************************
4504
4505
4506//*************************************************************************************************
4520template< typename MT // Type of the dense matrix
4521 , typename... CCAs > // Compile time column arguments
4522template< typename MT2 // Type of the right-hand side matrix
4523 , bool SO2 > // Storage order of the right-hand side matrix
4524inline auto Columns<MT,false,true,false,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4525 -> DisableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4526{
4529
4533
4534 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4535
4537
4538 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4539 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4540 }
4541
4542 if( IsRestricted_v<MT> ) {
4543 for( size_t j=0UL; j<columns(); ++j ) {
4544 if( !tryMultAssign( column( matrix_, idx(j), unchecked ), column( *rhs, j, unchecked ), 0UL ) ) {
4545 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4546 }
4547 }
4548 }
4549
4550 decltype(auto) left( derestrict( *this ) );
4551
4552 if( (*rhs).canAlias( this ) ) {
4553 const SchurType tmp( *this % (*rhs) );
4554 if( IsSparseMatrix_v<SchurType> )
4555 reset();
4556 smpAssign( left, tmp );
4557 }
4558 else {
4559 smpSchurAssign( left, *rhs );
4560 }
4561
4562 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4563
4564 return *this;
4565}
4567//*************************************************************************************************
4568
4569
4570//*************************************************************************************************
4584template< typename MT // Type of the dense matrix
4585 , typename... CCAs > // Compile time column arguments
4586template< typename MT2 // Type of the right-hand side matrix
4587 , bool SO2 > // Storage order of the right-hand side matrix
4588inline auto Columns<MT,false,true,false,CCAs...>::operator%=( const Matrix<MT2,SO2>& rhs )
4589 -> EnableIf_t< EnforceEvaluation_v<MT,MT2>, Columns& >
4590{
4593
4597
4598 using SchurType = SchurTrait_t< ResultType, ResultType_t<MT2> >;
4599
4601
4602 if( rows() != (*rhs).rows() || columns() != (*rhs).columns() ) {
4603 BLAZE_THROW_INVALID_ARGUMENT( "Matrix sizes do not match" );
4604 }
4605
4606 const SchurType tmp( *this % (*rhs) );
4607
4608 if( IsRestricted_v<MT> ) {
4609 for( size_t j=0UL; j<columns(); ++j ) {
4610 if( !tryAssign( column( matrix_, idx(j), unchecked ), column( tmp, j, unchecked ), 0UL ) ) {
4611 BLAZE_THROW_INVALID_ARGUMENT( "Invalid assignment to restricted matrix" );
4612 }
4613 }
4614 }
4615
4616 decltype(auto) left( derestrict( *this ) );
4617
4618 if( IsSparseMatrix_v<SchurType> ) {
4619 reset();
4620 }
4621
4622 smpAssign( left, tmp );
4623
4624 BLAZE_INTERNAL_ASSERT( isIntact( matrix_ ), "Invariant violation detected" );
4625
4626 return *this;
4627}
4629//*************************************************************************************************
4630
4631
4632
4633
4634//=================================================================================================
4635//
4636// UTILITY FUNCTIONS
4637//
4638//=================================================================================================
4639
4640//*************************************************************************************************
4646template< typename MT // Type of the dense matrix
4647 , typename... CCAs > // Compile time column arguments
4648inline MT& Columns<MT,false,true,false,CCAs...>::operand() noexcept
4649{
4650 return matrix_;
4651}
4653//*************************************************************************************************
4654
4655
4656//*************************************************************************************************
4662template< typename MT // Type of the dense matrix
4663 , typename... CCAs > // Compile time column arguments
4664inline const MT& Columns<MT,false,true,false,CCAs...>::operand() const noexcept
4665{
4666 return matrix_;
4667}
4669//*************************************************************************************************
4670
4671
4672//*************************************************************************************************
4678template< typename MT // Type of the dense matrix
4679 , typename... CCAs > // Compile time column arguments
4680inline size_t Columns<MT,false,true,false,CCAs...>::rows() const noexcept
4681{
4682 return matrix_.rows();
4683}
4685//*************************************************************************************************
4686
4687
4688//*************************************************************************************************
4697template< typename MT // Type of the dense matrix
4698 , typename... CCAs > // Compile time column arguments
4699inline size_t Columns<MT,false,true,false,CCAs...>::spacing() const noexcept
4700{
4701 return matrix_.rows();
4702}
4704//*************************************************************************************************
4705
4706
4707//*************************************************************************************************
4713template< typename MT // Type of the dense matrix
4714 , typename... CCAs > // Compile time column arguments
4715inline size_t Columns<MT,false,true,false,CCAs...>::capacity() const noexcept
4716{
4717 return rows() * columns();
4718}
4720//*************************************************************************************************
4721
4722
4723//*************************************************************************************************
4732template< typename MT // Type of the dense matrix
4733 , typename... CCAs > // Compile time column arguments
4734inline size_t Columns<MT,false,true,false,CCAs...>::capacity( size_t j ) const noexcept
4735{
4736 MAYBE_UNUSED( j );
4737
4738 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4739
4740 return rows();
4741}
4743//*************************************************************************************************
4744
4745
4746//*************************************************************************************************
4752template< typename MT // Type of the dense matrix
4753 , typename... CCAs > // Compile time column arguments
4755{
4756 size_t nonzeros( 0UL );
4757
4758 for( size_t j=0UL; j<columns(); ++j ) {
4759 nonzeros += nonZeros( j );
4760 }
4761
4762 return nonzeros;
4763}
4765//*************************************************************************************************
4766
4767
4768//*************************************************************************************************
4777template< typename MT // Type of the dense matrix
4778 , typename... CCAs > // Compile time column arguments
4779inline size_t Columns<MT,false,true,false,CCAs...>::nonZeros( size_t j ) const
4780{
4781 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
4782
4783 size_t nonzeros( 0UL );
4784
4785 const size_t index( idx(j) );
4786 for( size_t i=0UL; i<rows(); ++i ) {
4787 if( !isDefault( matrix_( i, index ) ) )
4788 ++nonzeros;
4789 }
4790
4791 return nonzeros;
4792}
4794//*************************************************************************************************
4795
4796
4797//*************************************************************************************************
4803template< typename MT // Type of the dense matrix
4804 , typename... CCAs > // Compile time column arguments
4806{
4807 for( size_t j=0UL; j<columns(); ++j ) {
4808 reset( j );
4809 }
4810}
4812//*************************************************************************************************
4813
4814
4815//*************************************************************************************************
4824template< typename MT // Type of the dense matrix
4825 , typename... CCAs > // Compile time column arguments
4826inline void Columns<MT,false,true,false,CCAs...>::reset( size_t j )
4827{
4828 using blaze::reset;
4829
4830 const size_t index( idx(j) );
4831 for( size_t i=0UL; i<rows(); ++i ) {
4832 reset( matrix_( i, index ) );
4833 }
4834}
4836//*************************************************************************************************
4837
4838
4839
4840
4841//=================================================================================================
4842//
4843// NUMERIC FUNCTIONS
4844//
4845//=================================================================================================
4846
4847//*************************************************************************************************
4860template< typename MT // Type of the dense matrix
4861 , typename... CCAs > // Compile time column arguments
4862inline Columns<MT,false,true,false,CCAs...>&
4864{
4867
4868 if( rows() != columns() ) {
4869 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4870 }
4871
4872 const ResultType tmp( trans( *this ) );
4873
4874 if( IsRestricted_v<MT> ) {
4875 for( size_t j=0UL; j<columns(); ++j ) {
4876 if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4877 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4878 }
4879 }
4880 }
4881
4882 decltype(auto) left( derestrict( *this ) );
4883
4884 smpAssign( left, tmp );
4885
4886 return *this;
4887}
4889//*************************************************************************************************
4890
4891
4892//*************************************************************************************************
4905template< typename MT // Type of the dense matrix
4906 , typename... CCAs > // Compile time column arguments
4907inline Columns<MT,false,true,false,CCAs...>&
4909{
4912
4913 if( rows() != columns() ) {
4914 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose of a non-quadratic matrix" );
4915 }
4916
4917 const ResultType tmp( ctrans( *this ) );
4918
4919 if( IsRestricted_v<MT> ) {
4920 for( size_t j=0UL; j<columns(); ++j ) {
4921 if( !tryAssign( matrix_, column( tmp, j ), 0UL, idx(j) ) ) {
4922 BLAZE_THROW_LOGIC_ERROR( "Invalid transpose operation" );
4923 }
4924 }
4925 }
4926
4927 decltype(auto) left( derestrict( *this ) );
4928
4929 smpAssign( left, tmp );
4930
4931 return *this;
4932}
4934//*************************************************************************************************
4935
4936
4937//*************************************************************************************************
4950template< typename MT // Type of the dense matrix
4951 , typename... CCAs > // Compile time column arguments
4952template< typename Other > // Data type of the scalar value
4953inline Columns<MT,false,true,false,CCAs...>&
4954 Columns<MT,false,true,false,CCAs...>::scale( const Other& scalar )
4955{
4959
4960 for( size_t j=0UL; j<columns(); ++j )
4961 {
4962 const size_t index ( idx(j) );
4963 const size_t ibegin( IsLower<MT>::value ? ( IsStrictlyLower_v<MT> ? index+1UL : index ) : 0UL );
4964 const size_t iend ( IsUpper<MT>::value ? ( IsStrictlyUpper_v<MT> ? index : index+1UL ) : rows() );
4965
4966 for( size_t i=ibegin; i<iend; ++i ) {
4967 matrix_(i,index) *= scalar;
4968 }
4969 }
4970
4971 return *this;
4972}
4974//*************************************************************************************************
4975
4976
4977
4978
4979//=================================================================================================
4980//
4981// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
4982//
4983//=================================================================================================
4984
4985//*************************************************************************************************
4996template< typename MT // Type of the dense matrix
4997 , typename... CCAs > // Compile time column arguments
4998template< typename Other > // Data type of the foreign expression
4999inline bool Columns<MT,false,true,false,CCAs...>::canAlias( const Other* alias ) const noexcept
5000{
5001 return matrix_.isAliased( &unview( *alias ) );
5002}
5004//*************************************************************************************************
5005
5006
5007//*************************************************************************************************
5019template< typename MT // Type of the dense matrix
5020 , typename... CCAs > // Compile time column arguments
5021template< typename MT2 // Data type of the foreign dense column selection
5022 , bool SO2 // Storage order of the foreign dense column selection
5023 , bool SF2 // Symmetry flag of the foreign dense column selection
5024 , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
5025inline bool
5026 Columns<MT,false,true,false,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5027{
5028 return matrix_.isAliased( &alias->matrix_ );
5029}
5031//*************************************************************************************************
5032
5033
5034//*************************************************************************************************
5045template< typename MT // Type of the dense matrix
5046 , typename... CCAs > // Compile time column arguments
5047template< typename Other > // Data type of the foreign expression
5048inline bool Columns<MT,false,true,false,CCAs...>::isAliased( const Other* alias ) const noexcept
5049{
5050 return matrix_.isAliased( &unview( *alias ) );
5051}
5053//*************************************************************************************************
5054
5055
5056//*************************************************************************************************
5068template< typename MT // Type of the dense matrix
5069 , typename... CCAs > // Compile time column arguments
5070template< typename MT2 // Data type of the foreign dense column selection
5071 , bool SO2 // Storage order of the foreign dense column selection
5072 , bool SF2 // Symmetry flag of the foreign dense column selection
5073 , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
5074inline bool
5075 Columns<MT,false,true,false,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
5076{
5077 return matrix_.isAliased( &alias->matrix_ );
5078}
5080//*************************************************************************************************
5081
5082
5083//*************************************************************************************************
5093template< typename MT // Type of the dense matrix
5094 , typename... CCAs > // Compile time column arguments
5095inline bool Columns<MT,false,true,false,CCAs...>::isAligned() const noexcept
5096{
5097 return false;
5098}
5100//*************************************************************************************************
5101
5102
5103//*************************************************************************************************
5114template< typename MT // Type of the dense matrix
5115 , typename... CCAs > // Compile time column arguments
5116inline bool Columns<MT,false,true,false,CCAs...>::canSMPAssign() const noexcept
5117{
5118 return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
5119}
5121//*************************************************************************************************
5122
5123
5124//*************************************************************************************************
5136template< typename MT // Type of the dense matrix
5137 , typename... CCAs > // Compile time column arguments
5138template< typename MT2 > // Type of the right-hand side dense matrix
5139inline void Columns<MT,false,true,false,CCAs...>::assign( const DenseMatrix<MT2,true>& rhs )
5140{
5143
5144 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5145 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5146
5147 const size_t ipos( prevMultiple( rows(), 2UL ) );
5148 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
5149
5150 for( size_t j=0UL; j<columns(); ++j ) {
5151 const size_t index( idx(j) );
5152 for( size_t i=0UL; i<ipos; i+=2UL ) {
5153 matrix_(i ,index) = (*rhs)(i ,j);
5154 matrix_(i+1UL,index) = (*rhs)(i+1UL,j);
5155 }
5156 if( ipos < rows() ) {
5157 matrix_(ipos,index) = (*rhs)(ipos,j);
5158 }
5159 }
5160}
5162//*************************************************************************************************
5163
5164
5165//*************************************************************************************************
5177template< typename MT // Type of the dense matrix
5178 , typename... CCAs > // Compile time column arguments
5179template< typename MT2 > // Type of the right-hand side dense matrix
5180inline void Columns<MT,false,true,false,CCAs...>::assign( const DenseMatrix<MT2,false>& rhs )
5181{
5184
5186
5187 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5188 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5189
5190 constexpr size_t block( BLOCK_SIZE );
5191
5192 if( rows() < block && columns() < block )
5193 {
5194 const size_t ipos( prevMultiple( (*rhs).rows(), 2UL ) );
5195 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).rows(), "Invalid end calculation" );
5196
5197 for( size_t j=0UL; j<columns(); ++j ) {
5198 const size_t index( idx(j) );
5199 for( size_t i=0UL; i<ipos; i+=2UL ) {
5200 matrix_(i ,index) = (*rhs)(i ,j);
5201 matrix_(i+1UL,index) = (*rhs)(i+1UL,j);
5202 }
5203 if( ipos < (*rhs).rows() ) {
5204 matrix_(ipos,index) = (*rhs)(ipos,j);
5205 }
5206 }
5207 }
5208 else
5209 {
5210 for( size_t jj=0UL; jj<columns(); jj+=block ) {
5211 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5212 for( size_t ii=0UL; ii<rows(); ii+=block ) {
5213 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5214 for( size_t j=jj; j<jend; ++j ) {
5215 const size_t index( idx(j) );
5216 for( size_t i=ii; i<iend; ++i ) {
5217 matrix_(i,index) = (*rhs)(i,j);
5218 }
5219 }
5220 }
5221 }
5222 }
5223}
5225//*************************************************************************************************
5226
5227
5228//*************************************************************************************************
5240template< typename MT // Type of the dense matrix
5241 , typename... CCAs > // Compile time column arguments
5242template< typename MT2 > // Type of the right-hand side sparse matrix
5243inline void Columns<MT,false,true,false,CCAs...>::assign( const SparseMatrix<MT2,true>& rhs )
5244{
5247
5248 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5249 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5250
5251 for( size_t j=0UL; j<columns(); ++j ) {
5252 const size_t index( idx(j) );
5253 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
5254 matrix_(element->index(),index) = element->value();
5255 }
5256}
5258//*************************************************************************************************
5259
5260
5261//*************************************************************************************************
5273template< typename MT // Type of the dense matrix
5274 , typename... CCAs > // Compile time column arguments
5275template< typename MT2 > // Type of the right-hand side sparse matrix
5276inline void Columns<MT,false,true,false,CCAs...>::assign( const SparseMatrix<MT2,false>& rhs )
5277{
5280
5282
5283 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5284 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5285
5286 for( size_t i=0UL; i<rows(); ++i ) {
5287 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5288 matrix_(i,idx(element->index())) = element->value();
5289 }
5290}
5292//*************************************************************************************************
5293
5294
5295//*************************************************************************************************
5307template< typename MT // Type of the dense matrix
5308 , typename... CCAs > // Compile time column arguments
5309template< typename MT2 > // Type of the right-hand side dense matrix
5310inline void Columns<MT,false,true,false,CCAs...>::addAssign( const DenseMatrix<MT2,true>& rhs )
5311{
5314
5315 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5316 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5317
5318 const size_t ipos( prevMultiple( rows(), 2UL ) );
5319 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
5320
5321 for( size_t j=0UL; j<columns(); ++j )
5322 {
5323 const size_t index( idx(j) );
5324 if( IsDiagonal_v<MT2> ) {
5325 matrix_(j,index) += (*rhs)(j,j);
5326 }
5327 else {
5328 for( size_t i=0UL; i<ipos; i+=2UL ) {
5329 matrix_(i ,index) += (*rhs)(i ,j);
5330 matrix_(i+1UL,index) += (*rhs)(i+1UL,j);
5331 }
5332 if( ipos < rows() ) {
5333 matrix_(ipos,index) += (*rhs)(ipos,j);
5334 }
5335 }
5336 }
5337}
5339//*************************************************************************************************
5340
5341
5342//*************************************************************************************************
5354template< typename MT // Type of the dense matrix
5355 , typename... CCAs > // Compile time column arguments
5356template< typename MT2 > // Type of the right-hand side dense matrix
5357inline void Columns<MT,false,true,false,CCAs...>::addAssign( const DenseMatrix<MT2,false>& rhs )
5358{
5361
5363
5364 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5365 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5366
5367 constexpr size_t block( BLOCK_SIZE );
5368
5369 if( rows() < block && columns() < block )
5370 {
5371 const size_t ipos( prevMultiple( (*rhs).rows(), 2UL ) );
5372 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).rows(), "Invalid end calculation" );
5373
5374 for( size_t j=0UL; j<columns(); ++j ) {
5375 const size_t index( idx(j) );
5376 for( size_t i=0UL; i<ipos; i+=2UL ) {
5377 matrix_(i ,index) += (*rhs)(i ,j);
5378 matrix_(i+1UL,index) += (*rhs)(i+1UL,j);
5379 }
5380 if( ipos < (*rhs).rows() )
5381 matrix_(ipos,index) += (*rhs)(ipos,j);
5382 }
5383 }
5384 else
5385 {
5386 for( size_t jj=0UL; jj<columns(); jj+=block ) {
5387 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5388 for( size_t ii=0UL; ii<rows(); ii+=block ) {
5389 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5390 for( size_t j=jj; j<jend; ++j ) {
5391 const size_t index( idx(j) );
5392 for( size_t i=ii; i<iend; ++i ) {
5393 matrix_(i,index) += (*rhs)(i,j);
5394 }
5395 }
5396 }
5397 }
5398 }
5399}
5401//*************************************************************************************************
5402
5403
5404//*************************************************************************************************
5416template< typename MT // Type of the dense matrix
5417 , typename... CCAs > // Compile time column arguments
5418template< typename MT2 > // Type of the right-hand side sparse matrix
5419inline void Columns<MT,false,true,false,CCAs...>::addAssign( const SparseMatrix<MT2,true>& rhs )
5420{
5423
5424 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5425 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5426
5427 for( size_t j=0UL; j<columns(); ++j ) {
5428 const size_t index( idx(j) );
5429 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
5430 matrix_(element->index(),index) += element->value();
5431 }
5432}
5434//*************************************************************************************************
5435
5436
5437//*************************************************************************************************
5449template< typename MT // Type of the dense matrix
5450 , typename... CCAs > // Compile time column arguments
5451template< typename MT2 > // Type of the right-hand side sparse matrix
5452inline void Columns<MT,false,true,false,CCAs...>::addAssign( const SparseMatrix<MT2,false>& rhs )
5453{
5456
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 for( size_t i=0UL; i<rows(); ++i ) {
5463 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5464 matrix_(i,idx(element->index())) += element->value();
5465 }
5466}
5468//*************************************************************************************************
5469
5470
5471//*************************************************************************************************
5483template< typename MT // Type of the dense matrix
5484 , typename... CCAs > // Compile time column arguments
5485template< typename MT2 > // Type of the right-hand side dense matrix
5486inline void Columns<MT,false,true,false,CCAs...>::subAssign( const DenseMatrix<MT2,true>& rhs )
5487{
5490
5491 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5492 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5493
5494 const size_t ipos( prevMultiple( rows(), 2UL ) );
5495 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
5496
5497 for( size_t j=0UL; j<columns(); ++j )
5498 {
5499 const size_t index( idx(j) );
5500
5501 if( IsDiagonal_v<MT2> ) {
5502 matrix_(j,index) -= (*rhs)(j,j);
5503 }
5504 else {
5505 for( size_t i=0UL; i<ipos; i+=2UL ) {
5506 matrix_(i ,index) -= (*rhs)(i ,j);
5507 matrix_(i+1UL,index) -= (*rhs)(i+1UL,j);
5508 }
5509 if( ipos < rows() ) {
5510 matrix_(ipos,index) -= (*rhs)(ipos,j);
5511 }
5512 }
5513 }
5514}
5516//*************************************************************************************************
5517
5518
5519//*************************************************************************************************
5531template< typename MT // Type of the dense matrix
5532 , typename... CCAs > // Compile time column arguments
5533template< typename MT2 > // Type of the right-hand side dense matrix
5534inline void Columns<MT,false,true,false,CCAs...>::subAssign( const DenseMatrix<MT2,false>& rhs )
5535{
5538
5540
5541 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5542 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5543
5544 constexpr size_t block( BLOCK_SIZE );
5545
5546 if( rows() < block && columns() < block )
5547 {
5548 const size_t ipos( prevMultiple( (*rhs).rows(), 2UL ) );
5549 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).rows(), "Invalid end calculation" );
5550
5551 for( size_t j=0UL; j<columns(); ++j ) {
5552 const size_t index( idx(j) );
5553 for( size_t i=0UL; i<ipos; i+=2UL ) {
5554 matrix_(i ,index) -= (*rhs)(i ,j);
5555 matrix_(i+1UL,index) -= (*rhs)(i+1UL,j);
5556 }
5557 if( ipos < (*rhs).rows() )
5558 matrix_(ipos,index) -= (*rhs)(ipos,j);
5559 }
5560 }
5561 else
5562 {
5563 for( size_t jj=0UL; jj<columns(); jj+=block ) {
5564 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5565 for( size_t ii=0UL; ii<rows(); ii+=block ) {
5566 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5567 for( size_t j=jj; j<jend; ++j ) {
5568 const size_t index( idx(j) );
5569 for( size_t i=ii; i<iend; ++i ) {
5570 matrix_(i,index) -= (*rhs)(i,j);
5571 }
5572 }
5573 }
5574 }
5575 }
5576}
5578//*************************************************************************************************
5579
5580
5581//*************************************************************************************************
5593template< typename MT // Type of the dense matrix
5594 , typename... CCAs > // Compile time column arguments
5595template< typename MT2 > // Type of the right-hand side sparse matrix
5596inline void Columns<MT,false,true,false,CCAs...>::subAssign( const SparseMatrix<MT2,true>& rhs )
5597{
5600
5601 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5602 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5603
5604 for( size_t j=0UL; j<columns(); ++j ) {
5605 const size_t index( idx(j) );
5606 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element )
5607 matrix_(element->index(),index) -= element->value();
5608 }
5609}
5611//*************************************************************************************************
5612
5613
5614//*************************************************************************************************
5626template< typename MT // Type of the dense matrix
5627 , typename... CCAs > // Compile time column arguments
5628template< typename MT2 > // Type of the right-hand side sparse matrix
5629inline void Columns<MT,false,true,false,CCAs...>::subAssign( const SparseMatrix<MT2,false>& rhs )
5630{
5633
5635
5636 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5637 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5638
5639 for( size_t i=0UL; i<rows(); ++i ) {
5640 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element )
5641 matrix_(i,idx(element->index())) -= element->value();
5642 }
5643}
5645//*************************************************************************************************
5646
5647
5648//*************************************************************************************************
5660template< typename MT // Type of the dense matrix
5661 , typename... CCAs > // Compile time column arguments
5662template< typename MT2 > // Type of the right-hand side dense matrix
5663inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const DenseMatrix<MT2,true>& rhs )
5664{
5667
5668 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5669 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5670
5671 const size_t ipos( prevMultiple( rows(), 2UL ) );
5672 BLAZE_INTERNAL_ASSERT( ipos <= rows(), "Invalid end calculation" );
5673
5674 for( size_t j=0UL; j<columns(); ++j ) {
5675 const size_t index( idx(j) );
5676 for( size_t i=0UL; i<ipos; i+=2UL ) {
5677 matrix_(i ,index) *= (*rhs)(i ,j);
5678 matrix_(i+1UL,index) *= (*rhs)(i+1UL,j);
5679 }
5680 if( ipos < rows() ) {
5681 matrix_(ipos,index) *= (*rhs)(ipos,j);
5682 }
5683 }
5684}
5686//*************************************************************************************************
5687
5688
5689//*************************************************************************************************
5701template< typename MT // Type of the dense matrix
5702 , typename... CCAs > // Compile time column arguments
5703template< typename MT2 > // Type of the right-hand side dense matrix
5704inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const DenseMatrix<MT2,false>& rhs )
5705{
5708
5710
5711 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5712 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5713
5714 constexpr size_t block( BLOCK_SIZE );
5715
5716 if( rows() < block && columns() < block )
5717 {
5718 const size_t ipos( prevMultiple( (*rhs).rows(), 2UL ) );
5719 BLAZE_INTERNAL_ASSERT( ipos <= (*rhs).rows(), "Invalid end calculation" );
5720
5721 for( size_t j=0UL; j<columns(); ++j ) {
5722 const size_t index( idx(j) );
5723 for( size_t i=0UL; i<ipos; i+=2UL ) {
5724 matrix_(i ,index) *= (*rhs)(i ,j);
5725 matrix_(i+1UL,index) *= (*rhs)(i+1UL,j);
5726 }
5727 if( ipos < (*rhs).rows() )
5728 matrix_(ipos,index) *= (*rhs)(ipos,j);
5729 }
5730 }
5731 else
5732 {
5733 for( size_t jj=0UL; jj<columns(); jj+=block ) {
5734 const size_t jend( ( columns()<(jj+block) )?( columns() ):( jj+block ) );
5735 for( size_t ii=0UL; ii<rows(); ii+=block ) {
5736 const size_t iend( ( rows()<(ii+block) )?( rows() ):( ii+block ) );
5737 for( size_t j=jj; j<jend; ++j ) {
5738 const size_t index( idx(j) );
5739 for( size_t i=ii; i<iend; ++i ) {
5740 matrix_(i,index) *= (*rhs)(i,j);
5741 }
5742 }
5743 }
5744 }
5745 }
5746}
5748//*************************************************************************************************
5749
5750
5751//*************************************************************************************************
5763template< typename MT // Type of the dense matrix
5764 , typename... CCAs > // Compile time column arguments
5765template< typename MT2 > // Type of the right-hand side sparse matrix
5766inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const SparseMatrix<MT2,true>& rhs )
5767{
5768 using blaze::reset;
5769
5772
5773 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5774 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5775
5776 for( size_t j=0UL; j<columns(); ++j )
5777 {
5778 const size_t index( idx(j) );
5779 size_t i( 0UL );
5780
5781 for( ConstIterator_t<MT2> element=(*rhs).begin(j); element!=(*rhs).end(j); ++element ) {
5782 for( ; i<element->index(); ++i )
5783 reset( matrix_(i,index) );
5784 matrix_(i,index) *= element->value();
5785 ++i;
5786 }
5787
5788 for( ; i<rows(); ++i ) {
5789 reset( matrix_(i,index) );
5790 }
5791 }
5792}
5794//*************************************************************************************************
5795
5796
5797//*************************************************************************************************
5809template< typename MT // Type of the dense matrix
5810 , typename... CCAs > // Compile time column arguments
5811template< typename MT2 > // Type of the right-hand side sparse matrix
5812inline void Columns<MT,false,true,false,CCAs...>::schurAssign( const SparseMatrix<MT2,false>& rhs )
5813{
5814 using blaze::reset;
5815
5818
5820
5821 BLAZE_INTERNAL_ASSERT( rows() == (*rhs).rows() , "Invalid number of rows" );
5822 BLAZE_INTERNAL_ASSERT( columns() == (*rhs).columns(), "Invalid number of columns" );
5823
5824 for( size_t i=0UL; i<rows(); ++i )
5825 {
5826 size_t j( 0UL );
5827
5828 for( ConstIterator_t<MT2> element=(*rhs).begin(i); element!=(*rhs).end(i); ++element ) {
5829 for( ; j<element->index(); ++j )
5830 reset( matrix_(i,idx(j)) );
5831 matrix_(i,idx(j)) *= element->value();
5832 ++j;
5833 }
5834
5835 for( ; j<columns(); ++j ) {
5836 reset( matrix_(i,idx(j)) );
5837 }
5838 }
5839}
5841//*************************************************************************************************
5842
5843
5844
5845
5846
5847
5848
5849
5850//=================================================================================================
5851//
5852// CLASS TEMPLATE SPECIALIZATION FOR SYMMETRIC ROW-MAJOR DENSE MATRICES
5853//
5854//=================================================================================================
5855
5856//*************************************************************************************************
5864template< typename MT // Type of the dense matrix
5865 , typename... CCAs > // Compile time column arguments
5866class Columns<MT,false,true,true,CCAs...>
5867 : public View< DenseMatrix< Columns<MT,false,true,true,CCAs...>, true > >
5868 , private ColumnsData<CCAs...>
5869{
5870 private:
5871 //**Type definitions****************************************************************************
5872 using DataType = ColumnsData<CCAs...>;
5873 using Operand = If_t< IsExpression_v<MT>, MT, MT& >;
5874 //**********************************************************************************************
5875
5876 //**Compile time flags**************************************************************************
5877 using DataType::N;
5878 //**********************************************************************************************
5879
5880 public:
5881 //**Type definitions****************************************************************************
5883 using This = Columns<MT,false,true,true,CCAs...>;
5884
5886 using BaseType = View< DenseMatrix<This,true> >;
5887
5888 using ViewedType = MT;
5889 using ResultType = ColumnsTrait_t<MT,N>;
5890 using OppositeType = OppositeType_t<ResultType>;
5891 using TransposeType = TransposeType_t<ResultType>;
5892 using ElementType = ElementType_t<MT>;
5893 using SIMDType = SIMDTrait_t<ElementType>;
5894 using ReturnType = ReturnType_t<MT>;
5895 using CompositeType = const Columns&;
5896
5898 using ConstReference = ConstReference_t<MT>;
5899
5901 using Reference = If_t< IsConst_v<MT>, ConstReference, Reference_t<MT> >;
5902
5904 using ConstPointer = ConstPointer_t<MT>;
5905
5907 using Pointer = If_t< IsConst_v<MT> || !HasMutableDataAccess_v<MT>, ConstPointer, Pointer_t<MT> >;
5908
5910 using ConstIterator = ConstIterator_t<MT>;
5911
5913 using Iterator = If_t< IsConst_v<MT>, ConstIterator, Iterator_t<MT> >;
5914 //**********************************************************************************************
5915
5916 //**Compilation flags***************************************************************************
5918 static constexpr bool simdEnabled = MT::simdEnabled;
5919
5921 static constexpr bool smpAssignable = MT::smpAssignable;
5922
5924 static constexpr bool compileTimeArgs = DataType::compileTimeArgs;
5925 //**********************************************************************************************
5926
5927 //**Constructors********************************************************************************
5930 template< typename... RCAs >
5931 explicit inline Columns( MT& matrix, RCAs... args );
5932
5933 Columns( const Columns& ) = default;
5934 Columns( Columns&& ) = default;
5936 //**********************************************************************************************
5937
5938 //**Destructor**********************************************************************************
5941 ~Columns() = default;
5943 //**********************************************************************************************
5944
5945 //**Data access functions***********************************************************************
5948 inline Reference operator()( size_t i, size_t j );
5949 inline ConstReference operator()( size_t i, size_t j ) const;
5950 inline Reference at( size_t i, size_t j );
5951 inline ConstReference at( size_t i, size_t j ) const;
5952 inline Pointer data () noexcept;
5953 inline ConstPointer data () const noexcept;
5954 inline Pointer data ( size_t j ) noexcept;
5955 inline ConstPointer data ( size_t j ) const noexcept;
5956 inline Iterator begin ( size_t j );
5957 inline ConstIterator begin ( size_t j ) const;
5958 inline ConstIterator cbegin( size_t j ) const;
5959 inline Iterator end ( size_t j );
5960 inline ConstIterator end ( size_t j ) const;
5961 inline ConstIterator cend ( size_t j ) const;
5963 //**********************************************************************************************
5964
5965 //**Assignment operators************************************************************************
5968 inline Columns& operator=( const ElementType& rhs );
5969
5970 Columns& operator=( const Columns& ) = delete;
5972 //**********************************************************************************************
5973
5974 //**Utility functions***************************************************************************
5977 using DataType::idx;
5978 using DataType::idces;
5979 using DataType::columns;
5980
5981 inline MT& operand() noexcept;
5982 inline const MT& operand() const noexcept;
5983
5984 inline size_t rows() const noexcept;
5985 inline size_t spacing() const noexcept;
5986 inline size_t capacity() const noexcept;
5987 inline size_t capacity( size_t j ) const noexcept;
5988 inline size_t nonZeros() const;
5989 inline size_t nonZeros( size_t j ) const;
5990 inline void reset();
5991 inline void reset( size_t j );
5993 //**********************************************************************************************
5994
5995 //**Expression template evaluation functions****************************************************
5998 template< typename Other >
5999 inline bool canAlias( const Other* alias ) const noexcept;
6000
6001 template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
6002 inline bool canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
6003
6004 template< typename Other >
6005 inline bool isAliased( const Other* alias ) const noexcept;
6006
6007 template< typename MT2, bool SO2, bool SF2, typename... CCAs2 >
6008 inline bool isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept;
6009
6010 inline bool isAligned () const noexcept;
6011 inline bool canSMPAssign() const noexcept;
6012
6013 BLAZE_ALWAYS_INLINE SIMDType load ( size_t i, size_t j ) const noexcept;
6014 BLAZE_ALWAYS_INLINE SIMDType loada( size_t i, size_t j ) const noexcept;
6015 BLAZE_ALWAYS_INLINE SIMDType loadu( size_t i, size_t j ) const noexcept;
6017 //**********************************************************************************************
6018
6019 private:
6020 //**Member variables****************************************************************************
6023 Operand matrix_;
6025 //**********************************************************************************************
6026
6027 //**Friend declarations*************************************************************************
6028 template< typename MT2, bool SO2, bool DF2, bool SF2, typename... CCAs2 > friend class Columns;
6029 //**********************************************************************************************
6030
6031 //**Compile time checks*************************************************************************
6041 //**********************************************************************************************
6042};
6044//*************************************************************************************************
6045
6046
6047
6048
6049//=================================================================================================
6050//
6051// CONSTRUCTORS
6052//
6053//=================================================================================================
6054
6055//*************************************************************************************************
6068template< typename MT // Type of the dense matrix
6069 , typename... CCAs > // Compile time column arguments
6070template< typename... RCAs > // Runtime column arguments
6071inline Columns<MT,false,true,true,CCAs...>::Columns( MT& matrix, RCAs... args )
6072 : DataType( args... ) // Base class initialization
6073 , matrix_ ( matrix ) // The matrix containing the columns
6074{
6075 if( isChecked( args... ) ) {
6076 for( size_t j=0UL; j<columns(); ++j ) {
6077 if( matrix_.columns() <= idx(j) ) {
6078 BLAZE_THROW_INVALID_ARGUMENT( "Invalid column access index" );
6079 }
6080 }
6081 }
6082}
6084//*************************************************************************************************
6085
6086
6087
6088
6089//=================================================================================================
6090//
6091// DATA ACCESS FUNCTIONS
6092//
6093//=================================================================================================
6094
6095//*************************************************************************************************
6106template< typename MT // Type of the dense matrix
6107 , typename... CCAs > // Compile time column arguments
6108inline typename Columns<MT,false,true,true,CCAs...>::Reference
6109 Columns<MT,false,true,true,CCAs...>::operator()( size_t i, size_t j )
6110{
6111 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6112 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6113
6114 return matrix_(idx(j),i);
6115}
6117//*************************************************************************************************
6118
6119
6120//*************************************************************************************************
6131template< typename MT // Type of the dense matrix
6132 , typename... CCAs > // Compile time column arguments
6133inline typename Columns<MT,false,true,true,CCAs...>::ConstReference
6134 Columns<MT,false,true,true,CCAs...>::operator()( size_t i, size_t j ) const
6135{
6136 BLAZE_USER_ASSERT( i < rows() , "Invalid row access index" );
6137 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6138
6139 return const_cast<const MT&>( matrix_ )(idx(j),i);
6140}
6142//*************************************************************************************************
6143
6144
6145//*************************************************************************************************
6157template< typename MT // Type of the dense matrix
6158 , typename... CCAs > // Compile time column arguments
6159inline typename Columns<MT,false,true,true,CCAs...>::Reference
6160 Columns<MT,false,true,true,CCAs...>::at( size_t i, size_t j )
6161{
6162 if( i >= rows() ) {
6163 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6164 }
6165 if( j >= columns() ) {
6166 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6167 }
6168 return (*this)(i,j);
6169}
6171//*************************************************************************************************
6172
6173
6174//*************************************************************************************************
6186template< typename MT // Type of the dense matrix
6187 , typename... CCAs > // Compile time column arguments
6188inline typename Columns<MT,false,true,true,CCAs...>::ConstReference
6189 Columns<MT,false,true,true,CCAs...>::at( size_t i, size_t j ) const
6190{
6191 if( i >= rows() ) {
6192 BLAZE_THROW_OUT_OF_RANGE( "Invalid row access index" );
6193 }
6194 if( j >= columns() ) {
6195 BLAZE_THROW_OUT_OF_RANGE( "Invalid column access index" );
6196 }
6197 return (*this)(i,j);
6198}
6200//*************************************************************************************************
6201
6202
6203//*************************************************************************************************
6213template< typename MT // Type of the dense matrix
6214 , typename... CCAs > // Compile time column arguments
6215inline typename Columns<MT,false,true,true,CCAs...>::Pointer
6217{
6218 return matrix_.data( idx(0UL) );
6219}
6221//*************************************************************************************************
6222
6223
6224//*************************************************************************************************
6234template< typename MT // Type of the dense matrix
6235 , typename... CCAs > // Compile time column arguments
6236inline typename Columns<MT,false,true,true,CCAs...>::ConstPointer
6238{
6239 return matrix_.data( idx(0UL) );
6240}
6242//*************************************************************************************************
6243
6244
6245//*************************************************************************************************
6254template< typename MT // Type of the dense matrix
6255 , typename... CCAs > // Compile time column arguments
6256inline typename Columns<MT,false,true,true,CCAs...>::Pointer
6258{
6259 return matrix_.data( idx(j) );
6260}
6262//*************************************************************************************************
6263
6264
6265//*************************************************************************************************
6274template< typename MT // Type of the dense matrix
6275 , typename... CCAs > // Compile time column arguments
6276inline typename Columns<MT,false,true,true,CCAs...>::ConstPointer
6277 Columns<MT,false,true,true,CCAs...>::data( size_t j ) const noexcept
6278{
6279 return matrix_.data( idx(j) );
6280}
6282//*************************************************************************************************
6283
6284
6285//*************************************************************************************************
6294template< typename MT // Type of the dense matrix
6295 , typename... CCAs > // Compile time column arguments
6296inline typename Columns<MT,false,true,true,CCAs...>::Iterator
6298{
6299 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6300 return matrix_.begin( idx(j) );
6301}
6303//*************************************************************************************************
6304
6305
6306//*************************************************************************************************
6315template< typename MT // Type of the dense matrix
6316 , typename... CCAs > // Compile time column arguments
6317inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6319{
6320 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6321 return matrix_.cbegin( idx(j) );
6322}
6324//*************************************************************************************************
6325
6326
6327//*************************************************************************************************
6336template< typename MT // Type of the dense matrix
6337 , typename... CCAs > // Compile time column arguments
6338inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6340{
6341 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6342 return matrix_.cbegin( idx(j) );
6343}
6345//*************************************************************************************************
6346
6347
6348//*************************************************************************************************
6357template< typename MT // Type of the dense matrix
6358 , typename... CCAs > // Compile time column arguments
6359inline typename Columns<MT,false,true,true,CCAs...>::Iterator
6361{
6362 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6363 return matrix_.end( idx(j) );
6364}
6366//*************************************************************************************************
6367
6368
6369//*************************************************************************************************
6378template< typename MT // Type of the dense matrix
6379 , typename... CCAs > // Compile time column arguments
6380inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6382{
6383 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6384 return matrix_.cend( idx(j) );
6385}
6387//*************************************************************************************************
6388
6389
6390//*************************************************************************************************
6399template< typename MT // Type of the dense matrix
6400 , typename... CCAs > // Compile time column arguments
6401inline typename Columns<MT,false,true,true,CCAs...>::ConstIterator
6403{
6404 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6405 return matrix_.cend( idx(j) );
6406}
6408//*************************************************************************************************
6409
6410
6411
6412
6413//=================================================================================================
6414//
6415// ASSIGNMENT OPERATORS
6416//
6417//=================================================================================================
6418
6419//*************************************************************************************************
6430template< typename MT // Type of the dense matrix
6431 , typename... CCAs > // Compile time column arguments
6432inline Columns<MT,false,true,true,CCAs...>&
6433 Columns<MT,false,true,true,CCAs...>::operator=( const ElementType& rhs )
6434{
6435 for( size_t j=0UL; j<columns(); ++j ) {
6436 row( matrix_, idx(j), unchecked ) = rhs;
6437 }
6438
6439 return *this;
6440}
6442//*************************************************************************************************
6443
6444
6445
6446
6447//=================================================================================================
6448//
6449// UTILITY FUNCTIONS
6450//
6451//=================================================================================================
6452
6453//*************************************************************************************************
6459template< typename MT // Type of the dense matrix
6460 , typename... CCAs > // Compile time column arguments
6461inline MT& Columns<MT,false,true,true,CCAs...>::operand() noexcept
6462{
6463 return matrix_;
6464}
6466//*************************************************************************************************
6467
6468
6469//*************************************************************************************************
6475template< typename MT // Type of the dense matrix
6476 , typename... CCAs > // Compile time column arguments
6477inline const MT& Columns<MT,false,true,true,CCAs...>::operand() const noexcept
6478{
6479 return matrix_;
6480}
6482//*************************************************************************************************
6483
6484
6485//*************************************************************************************************
6491template< typename MT // Type of the dense matrix
6492 , typename... CCAs > // Compile time column arguments
6493inline size_t Columns<MT,false,true,true,CCAs...>::rows() const noexcept
6494{
6495 return matrix_.rows();
6496}
6498//*************************************************************************************************
6499
6500
6501//*************************************************************************************************
6510template< typename MT // Type of the dense matrix
6511 , typename... CCAs > // Compile time column arguments
6512inline size_t Columns<MT,false,true,true,CCAs...>::spacing() const noexcept
6513{
6514 return matrix_.spacing();
6515}
6517//*************************************************************************************************
6518
6519
6520//*************************************************************************************************
6526template< typename MT // Type of the dense matrix
6527 , typename... CCAs > // Compile time column arguments
6528inline size_t Columns<MT,false,true,true,CCAs...>::capacity() const noexcept
6529{
6530 return rows() * columns();
6531}
6533//*************************************************************************************************
6534
6535
6536//*************************************************************************************************
6545template< typename MT // Type of the dense matrix
6546 , typename... CCAs > // Compile time column arguments
6547inline size_t Columns<MT,false,true,true,CCAs...>::capacity( size_t j ) const noexcept
6548{
6549 MAYBE_UNUSED( j );
6550
6551 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6552
6553 return rows();
6554}
6556//*************************************************************************************************
6557
6558
6559//*************************************************************************************************
6565template< typename MT // Type of the dense matrix
6566 , typename... CCAs > // Compile time column arguments
6568{
6569 size_t nonzeros( 0UL );
6570
6571 for( size_t j=0UL; j<columns(); ++j ) {
6572 nonzeros += matrix_.nonZeros( idx(j) );
6573 }
6574
6575 return nonzeros;
6576}
6578//*************************************************************************************************
6579
6580
6581//*************************************************************************************************
6590template< typename MT // Type of the dense matrix
6591 , typename... CCAs > // Compile time column arguments
6592inline size_t Columns<MT,false,true,true,CCAs...>::nonZeros( size_t j ) const
6593{
6594 BLAZE_USER_ASSERT( j < columns(), "Invalid column access index" );
6595
6596 return matrix_.nonZeros( idx(j) );
6597}
6599//*************************************************************************************************
6600
6601
6602//*************************************************************************************************
6608template< typename MT // Type of the dense matrix
6609 , typename... CCAs > // Compile time column arguments
6611{
6612 for( size_t j=0UL; j<columns(); ++j ) {
6613 matrix_.reset( idx(j) );
6614 }
6615}
6617//*************************************************************************************************
6618
6619
6620//*************************************************************************************************
6629template< typename MT // Type of the dense matrix
6630 , typename... CCAs > // Compile time column arguments
6631inline void Columns<MT,false,true,true,CCAs...>::reset( size_t j )
6632{
6633 matrix_.reset( idx(j) );
6634}
6636//*************************************************************************************************
6637
6638
6639//=================================================================================================
6640//
6641// EXPRESSION TEMPLATE EVALUATION FUNCTIONS
6642//
6643//=================================================================================================
6644
6645//*************************************************************************************************
6656template< typename MT // Type of the dense matrix
6657 , typename... CCAs > // Compile time column arguments
6658template< typename Other > // Data type of the foreign expression
6659inline bool Columns<MT,false,true,true,CCAs...>::canAlias( const Other* alias ) const noexcept
6660{
6661 return matrix_.isAliased( &unview( *alias ) );
6662}
6664//*************************************************************************************************
6665
6666
6667//*************************************************************************************************
6679template< typename MT // Type of the dense matrix
6680 , typename... CCAs > // Compile time column arguments
6681template< typename MT2 // Data type of the foreign dense column selection
6682 , bool SO2 // Storage order of the foreign dense column selection
6683 , bool SF2 // Symmetry flag of the foreign dense column selection
6684 , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
6685inline bool
6686 Columns<MT,false,true,true,CCAs...>::canAlias( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
6687{
6688 return matrix_.isAliased( &alias->matrix_ );
6689}
6691//*************************************************************************************************
6692
6693
6694//*************************************************************************************************
6705template< typename MT // Type of the dense matrix
6706 , typename... CCAs > // Compile time column arguments
6707template< typename Other > // Data type of the foreign expression
6708inline bool Columns<MT,false,true,true,CCAs...>::isAliased( const Other* alias ) const noexcept
6709{
6710 return matrix_.isAliased( &unview( *alias ) );
6711}
6713//*************************************************************************************************
6714
6715
6716//*************************************************************************************************
6728template< typename MT // Type of the dense matrix
6729 , typename... CCAs > // Compile time column arguments
6730template< typename MT2 // Data type of the foreign dense column selection
6731 , bool SO2 // Storage order of the foreign dense column selection
6732 , bool SF2 // Symmetry flag of the foreign dense column selection
6733 , typename... CCAs2 > // Compile time column arguments of the foreign dense column selection
6734inline bool
6735 Columns<MT,false,true,true,CCAs...>::isAliased( const Columns<MT2,SO2,true,SF2,CCAs2...>* alias ) const noexcept
6736{
6737 return matrix_.isAliased( &alias->matrix_ );
6738}
6740//*************************************************************************************************
6741
6742
6743//*************************************************************************************************
6753template< typename MT // Type of the dense matrix
6754 , typename... CCAs > // Compile time column arguments
6755inline bool Columns<MT,false,true,true,CCAs...>::isAligned() const noexcept
6756{
6757 return matrix_.isAligned();
6758}
6760//*************************************************************************************************
6761
6762
6763//*************************************************************************************************
6774template< typename MT // Type of the dense matrix
6775 , typename... CCAs > // Compile time column arguments
6776inline bool Columns<MT,false,true,true,CCAs...>::canSMPAssign() const noexcept
6777{
6778 return ( rows() * columns() > SMP_DMATASSIGN_THRESHOLD );
6779}
6781//*************************************************************************************************
6782
6783
6784//*************************************************************************************************
6799template< typename MT // Type of the dense matrix
6800 , typename... CCAs > // Compile time column arguments
6801BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6802 Columns<MT,false,true,true,CCAs...>::load( size_t i, size_t j ) const noexcept
6803{
6804 return matrix_.load( idx(j), i );
6805}
6807//*************************************************************************************************
6808
6809
6810//*************************************************************************************************
6825template< typename MT // Type of the dense matrix
6826 , typename... CCAs > // Compile time column arguments
6827BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6828 Columns<MT,false,true,true,CCAs...>::loada( size_t i, size_t j ) const noexcept
6829{
6830 return matrix_.loada( idx(j), i );
6831}
6833//*************************************************************************************************
6834
6835
6836//*************************************************************************************************
6851template< typename MT // Type of the dense matrix
6852 , typename... CCAs > // Compile time column arguments
6853BLAZE_ALWAYS_INLINE typename Columns<MT,false,true,true,CCAs...>::SIMDType
6854 Columns<MT,false,true,true,CCAs...>::loadu( size_t i, size_t j ) const noexcept
6855{
6856 return matrix_.loadu( idx(j), i );
6857}
6859//*************************************************************************************************
6860
6861} // namespace blaze
6862
6863#endif
Header file for the addition trait.
Header file for auxiliary alias declarations.
Header file for run time assertion macros.
Header file for kernel specific block sizes.
Header file for the blaze::checked and blaze::unchecked instances.
Constraints on the storage order of matrix types.
Header file for the implementation of the ColumnsData class template.
Header file for the columns trait.
constexpr const DenseIterator< Type, AF > operator-(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Subtraction between a DenseIterator and an integral value.
Definition: DenseIterator.h:751
constexpr const DenseIterator< Type, AF > operator+(const DenseIterator< Type, AF > &it, ptrdiff_t inc) noexcept
Addition between a DenseIterator and an integral value.
Definition: DenseIterator.h:719
Header file for the EnableIf class template.
Header file for the HasMutableDataAccess type trait.
Header file for the HasSIMDAdd type trait.
Header file for the HasSIMDMult type trait.
Header file for the HasSIMDSub type trait.
Constraint on the data type.
Header file for the If class template.
Header file for the IsConst type trait.
Header file for the IsDiagonal type trait.
Header file for the IsExpression type trait class.
Header file for the IsLower type trait.
Header file for the IsReference type trait.
Header file for the IsRestricted type trait.
Header file for the IsSIMDCombinable type trait.
Header file for the IsSparseMatrix type trait.
Header file for the IsStrictlyLower type trait.
Header file for the IsStrictlyUpper type trait.
Header file for the IsUpper type trait.
Header file for the MAYBE_UNUSED function template.
Constraint on the data type.
Header file for the prevMultiple shim.
Constraint on the data type.
Constraints on the storage order of matrix types.
Header file for all SIMD functionality.
Header file for the Schur product trait.
Header file for the subtraction trait.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Initializer list type of the Blaze library.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Constraint on the data type.
Header file for the implementation of a matrix representation of an initializer list.
Header file for the DenseMatrix base class.
Header file for the View base class.
decltype(auto) column(Matrix< MT, SO > &matrix, RCAs... args)
Creating a view on a specific column of the given matrix.
Definition: Column.h:137
#define BLAZE_CONSTRAINT_MUST_NOT_BE_POINTER_TYPE(T)
Constraint on the data type.
Definition: Pointer.h:79
#define BLAZE_CONSTRAINT_MUST_BE_VECTORIZABLE_TYPE(T)
Constraint on the data type.
Definition: Vectorizable.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_REFERENCE_TYPE(T)
Constraint on the data type.
Definition: Reference.h:79
decltype(auto) ctrans(const DenseMatrix< MT, SO > &dm)
Returns the conjugate transpose matrix of dm.
Definition: DMatMapExpr.h:1501
decltype(auto) trans(const DenseMatrix< MT, SO > &dm)
Calculation of the transpose of the given dense matrix.
Definition: DMatTransExpr.h:766
MT::ElementType * data(DenseMatrix< MT, SO > &dm) noexcept
Low-level data access to the dense matrix elements.
Definition: DenseMatrix.h:182
auto operator+=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Addition assignment operator for the addition of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:386
size_t spacing(const DenseMatrix< MT, SO > &dm) noexcept
Returns the spacing between the beginning of two rows/columns.
Definition: DenseMatrix.h:265
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:9640
auto operator-=(DenseMatrix< MT, SO > &mat, ST scalar) -> EnableIf_t< IsScalar_v< ST >, MT & >
Subtraction assignment operator for the subtraction of a dense matrix and a scalar value ( ).
Definition: DenseMatrix.h:448
bool isIntact(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the invariants of the given diagonal matrix are intact.
Definition: DiagonalMatrix.h:207
bool isDefault(const DiagonalMatrix< MT, SO, DF > &m)
Returns whether the given diagonal matrix is in default state.
Definition: DiagonalMatrix.h:169
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:79
#define BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: RowMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION(T)
Constraint on the data type.
Definition: RequiresEvaluation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_HERMITIAN_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Hermitian.h:79
#define BLAZE_CONSTRAINT_MUST_NOT_BE_TRANSEXPR_TYPE(T)
Constraint on the data type.
Definition: TransExpr.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_SUBMATRIX_TYPE(T)
Constraint on the data type.
Definition: Submatrix.h:81
#define BLAZE_CONSTRAINT_MUST_BE_SYMMETRIC_MATRIX_TYPE(T)
Constraint on the data type.
Definition: Symmetric.h:60
#define BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE(T)
Constraint on the data type.
Definition: DenseMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COMPUTATION_TYPE(T)
Constraint on the data type.
Definition: Computation.h:81
#define BLAZE_CONSTRAINT_MUST_NOT_BE_UNITRIANGULAR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: UniTriangular.h:81
#define BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE(T)
Constraint on the data type.
Definition: ColumnMajorMatrix.h:61
#define BLAZE_CONSTRAINT_MUST_NOT_BE_COLUMNS_TYPE(T)
Constraint on the data type.
Definition: Columns.h:81
constexpr bool HasSIMDSub_v
Auxiliary variable template for the HasSIMDSub type trait.
Definition: HasSIMDSub.h:187
constexpr bool IsSIMDCombinable_v
Auxiliary variable template for the IsSIMDCombinable type trait.
Definition: IsSIMDCombinable.h:137
constexpr bool IsDiagonal_v
Auxiliary variable template for the IsDiagonal type trait.
Definition: IsDiagonal.h:148
constexpr bool HasSIMDAdd_v
Auxiliary variable template for the HasSIMDAdd type trait.
Definition: HasSIMDAdd.h:187
constexpr bool HasSIMDMult_v
Auxiliary variable template for the HasSIMDMult type trait.
Definition: HasSIMDMult.h:188
BLAZE_ALWAYS_INLINE constexpr auto prevMultiple(T1 value, T2 factor) noexcept
Rounds down an integral value to the previous multiple of a given factor.
Definition: PrevMultiple.h:68
constexpr bool operator>(const NegativeAccuracy< A > &lhs, const T &rhs)
Greater-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:370
constexpr bool operator==(const NegativeAccuracy< A > &lhs, const T &rhs)
Equality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:253
constexpr bool operator<(const NegativeAccuracy< A > &lhs, const T &rhs)
Less-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:332
constexpr bool operator>=(const NegativeAccuracy< A > &, const T &rhs)
Greater-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:446
constexpr bool operator!=(const NegativeAccuracy< A > &lhs, const T &rhs)
Inequality comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:293
constexpr bool operator<=(const NegativeAccuracy< A > &, const T &rhs)
Less-or-equal-than comparison between a NegativeAccuracy object and a floating point value.
Definition: Accuracy.h:408
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:628
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:644
size_t nonZeros(const Matrix< MT, SO > &matrix)
Returns the total number of non-zero elements in the matrix.
Definition: Matrix.h:730
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:562
size_t capacity(const Matrix< MT, SO > &matrix) noexcept
Returns the maximum capacity of the matrix.
Definition: Matrix.h:692
constexpr void reset(Matrix< MT, SO > &matrix)
Resetting the given matrix.
Definition: Matrix.h:806
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:660
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:584
void ctranspose(Matrix< MT, SO > &matrix)
In-place conjugate transpose of the given matrix.
Definition: Matrix.h:1221
MT::Iterator begin(Matrix< MT, SO > &matrix, size_t i)
Returns an iterator to the first element of row/column i.
Definition: Matrix.h:518
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:676
void transpose(Matrix< MT, SO > &matrix)
In-place transpose of the given matrix.
Definition: Matrix.h:1195
decltype(auto) row(Matrix< MT, SO > &, RRAs...)
Creating a view on a specific row of the given matrix.
Definition: Row.h:137
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.
Definition: Assert.h:101
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.
Definition: Assert.h:117
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storea(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned store of a vector of 1-byte integral values.
Definition: Storea.h:78
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > storeu(T1 *address, const SIMDi8< T2 > &value) noexcept
Unaligned store of a vector of 1-byte integral values.
Definition: Storeu.h:75
BLAZE_ALWAYS_INLINE EnableIf_t< IsIntegral_v< T1 > &&HasSize_v< T1, 1UL > > stream(T1 *address, const SIMDi8< T2 > &value) noexcept
Aligned, non-temporal store of a vector of 1-byte integral values.
Definition: Stream.h:74
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loadu(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loadu.h:76
BLAZE_ALWAYS_INLINE const EnableIf_t< IsIntegral_v< T > &&HasSize_v< T, 1UL >, If_t< IsSigned_v< T >, SIMDint8, SIMDuint8 > > loada(const T *address) noexcept
Loads a vector of 1-byte integral values.
Definition: Loada.h:79
auto smpSubAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP subtraction assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:162
auto smpAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:100
auto smpSchurAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP Schur product assignment of a matrix to dense matrix.
Definition: DenseMatrix.h:194
auto smpAddAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs) -> EnableIf_t< IsDenseMatrix_v< MT1 > >
Default implementation of the SMP addition assignment of a matrix to a dense matrix.
Definition: DenseMatrix.h:131
#define BLAZE_ALWAYS_INLINE
Platform dependent setup of an enforced inline keyword.
Definition: Inline.h:85
typename EnableIf< Condition, T >::Type EnableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:138
constexpr void MAYBE_UNUSED(const Args &...)
Suppression of unused parameter warnings.
Definition: MaybeUnused.h:81
#define BLAZE_THROW_OUT_OF_RANGE(MESSAGE)
Macro for the emission of a std::out_of_range exception.
Definition: Exception.h:331
#define BLAZE_THROW_INVALID_ARGUMENT(MESSAGE)
Macro for the emission of a std::invalid_argument exception.
Definition: Exception.h:235
#define BLAZE_THROW_LOGIC_ERROR(MESSAGE)
Macro for the emission of a std::logic_error exception.
Definition: Exception.h:187
typename EnableIf<!Condition, T >::Type DisableIf_t
Auxiliary type for the EnableIf class template.
Definition: EnableIf.h:175
constexpr bool isChecked(const Ts &... args)
Extracting blaze::Check arguments from a given list of arguments.
Definition: Check.h:225
constexpr Unchecked unchecked
Global Unchecked instance.
Definition: Check.h:146
Header file for the exception macros of the math module.
Header file for the extended initializer_list functionality.
Header file for the reset shim.
Header file for the cache size of the target architecture.
System settings for the inline keywords.
System settings for performance optimizations.
Header file for the thresholds for matrix/vector and matrix/matrix multiplications.
Header file for the RequiresEvaluation type trait.
Header file for basic type definitions.
Header file for the implementation of the Columns base template.